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

feat: add support for LDtk tilemap #4575

Merged
merged 49 commits into from
Dec 22, 2022
Merged

feat: add support for LDtk tilemap #4575

merged 49 commits into from
Dec 22, 2022

Conversation

daiyam
Copy link
Contributor

@daiyam daiyam commented Nov 23, 2022

This PR adds support for LDtk tilemap.

Capture

Caveats:

  • floating tiles' position are rounded to the lower integer.
  • it doesn't support levels with layers of different grid sizes, it will pick the first one.

Todo:

  • resources loading or importing, to be validated what to do.
  • support .ldtk files (only .json for now) (* there is any issue with existing tilemap)

closes #2434

@daiyam daiyam requested a review from 4ian as a code owner November 23, 2022 19:04
@4ian
Copy link
Owner

4ian commented Nov 25, 2022

Looks great! I'm reviewing this today :)

Copy link
Owner

@4ian 4ian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just did a quick review but so far only a few minor comments.

SharedLibs/TileMapHelper/src/render/Manager.ts Outdated Show resolved Hide resolved
SharedLibs/TileMapHelper/src/render/Manager.ts Outdated Show resolved Hide resolved
SharedLibs/TileMapHelper/src/render/PixiHelper.ts Outdated Show resolved Hide resolved
SharedLibs/TileMapHelper/src/render/ldtk/PixiHelper.ts Outdated Show resolved Hide resolved
SharedLibs/TileMapHelper/src/render/ldtk/PixiHelper.ts Outdated Show resolved Hide resolved
SharedLibs/TileMapHelper/src/render/ldtk/PixiHelper.ts Outdated Show resolved Hide resolved
SharedLibs/TileMapHelper/src/render/ldtk/PixiHelper.ts Outdated Show resolved Hide resolved
@daiyam
Copy link
Contributor Author

daiyam commented Nov 25, 2022

@4ian From my todo, let's start with the resources loading.

When adding a LDtk map, here what I would like to do:

  • parse the map
  • locate all the files
  • import all those files to the project as resources
  • rewrite the map/json with the corresponding resource ids

What do you think about it?

The issue with that approach is external map (not copied into the project), we can't really refactor them to our need.

@4ian
Copy link
Owner

4ian commented Nov 26, 2022

When adding a LDtk map, here what I would like to do:

That's a way to do it yes, parse the map and import as resources the other files... but as you said this implies to also update the map..

I wonder if there is something we could do that would work as a "mapping", stored in the object, that using as:

  • As key: the name of the file/resource used in the LDtk JSON
  • As a value: the name of the resource in GDevelop.

So when you import a LDtk file in the editor:

  • The LDtk map is parsed and every file referenced inside is imported as a new resource (unless it already exists, not sure how exactly it would work)
  • We keep inside the object a mapping of "name of the file in LDtk -> name of the resource".

This way, the LDtk map does not need to be modified. This will allow this approach to work for example with LDtk maps stored in URLs for the web-app.

Do you think this could work?

@daiyam
Copy link
Contributor Author

daiyam commented Nov 26, 2022

Yes, I like that.
Will it be ok to add that mapping/translation layer in the metadata field of the resource? Since we can have several objects referencing the same map but using different a level.

@4ian
Copy link
Owner

4ian commented Nov 26, 2022

Will it be ok to add that mapping/translation layer in the metadata field of the resource? Since we can have several objects referencing the same map but using different a level.

Sounds like an excellent idea (and if it does not work it can always go back in the object). Do this into a field in the metadata (so like the metadata looks like: { ldtkRelPathsMapping: {...} }, so other metadata can live next to it).

This will probably need some special work when the resource is imported, you can set it up at some place and we can then ensure it's applied everywhere resources can be imported in the editor.

SharedLibs/TileMapHelper/src/model/Model.ts Outdated Show resolved Hide resolved
SharedLibs/TileMapHelper/src/model/Model.ts Outdated Show resolved Hide resolved
SharedLibs/TileMapHelper/src/model/Model.ts Outdated Show resolved Hide resolved
SharedLibs/TileMapHelper/src/model/Model.ts Outdated Show resolved Hide resolved
@D8H
Copy link
Collaborator

D8H commented Nov 28, 2022

Thanks for working on this, it will make a lot of people happy 😃

@daiyam
Copy link
Contributor Author

daiyam commented Nov 28, 2022

@4ian In the end, I've named metadata as { embeddedResourcesMapping: ... } since it's a generic structure and can be used by other resources.
So now, it can load LDtk maps that are inside or outside the project.

I have a issue with Remove unused resources, it would remove the embedded resources. I see exposeImage or exposeResources but I don't know if it's correct way to declare them as used.

@daiyam
Copy link
Contributor Author

daiyam commented Nov 28, 2022

To add support for .ldtk file, I've added the new tilemap resource.
I'm having issue with old tilemaps which are using json resource. The tilemaps are displayed but can't be reused (if you remove the property from the object and re-add it, you get an error!).
Should they be transformed as tilemap resource?

@4ian
Copy link
Owner

4ian commented Nov 28, 2022

I have a issue with Remove unused resources, it would remove the embedded resources. I see exposeImage or exposeResources but I don't know if it's correct way to declare them as used.

Indeed, we need to rework the way we iterate on the project resources so that resources can themselves notify that they are using other resources. Project::ExposeResources calls worker.ExposeResources(&GetResourcesManager()) which calls void ArbitraryResourceWorker::ExposeResources(gd::ResourcesManager* resourcesManager) which iterates on resources:
image

That's where we should call ExposeImage/Audio/Font/Json/Video/BitmapFont according to the content of embeddedResourcesMapping . This means we'll likely need to know in the mapping the type of the resources being pointed... or not? Because we'll get the resource name, so we can just check the resource type by looking at the resource itself.

