-
Notifications
You must be signed in to change notification settings - Fork 199
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
Upgrade tiled dep and add support for image-per-tile tilesets. #381
Conversation
This doesn't appear to work with my map. It was saved with Tiled 1.4, so I think it should be compatible with rs-tiled 0.10. https://github.com/rparrett/taipo/blob/main/assets/textures/level1.tmx |
Thanks for reviewing this @rparrett. I'm not sure why I didn't notice the obvious error for the test map rendering. I'll take another pass at this soon. |
I just pushed a change that incorporates your suggestions and fixes the test map loading. Here's screenshots of the test map being rendered as it is by default and then zoomed out to see the entire thing. The spacing between tiles looks a little strange but I think it is a rendering artifact rather than a tile placement error because it goes away when I zoom in. Would be good to test on another machine though. I wasn't able to test with your map @rparrett because it doesn't include the tileset image. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good on my end now. (tileset image for level1.tmx
is in the same repo)
I'd still like to take a slightly closer look when I have a few more minutes, especially with a map with multiple "single image" tilesets and layers.
I wouldn't expect the visual artifacts you mentioned to be related to this PR.
examples/helpers/tiled.rs
Outdated
x: tiled_map.map.tile_width as f32, | ||
y: tiled_map.map.tile_height as f32, | ||
}; | ||
match tile_layer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we collapse this match into a let else guard also?
examples/helpers/tiled.rs
Outdated
y: tiled_map.map.height, | ||
let tiled::LayerType::TileLayer(tile_layer) = layer.layer_type() else { | ||
log::info!( | ||
"Skipping layer because {:?} is not supported.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like the debug impl for LayerType
prints all the map data somehow, making this spew several screens of spam for my map.
Maybe something like
log::info!(
"Skipping layer {} because it is an unsupported type",
layer.id()
);
would be adequate?
examples/helpers/tiled.rs
Outdated
.insert(layer_index as u32, layer_entity); | ||
} | ||
_ => { | ||
log::info!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing here about the debug print.
examples/helpers/tiled.rs
Outdated
}) | ||
.id(); | ||
tile_storage.set(&tile_pos, tile_entity); | ||
let texture = if tiled_map.tile_texture_indexes.is_empty() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like it should be possible to allow "image collection tilesets" as well as normal tilesets in a single map, provided each layer exclusively uses one or the other type of tileset.
But this code causes TilemapTexture::Vector
to be used for every layer if any layer uses an image collection tileset.
A couple more notes:
|
I just pushed a commit that unifies the handling of single image and image collection tilesets, skipping the latter when the atlas feature is enabled. I also updated Here is a screenshot with the atlas feature enabled and another with it disabled: In the second screenshot you can see the castles because they use an image collection tileset. Here's is the rendering of the level1.tmx file you linked to earlier: I haven't had a chance to test a layer that uses multiple tilesets yet. I plan to do that soon but I've run out of time for the day. |
examples/helpers/tiled.rs
Outdated
TilemapTexture::Single(tile_images[0].clone_weak()) | ||
} else { | ||
#[cfg(feature = "atlas")] | ||
panic!("Cannot use Tiled maps with a tileset that uses a collection of images due to incompatibility with the 'atlas' feature."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not really panic because the tileset should be skipped earlier in the loop. However I wasn't sure how to satisfy the compiler without an even more extreme solution, such as generating a placeholder TilemapTexture::Single()
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had an idea for cleaning up this and related code: rparrett@b9e707c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, this turned out to be a bad idea, as it also can't compile with the atlas feature. But maybe some parts are still useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed that up in a new commit here: rparrett@b794f2d which seems to be behaving, apart from some warnings that should probably be cleaned up when compiled with atlas
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks good to me. Works in my game. I like the idea of creating the Single
and Vector
structs earlier in the loading process. I had tried to do that but ran into some ownership issues and dialed it back for time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a couple warnings being generated still when building with the atlas
feature. I couldn't figure out a way to do that any more elegantly than sprinkling more #[cfg(not(feature = "atlas"))]
where rust is complaining.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dvogel @rparrett this is generally looking good to me. Feel free to ping me once you've settled down on solutions overall/CI is passing, and I'll merge it!
(currently, CI is not failing, but it has some review suggestions, some unnecessary mut
s apparently?)
(thanks very much for your contributions!)
Co-authored-by: Rob Parrett <robparrett@gmail.com>
I was able to suppress all of the remaining cargo check errors by completely removing the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be working well on my end now. Thanks for all the effort to make this work with the atlas
feature.
It's a bit unfortunate that this code that is likely to end up copy/pasted into users' projects won't work in those projects as-is. (due to feature gating on a bevy_ecs_tilemap
feature). Users would need to manually fix up the feature gated code based on whether or not they need the atlas
feature.
That seems preferable to other options
- not supporting image collection tilesets
- adding a completely separate
TiledMapPlugin
helper and feature gate inexamples/tiled.rs
instead - ?
Perhaps we should at least add a comment at the top somewhere explaining the situation.
Hmm, I am thinking: this might be a pretty good idea. Speaking from an end-user perspective, it seems clearer? But we can leave this for another PR. For now, we can merge as is, with a comment explaining the situation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me overall. We can further refine it new PRs. I do like @rparrett 's suggestion that we should leave a comment explaining the situation, so that's the only change I am going to request!
I just pushed a comment with an explanation of how the code will need to be cleaned up when adopted. @rparrett please double-check my explanation as it took me a few reads through your comments to understand that you meant their code wouldn't compile once copied over.
To be honest I was a initially a little lost re: this feature. I didn't realize it was an option until well into trying to update this helper. I think even with the comment I added to the top of the helper a new user may struggle to understand what to do since the atlas feature isn't advertised up front. As best I can tell it is an optimization to load sprite sheets into the GPU more efficiently than could be done otherwise. I don't understand how it is incompatible with the alternative tilemap texture modes though. My current impression is that the feature could be removed without much downside. I assume that's not actually true, but whatever I'm missing is likely a good piece to add to the documentation :) Long term it seems like maybe this could become full-featured enough to remain in the bevy_ecs_tilemap crate, re-exported for end-users to |
The feature is not well documented. I left a comment in there that might be helpful for understanding the atlas feature. But the gist is that it's there for compatibility with webgl2.
Right, yeah. It's unfortunate that I didn't realize that sooner. I think the comment generally looks good. Although now that it's all spelled out, it feels quite bad to ask users to do all that. Looking forward to when the We should definitely follow up on that before the next release if there's consensus about that. |
Thank you so much, dvogel and rparrett. 🙏 It will be nice indeed when we can yeet |
This does two things:
tiled
dependency. Should be no change in actual functionality but the 0.10 version is much easier to work with than the 0.9 version. (fixes Updatetiled
to version0.10
#249 and Newertiled
dependency planned? #320).Here is a screenshot of the example running with this code:
Here is a screenshot of a map loaded with the new image-per-tile support (this file has 5 layers and each is rendered as I see it in Tiled):