mapeditor / rs-tiled

Reads files from the Tiled editor into Rust
https://crates.io/crates/tiled
MIT License
269 stars 102 forks source link

Amethyst Integration #50

Closed yaahc closed 2 years ago

yaahc commented 6 years ago

Hi, I'm working on a game using the amethyst game engine and I'm planning on using this lib to do the map. It seems like it might be something useful to push back up stream so I wanted to create an issue to see if you wanted such a feature to get merged into this or a companion crate, and if so if you have any input on how you think it should be designed.

I'm not exactly an expert with this library or amethyst or game development in general but my initial idea is to have a function that takes a tiled::Map and either returns an amethyst::renderer::SpriteSheet or output serialized data (possibly writing it to a file) that matches https://www.amethyst.rs/doc/latest/doc/amethyst_renderer/struct.SpriteSheetFormat.html.

The first option seems more straightforward and efficient but it doesn't match the examples which are always loading sprite-sheets from files and it creates a common dependency between rs-tiled and part of amethyst, though it can be conditionally compiled with a feature. I'm not really sure which one is best.

The function would also need to return something like a Vec<(Transform, SpriteRender)> which can be easily iterated over and added to the world as entities.

If I'm way off base on this just let me know :)

mattyhall commented 6 years ago

Hi, sorry for the delay in replying. Anything that makes this library easier to use for people I would be more than happy to accept a PR for! I'm afraid I don't too much about amethyst either. I agree that the first option seems the best way to go in my opinion - transforming one format to another through a file, loading it in again etc seems like it could be quite flaky and just generally a bit annoying to use. I don't think there's necessarily anything wrong with companion crates, a lot of rust projects seem to go a similar route. Maybe it'd be worth seeing how the code comes out and based on that decide where it should live.

Sorry if this sounds a bit vague, I'm not really sure either! :)

yaahc commented 6 years ago

Hey no worries, I know the feeling.

I have some working code, https://github.com/yaahallo/gameoff/blob/407e14f3f1f8ead98f15985775ea0a45fab459a8/game-core/src/map.rs its not split up or anything its just a module in a game I'm working on and it needs to be split up a bit, theres some hacky unrelated things that dont really relate specifically to amethyst that wont need to get in there but its a good starting point I think and if I never get around to getting this split up and pushed back at least people will hopefully be able to find this issue and look back on the old code to jump start off of.

To summarize. I got it working with in memory construction of the sprite sheet layout which is then passed directly into the engine. Then it iterates through the tiles in the map and draws those. It draws them from bottom left to top right starting at the origin so that all tiles are in the positive x,y coordinate space. I'm not sure how much value there is to breaking this out into a library and making it configurable because im sure different people will have different use cases so maybe this can just be an example that is prominently linked so people can pull it into their code and modify to fit their usecase? I don't know.

Side note / question: I did notice that the indexes that rs-tiled has for each map tile is off by one from the indexes uses in the xml document, I'm curious about why this is, it seems to me like you shifted all the tile ids up by one so that you could store it in an unsigned number but im not sure why.

yaahc commented 6 years ago

Also, I dont have the specifics on the issue but im going to report this while i vaguely remember it and maybe I can go back and get you more details if its not immediately obvious what was wrong but I tried initially using parse and was getting some errors back (i know, no memory of what the errors were, not useful), and had to resort to using parse_file instead. I remember thinking the example in the root README was invalid as a result of my investigation. If I have time I'll try to recreate the issue later and log it properly as a separate issue.

mattyhall commented 6 years ago

It looks good :smile: I think you're right that it's possibly not worth putting into a library, would definitely be cool as an example. By the look of it it could be the tile flipping stuff that is causing the off by one error, if you mean the tile id? I didn't write that and didn't check it too closely, so might take a while to investigate.

Not sure why parse would fail, that's interesting.

Thanks for writing such detailed comments :)

yaahc commented 6 years ago

The off by one is the tile Id not index. So the tile on the sheet shows up as 29 in tiled editor and xml but it shows up as 30 in the layer vec of vecs of u32. The spec for the xml uses -1 for empty spaces I think but you obviously can't represent that with a u32 so I think the other person I guess just added 1

AnneKitsune commented 6 years ago

Normally we implement loaders for external crates in amethyst by creating a type implementing the Format trait. We will see on our side if we can integrate the loading and we will let you know of any issues :)

jaynus commented 5 years ago

I've implemented exporting spritesheets to amethyst spritesheet RON files. The amethyst portion could be extracted and put directly into Tiled (or a separate crate).

I chose this method as maps are imported differently based on game - but the spritesheet format is a pretty standard conversion for all amethyst projects for Tiled -> amethyst. I also chose exporting to the RON format, instead of the runtime definitions, as this is implemented for a resource baking process for my project (so it is converted Tiled -> amethyst once at compile time).

A problem that happens here, however, is that the serialized object format is not public from amethyst_renderer, so I need to redefine it locally. Besides that, its really super easy.

Its super simple, really. The rest of this crate is my 2D grid data store.

Relevant code: https://github.com/jaynus/survival-tiles/blob/master/src/lib.rs#L280-L348

simple tool, survival_tiles_tool convert -i blah.tmx -o blah.ron

I have a seperate fork of rs-tiled already for some cleanup and code changes. I could PR this if its relevant or wanted.

Moxinilian commented 5 years ago

Hello! I made the spritesheet serialization format in Amethyst. I made the types private because I did not expect it to be used by third parties to serialize them. There is no reason for it to be private (beyond avoiding expansion of the type zoo), so if you want to tweak the naming to make them more explicit and make it public, you sure can PR such modifications into Amethyst.

mattyhall commented 5 years ago

@jaynus That's cool! I'm not totally against including it, but I'm not sure whether there's much benefit compared to a separate crate. Particularly seeing as you wrote the code and (seem to be) using it for a game. I'm more than happy to be convinced otherwise if you'd prefer it to be in tiled though!

erlend-sh commented 5 years ago

@yaahallo maybe your code could be worked into @temeez’ example repo: https://github.com/Temeez/Tiled-Amethyst-Example

bjorn commented 2 years ago

Is this topic still relevant now that Amethyst development has halted?

In general I think it's a good idea to include some basic examples in this repository, since it enables quick testing of changes and makes developers of this crate aware of any compatibility breakage and allows others to see as well how this may affect their code.

bjorn commented 2 years ago

Closing this issue since an Amethyst example would not make much sense when it's no longer actively maintained, and its latest release even requires pinning to an old Rust version (1.47, according to the readme).