Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to mark resources as json and other types #1740

Open
Shadowblitz16 opened this issue Oct 27, 2020 · 7 comments · Fixed by goostengine/goost#30
Open

Ability to mark resources as json and other types #1740

Shadowblitz16 opened this issue Oct 27, 2020 · 7 comments · Fixed by goostengine/goost#30

Comments

@Shadowblitz16
Copy link

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.

@Xrayez
Copy link
Contributor

Xrayez commented Oct 27, 2020

For reference, this can be implemented as a JSON resource importer, as in https://github.com/godot-extended-libraries/json.

@Shadowblitz16
Copy link
Author

Shadowblitz16 commented Oct 28, 2020

@Xrayez Is this possible to do with gdscript currently?
That link is c++ code

@Xrayez
Copy link
Contributor

Xrayez commented Oct 28, 2020

@Shadowblitz16 yes, I think it should be straightforward to port to GDScript since the import API is quite similar, see Import plugins.

@Shadowblitz16
Copy link
Author

Shadowblitz16 commented Oct 28, 2020

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

tool
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
tool
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 Shadowblitz16 changed the title Ability to mark resources as json Ability to mark resources as json and other types Oct 28, 2020
@Xrayez
Copy link
Contributor

Xrayez commented Oct 28, 2020

@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.

@Shadowblitz16
Copy link
Author

Shadowblitz16 commented Oct 28, 2020

@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

@Xrayez
Copy link
Contributor

Xrayez commented Oct 29, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants