mapeditor / tiled

Flexible level editor
https://www.mapeditor.org/
Other
11.25k stars 1.76k forks source link

Create JSON Schema for Tiled json format #4096

Open krychu opened 2 weeks ago

krychu commented 2 weeks ago

Is your feature request related to a problem? Please describe.

Describe the solution you'd like

Describe alternatives you've considered

Additional notes

Documentation of the json format has to exist in some form: html, markdown or JSON schema. Moving to adopting JSON schema might thus potentially be only one off cost.

bjorn commented 2 weeks ago

I've already tried to create a JSON schema once (or possibly, a typescript definition for the JSON format), but I have unfortunately found the current JSON format to be rather unsuitable. One of the main issues is that the map layers are stored in an array that can contain different kinds of layers, identified by a "type" field. And yet they do share some common fields, which is usually solved by inheritance (or an aggregated enum in Rust). However, modeling inheritance in JSON schema appears to be tricky and even if you could get a working schema, it would likely not lead to the generation of desirable code through quicktype.

That is not to say I have entirely given up on this and I would certainly welcome any effort to create such a schema even if it is not a perfect solution. It could also help identify issues with the current JSON format, which we can eventually address when we introduce an improved JSON format (see #3212).

aleokdev commented 2 weeks ago

Hey, chiming in to say that I've worked on exactly this on my workplace and we were able to emulate aggregated enums in JSON schemas by using the oneOf attribute. I hadn't tried to generate code from it up until now (I just happened to read this post from the Discord forum channel), and while it is able to generate classes/structures from the aggregated enums, it flattens them, placing all of the members of each variant in the same place alongside the type like this: image

While this is not ideal I thought you still might be interested in this. Here's the schema and the code that generates such schema. We have a visualizer as well but I believe the code is a bit nicer to read if you understand Rust. We generated the schema using the Schemars library.

krychu commented 2 weeks ago

I'm not familiar with JSON schema myself. But a quick search shows that oneOf indeed might be something to explore:

https://stackoverflow.com/questions/15396251/correct-json-schema-for-an-array-of-items-of-different-type

Here the answer I get from chatgpt: https://chatgpt.com/share/672c9303-ff0c-800c-82cb-cd8bebae69b4

and here json schema of tldk which also seems to use oneOf, not sure if they deal with the same structure/issues though: https://ldtk.io/files/JSON_SCHEMA.json

bjorn commented 2 weeks ago

and here json schema of tldk which also seems to use oneOf, not sure if they deal with the same structure/issues though: https://ldtk.io/files/JSON_SCHEMA.json

They don't. In that schema, "oneOf" is only used for values which might be null.

However, while "oneOf" might be a solution for validation, it still poses an issue for code generation, unless you're fine with having a monolithic "layer" class that simply has all the properties of tile layers, object layers, image layers and group layers (see above).