So that should work (not tested, just wrote it to check if it made sense):
image

Not very pretty too, so we could maybe improve this (have a "ExposePointedResources" in the gd::Resource class, maybe making this mapping a first class field in the C++ class, with a nice getter/setter... but for now that will do the trick!)

The tilemaps are displayed but can't be reused (if you remove the property from the object and re-add it, you get an error!).

Which error is it? This sounds weird.

Should they be transformed as tilemap resource?

I think we could keep both but I've not thought a lot about it. Do you think we could keep the JSONs for now and have this in another PR?

@daiyam
Copy link
Contributor Author

daiyam commented Nov 29, 2022

void ArbitraryResourceWorker::ExposeResources(gd::ResourcesManager* resourcesManager)

I've tried your modifs. Here my results:

  • the tileset/image is not removed when the tilemap is used.
  • the tileset/image is not removed when the tilemap is not used and still present in the resources.
  • the tileset/image is removed when the tilemap is not present in the resources.

I will search why...

Which error is it? This sounds weird.

It's an UI error:
Capture

I think we could keep both but I've not thought a lot about it. Do you think we could keep the JSONs for now and have this in another PR?

I can make the changes but:

  • .ldtk won't be able to be imported (.json will still be available)
  • the listTileMapEmbeddedFiles function, listing all the embedded tilesets, will have to moved on the json resource. It will be an extra process for those resources.

4ian added 3 commits December 22, 2022 00:08
- Adapt property groups to show that the tilemap is all that is needed for LDtk
- Add missing parameter after merge
- Robustify instance renderer code against malformed metadata in a resource
- Remove useless parameter in ExposeEmbeddeds
- Code format JsExtension.js
Copy link
Owner

@4ian 4ian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to make a last pass on the IDE changes (newIDE/app/src/ResourcesList/EmbeddedResourceSources.js...) and we should be good.

Tested and it works well. Looks like magic to add a ldtk file and get the atlas image imported :) Also fixed renaming the resources.

I wonder if at some point we should make the "embedded resource mapping" a first class concept. For now we can keep it in metadata.

@Silver-Streak
Copy link
Collaborator

I wonder if at some point we should make the "embedded resource mapping" a first class concept. For now we can keep it in metadata.

If I understand correctly, this may be valuable later on if a Music Tracker is ever added, since I believe it can need/embed instrument audio files. Nothing crucial right now, but speaks to it being valuable long term.

@@ -364,10 +364,11 @@ const defineTileMap = function (
.setFunctionName('getLayerIndex');

object
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done 👍

D8H and others added 3 commits December 22, 2022 10:55
- Use a different data types to represent different part of the process of importing embedded resources
- Remove useless properties
- Avoid some branching
- Rename functions and some properties to clarify the data being handled
@4ian 4ian merged commit 77320ce into 4ian:master Dec 22, 2022
@4ian
Copy link
Owner

4ian commented Dec 22, 2022

Alright I did a few other changes and merged this! Thanks a lot for all the work done here @daiyam! 🎉 Awesome to see LDtk maps now direclty supported by GDevelop tilemaps. This will be appreciated by a large number of users and will make their life way easier :)
We'll need to update the documentation on the wiki and maybe then work on collisions or other polishing, but overall it's working 👍

@daiyam
Copy link
Contributor Author

daiyam commented Dec 22, 2022

@4ian @D8H How do you want to proceed to support the .ldtk files?

@4ian
Copy link
Owner

4ian commented Dec 22, 2022

@daiyam Was there any particular blocker for this? Feel free to go through the JsExtension.js file, setting up tilemap/tilemapResource instead of json/jsonResource when applicable and let's see how it's going?

@daiyam
Copy link
Contributor Author

daiyam commented Dec 22, 2022

The issue is that when editing existing tilemaps, the existing resources are of type json instead of tilemap and so they can't be reused.
I think we should detect this case and convert them as tilemap resources.

@Silver-Streak
Copy link
Collaborator

Silver-Streak commented Dec 23, 2022

@4ian @daiyam Just to confirm, is this something we think can be resolved easily?

I'd want to shore up as much of the support/functionality as possible before I put my approval on the bounty.

@daiyam daiyam deleted the feat-ldtk branch December 23, 2022 07:31
@daiyam daiyam mentioned this pull request Dec 23, 2022
@daiyam
Copy link
Contributor Author

daiyam commented Dec 23, 2022

@Silver-Streak I think it is doable but the decision on how to handle it should be made by the main developers.

@4ian
Copy link
Owner

4ian commented Dec 23, 2022

Just to confirm, is this something we think can be resolved easily?

What is "this" exactly, to be sure of the scope?
We'll add support for the ldtk extension in another PR: #4733 and probably .tmj too at least.

the existing resources are of type json instead of tilemap and so they can't be reused.

For a few versions, we'll use a "fallback" allowing to display json in the selector of tilemap/tileset resources. Let's check on the other PR that this is working.

@Silver-Streak
Copy link
Collaborator

What is "this" exactly, to be sure of the scope?

Sorry, speaking specifically to the item daiyam mentioned directly above mine, as far as them being detected as json rather than tilemap resources.

@daiyam
Copy link
Contributor Author

daiyam commented Dec 23, 2022

@4ian @D8H It seems there is a regression 😭 I'm not able to set the optional tileset for a tiled tilemap. I'm searching...

Edit: bad testing from my part... the json was already in the resources as a tilemap resource...

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

Successfully merging this pull request may close these issues.

[$525 Bounty] Add support for tilemaps made in LDtk (build a parser for .ldtk files)
6 participants