Describe the project you are working on:
Mario game
Describe the problem or limitation you are having in your project:
I want to be able to mark a resource as json so that I can implement modding support
Describe the feature / enhancement and how it helps to overcome the problem or limitation:
Allow us to mark resources and custom resources as json so they can be edited outside of the godot editor
Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
I would guess it would be a option in the import tab.
If this enhancement will not be used often, can it be worked around with a few lines of script?:
It would be used for modding and not without fighting the editor
Is there a reason why this should be core and not an add-on in the asset library?:
it improves modding support.
For reference, this can be implemented as a JSON resource importer, as in https://github.com/godot-extended-libraries/json.
@Xrayez Is this possible to do with gdscript currently?
That link is c++ code
@Shadowblitz16 yes, I think it should be straightforward to port to GDScript since the import API is quite similar, see Import plugins.
so I made a import plugin however that imports json files and populates a resource,
but I'm not sure how to actually get the variables to show up in the editor
extends EditorPlugin
var json_plugin
func _enter_tree() -> void:
json_plugin = preload("res://addons/json_resource/plugin_json.gd").new()
add_import_plugin(json_plugin)
func _exit_tree() -> void:
remove_import_plugin(json_plugin)
json_plugin=null
extends EditorImportPlugin
func get_importer_name():
return "shadowblitz16.jsonresource"
func get_visible_name() -> String:
return "JSON Importer"
func get_recognized_extensions():
return ["json"]
func get_save_extension():
return "json"
func get_resource_type():
return "Resource"
func import(source_file, save_path, options, r_platform_variants, r_gen_files):
var file = File.new()
var err = file.open(source_file, File.READ)
if err != OK:
return err
var dict = json2dict(file.get_as_text())
file.close()
var resource = parse_dict(Resource.new(), dict)
#var resource = Resource.new()
return ResourceSaver.save("%s.%s" % [save_path, get_save_extension()], resource)
func parse_dict(resource:Resource, dict:Dictionary)->Resource:
var properties = resource.get_property_list()
for i in range(properties.size()):
var k = properties[i].name
var v = properties[i].value
if v is Resource: resource.set(k, parse_dict(resource, v))
else: resource.set(k, v)
return resource
func json2dict(text:String)->Dictionary:
var json = JSON.new()
var test = json.parse(text)
if test.error != OK:
print("Error: could not parse json: "+test.error_line+"/n"+test.error_string)
return Dictionary()
elif not test.result is Dictionary:
print("Error: root must be object")
return Dictionary()
return test.result as Dictionary
Note this is temporary until its added to the engine.
I would assume resources would be able to be marked as several types such as ini, cfg, lua
@Shadowblitz16 you literally have to create a JSONData class extending Resource: https://github.com/godot-extended-libraries/json/blob/master/resource_importer_json.h#L37-L51, it's the only way to make the engine recognize the external data this way. It's similar to TextFile, I think.
@Xrayez DM me on discord about this its getting offtopic.
EDIT:
So the idea would be that you would derive from a resource and be able to save and load it somewhere as json
And you would be able to do with any resource type.
If the resource didn't have the property exported it wouldn't read it. ir the json didn't have the property it would stay whatever you set as default
Well I've just tried to port https://github.com/godot-extended-libraries/json. to GDScript and stumbled upon a limitation in Godot 3.2.
class_name JSONResource extends Resource
var data
var json setget set_json, get_json
func set_json(p_json):
data = JSON.parse(p_json).result
func get_json():
return JSON.print(data)
func _get_property_list():
return [
{ name = "data", type = TYPE_NIL, usage = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NIL_IS_VARIANT },
{ name = "json", type = TYPE_STRING, usage = PROPERTY_USAGE_EDITOR },
]
PROPERTY_USAGE_NIL_IS_VARIANT is not exposed to scripting, and type-less export is not supported, nor export(Variant).
This is also not possible in Godot 4.0:
@export var data: Variant
So, I guess there was a reason why it was implemented as a C++ module. 馃槷
Technically, it's still possible to export(Dictionary) but Godot's implementation is not restricted to converting dictionaries in JSON.
Most helpful comment
For reference, this can be implemented as a
JSONresource importer, as in https://github.com/godot-extended-libraries/json.