#bevy_ecs_ldtk
1145 messages · Page 2 of 2 (latest)
the spikes in-game are offset down, so any other anchor just pushes them further off
have tried a few
Bevy sprites are default anchored in the center though, unless you changed that?
Not sure if bevy_ecs_ldtk propagates that
hmm, yeah i mean, the ldtk entities are anchored top-left but the position bevy_ecs_ldtk spawns them in is like, 6 pixels from the bottom center
changing the ldtk anchor to center just puts them further off
actually no, it just doesn't have any effect
they're the same amount offset
so maybe bevy_ecs_ldtk is like... trying to correct the anchor somehow and getting it wrong
i figured it out - the ldtk level size somehow got stuck in a non-integer multiple of the tile size and this was messing up bevy_ecs_ldtk's height adjustment in ldtk_pixel_coords_to_translation_pivoted
the pixel height of the level was 10 pixels off from being an even number of tiles
nice detective work, sounds devious to troubleshoot
libraries always seem like an inscrutable black box until the moment i start just looking for "the bevy system that spawns this thing" lol
Hello guys, good morning. I would like to chunk render my map based on the camera position and GridCoord. Do you know if there is an easy way to do that?
how should i handle different variants of entities? should i have an enum or should i just have separate entities for each?
2 months late but there is this guide that makes the level selection follow the player, and you can set it to load neighbouring levels, i think that's what you're looking for? https://trouv.github.io/bevy_ecs_ldtk/v0.12.0/how-to-guides/make-level-selection-follow-player.html
@vagrant summit
What's your use case? I think it kinda depends on how different the variants are, and how much you want to segregate them in system code. Like, if you had them be different entities, that allows you to give them different components, which allows you to access one or the other in queries really easily. But if they're mostly going to have the same behavior, then that might not be worth the trouble, and an enum field would suffice.
What is the best way to add observers to entities spawned from the level, I want to implement something similar to https://bevy.org/examples/picking/mesh-picking/ with the hover function adding a marker component to the entities once hovered and remove it once not hovered, I know I can add a system that checks for <add> entities but what is the best way to do it, is there a way to hook into the spawn process directly?
Will have to get back to you later today on this, I haven't used observers yet (haven't had much time for game dev since their release)
Thanks in advance and love using this library for my game!
the recommended "blueprint pattern" takes care of this just fine and is much nicer than using bundles - https://trouv.github.io/bevy_ecs_ldtk/v0.12.0/explanation/game-logic-integration.html#a-combined-approach---the-blueprint-pattern
in particular you can add a world observer with Trigger<OnAdd, Player> instead of using the Added filter to hook into the process more directly
So an observer that adds the other generic observers that will act onHover? @slow slate
I used the blueprint method for initializing rigid bodies on walls so far and etc, just wanted to know if this is the best way to do so here as well
yeah, either that or you can add one global hover observer and then check if the hovered entity is one you're interested in, in case you'd be adding a lot of observers otherwise
looking into observers now, but the limitation for doing it w/ derive(LdtkEntity) would be that you don't have access to the bevy Entity associated w/ the ldtk entity, which you would want sometimes. But if it's okay if the use case allows for global observers
fn observe_hovers(_: &EntityInstance) -> Observer {
Observer::new(|trigger: Trigger<Pointer<Over>>| {
println!("detected hover");
})
}
#[derive(Bundle, LdtkEntity)]
struct MyLdtkEntity {
#[with(observe_hovers)]
observer: Observer,
}
Haven't tried compiling this or anything, just an idea
I imagine in most observer pattern use cases, post-processing/blueprint would be required
using #[from_entity_instance] is there a way to pass in the world size?
@vagrant summit
the best you can do rn is implement LdtkEntity directly, and get some height details from the layer_instance. I guess it only has the grid height of the layer though, not pixel height
I'm actually kind of surprised that it doesn't, looking at the code. let me check
yeah actually, that seems to be the behavior in the platformer example. Whole world is respawned, including the player. Though, now that I think about it, there might be a weird thing where you hot reload while the player's birth-level is unselected
ah, i haven't heard of the birth level
is that a thing in vanilla ldtk or specifically the bevy implementation?
it's not really a documented concept or anything, it's just whatever level the player is actually placed in in LDtk. When the world respawns it'll just despawn everything and then start the spawning process again for whatever levels are currently selected. If none of the currently selected levels contain the player in LDtk, then the player wouldn't be spawned.
Idk if that's what you're observing, just a guess
it works when the starting level is loaded in
that makes sense. Are you changing the level selection as the player traverses the world, like the platformer example?
yeah
You could potentially hack around this, though I can't guarantee how well it would work. Instead of making the player worldly, which makes it a child of the world and thus despawned on hot-reload, you could go further and make it not have a parent at all
Collection of methods similar to the built-in parenting methods on EntityWorldMut and EntityCommands, but preserving each entity’s GlobalTransform.
fwiw, the way i worked around this was to completely decouple the player spawn from level spawn - instead, i placed spawn points in the levels (invisible but always exist) and have the player spawn on the current level's spawn point (found by iterating children in the current level)
player needing a respawn is marked by a resource being present
hey @vagrant summit! quick question, how are you handling collisions and creating colliders? Is that deferred to devs to setup for walls/obstacles/etc, or do you parse any of the data in LDTk?
@vagrant summit any plans for 0.17? I can open a pr with basic stuff if you want but theres this new thing with tilemap chunks that I think is beyond my expertise
bevy_ecs_ldtk probably can't port to the upstream tilemapchunks yet. They're significantly less-featured than bevy_ecs_tilemap (which is what bevy_ecs_ldtk is currently based on). Notably, there's not support for entities on tiles and such.
ah cool, so migration should be pretty easy
yeah, migration for bevy_ecs_tilemap was pretty easy too. mostly renames and such
oh has that been done already? lol i was just doing it...
yeah it's currently published on crates.io even
It's a bit different depending on whether you're spawning colliders for entities or trying to spawn large colliders that cover many intgrid tiles. But the plugin doesn't have anything built in for either, just hooks and tools for your own solution. The platformer example does a bit of both, there's a kinda complex function for spawning wall colliders that cover many intgrid tiles close-to-optimally
yeah, even if it could (or maybe, when the time comes), I'd be happy to release a version that's a more minimal upgrade to the new bevy that's quicker and easier to migrate to, and then a followup that's more intense
@vagrant summit i opened a draft pr
looks like there's something wrong, every tile hitbox is spawning at the same place
it might be an avian thing
there are some other issues
@vagrant summit I don't really know how to fix this, could you take a look?
yes I will, I appreciate you getting this started
huh, are you talking about the platformer example? Bevy rapier2d has not even upgraded to bevy 0.17 yet. Unless you're using the 0.17 branch in rapier, but that's not in the Cargo.toml
No, im using avian with my own project
@vagrant summit have you made any progress? It's possible it could be avian as well but I have no idea
I'll try and get some more examples working on your branch, if the necessary crates are available
then maybe that'll reveal a bug
Well there's definitely some strange stuff going on, but it looks like collision placement isn't completely broken
Figured out one bug related to transforms. I'll push, hope you don't mind
Ugh I messed up some git operation and lost the ability to contribute to your branch after rebasing it so your commits are gone from your remote. Terribly sorry
Will put up a new branch on the upstream w/ your changes
I feel so validated, because I have literally made this exact same mistake before
Oh ok that's alright, ill see if it's working when I get home
to be honest, while the fix is transform related, your issue sounds like it might be completely different. Though, the platformer example is working, so at least rapier2d hitboxes seem fine.
I think it's transform, ill see
@vagrant summit it's not fixed unfortunately
it seems like a pretty normal usecase not sure why i'm having an issue
Made some changes to hopefully get CI passing
If you can either produce a minimal eample, that'd be awesome. Or maybe share your project w/ me, I might be able to figure it out from that. It seems like all the lib examples are working fine now
are any of the examples using avian?
They are not, just rapier
ah, it's probably an issue with the avian integration then
i'll send you the link to my project
i think it would be easier than reproducing it? i can try if you want though
oh wait i haven't pushed my migration yet one sec
@vagrant summit https://github.com/Lenchog/Simulacrum/tree/migration
nix flakes, nix config repo, based are we?

i was actually just trying to chase down this same issue and was trying to figure it out.
spawning entities with a Position component from avian fixes the issue, maybe scheduling issues related to the transform sync plugin?
more digging points to avian::physics_transform::transform::init_physics_transform overwriting the transform.
Nice, thats progress, have you posted this to #1124043933886976171
posted about it, someone pointed that it could be related to doing
spawn_empty().insert();
i created a minimal example that showcases the issue.
https://github.com/Hellzbellz123/test_issue
CHANGING COMPONENT INSERTIONS DID FIX IT
leftover debug from my project was preventing me from seeing the changes.
moving the component insertions to the same fn call seems to fix the example but it doesnt work on my actual project
@vagrant summit @lament forge
i have fix but this seems like a hack
opened a pr on github.
im assuming inserting transform on entity instances at the end is an attempt to prevent them from being overwritten by whatever bundle you register so i left it.
@random moth i added your fork to my project and there are no colliders at all for some reason
you mean the one you linked earlier or something else
yeah that one
took me a while to get it to compile, did some poking, it seems that with my repo the colliders DO spawn, just all at 0,0. the change i made only effected the entity spawning codepath and not tile spawning.
i am unsure how to fix the intgrid spawning.
messed with internals a bit and spawning every tile with a transform causes the layers to get positioned strangely.
gross hack that 'fixes' the issue. im unsure on specific behavior for your game so youll have to test yourself.
fn toggle_avian_sync(
time: Res<Time>,
mut avian_cfg: ResMut<PhysicsTransformConfig>,
mut level_transform_stuff: MessageReader<LevelEvent>,
mut unpause_timer: Local<Timer>,
){
let new_unpause_timer = Timer::new(Duration::from_secs_f32(0.1), TimerMode::Once);
unpause_timer.tick(time.delta());
for event in level_transform_stuff.read() {
match event {
LevelEvent::SpawnTriggered(_level_iid) => {
// disable physics transform config
avian_cfg.position_to_transform = false;
*unpause_timer = new_unpause_timer.clone();
},
_ => {},
}
}
if unpause_timer.is_finished() {
avian_cfg.position_to_transform = true
}
}
@vagrant summit @random moth my issue with colliders is now fixed on avian's main branch
thanks for all your efforts looking into this integration issue, @lament forge and @random moth , I feel more comfortable releasing 0.13 now
When I load a level, it is not rendering the whole tilemap, even though the whole level is loaded (you can see from the colliders). Any idea what could be causing this? It doesn't happen with small levels I load. I am running the branch that works with bevy 0.17.
do you know if this level was working on 0.16?
I didn't try it on bevy 0.16. It's a new project I started with 0.17. It's not a specicfic level. Any level that is longer than a specific width will not render after a certain point, but the level data is there as I can see the entities that I spawned.
Here's another screenshot. The level I am currently in stops rendering, but I have load_level_neighbors on, so you can see some tiles render from the next level in the lower right. And colliders which are spawned from entities are still there. It seems to draw tiles from left to right, and stops drawing them after it gets to the 65th tile. It is happening on levels that are more than 64 tiles wide. The 65th tile and after is not drawn. It still happens if load_level_neighbors is off.
It’s probably related to the new chunk rendering in bevy 0.17. Maybe a chunk is 64 tiles and it’s only rendering the first chunk of each level.
Also I don’t know if the problem is the ldtk plugin or if it’s the underlying tilemap plugin
I saw there were some new commits. I ran cargo update and the issue persists.
Apparently this is happening because I am scaling the parent entity that contains the map. I don't want to use pixels as coordinates so I am scaling the parent that contains the tilemap. It is frustrating if there is no way to scale the map that works. I want to use tiles as units, not pixels.
It's because I am using physics I wanted to have my character be 2 units tall. But maybe I should just give up and use pixels.
Is bevy_ecs_tilemap using the chunk rendering? I was under the impression they didn't want to because it doesn't support hex grids and a bunch of other stuff
It doesn't look like it's using the new chunk rendering based on the commit history
I don't know. In the features it says "Fast rendering using a chunked approach". Maybe it is a custom form of chunk-based rendering. But it seems I should have posted this in the thread for that plugin.
I posted in the tilemap plugin thread also. Will see what they say. They will probably just say not to scale the map.
yeah, ecs_tilemaps's current chunked rendering pre-dates TilemapChunk by a long time.
the issue here is allegedly related to scaling transforms, but we don't currently have a reproduction case to test.
0.13 is out
hehe it was out like 5 minutes before i needed it thanks :)
a built in solution for avian/rapier would be a really cool feature imo
Yeah I was just thinking yesterday it's probably within our purview to have at least some sort of tile grouping solution that can tell user where all rectangles of tiles are that to make it easier to spawn colliders
is there a way to alter the z position of individual tiles in a layer? I know that you can offset their x and y positions but I haven't found a way to z-sort stuff properly other than dividing it in multiple layers which is kind of a pain.
although I guess it's more of a https://discord.com/channels/691052431525675048/1034547455032832021 problem
Does it? we only really have y-sorting w/ bevy_ecs_tilemap within a layer, which comes into play especially when you have a grid with some overlap. I've had users ask about z-sorting individual tiles before and I thought the answer was just no, bevy_ecs_tilemap doesn't do it
the render chunk size can reduce the chunk to a single tile, basically.
only real way I know of to do inter-layer depth sorting is to use a custom material with the depth texture.
this. The problem is that I also have walls that are 2-tiles high so I’d want to offset the z value of the upper tile so they have the same z, which isn’t possible afaik
I’m thinking of making a fork for it, although I’ll need to fork both crates which sucks
basically add an adjustable z to each tile, besides the existing x and y, and have chunks be offset by the z of one of the tiles they contain (top-right tile or whatever is convenient, a 1x1 chunk will just have the z offset of the single tile it contains)
should be relatively clean although a bit confusing for chunks that aren’t 1x1
shameless plug of my new crate: #crates message
Hello, not sure if I'm going against the grain here but, I created a level that has some terrain tiles and a single ldtk entity LoadNextLevel. The entity has a rectangle shape, an editor color, and a size of 32x32. However, when I load the ldtk file with the plugin, my terrain tiles show up, but the entity does not.
I'm guessing the entity doesn't render because it doesn't have any sprite info associated with it, but is there a way to have the entity spawn as a sprite with the rectangle shape and editor color I set? Maybe something I need to specify in the bundle struct?
I'm not sure if I should just specify a tile on the entity from the ldtk side, or add a system on the bevy side that looks for the LoadNextLevel entity and spawns its own bevy rectangle sprite from that. But in the bevy sprite case, I'd still like the sprite to use the color I had set in the editor field (see image). Does that color even get loaded on the bevy side?
Thanks and sorry for the wall of text. I'm new to using this plugin, but it seems great so far!
With the plugin as it is today, I would expect the entity to still exist, but just not have any visuals. There isn't anything for showing entity color in the plugin today, we only do that for intgrid tiles that don't have a tileset.
So, you'll need to do something else if you want some visuals on it. Either by doing extra work on the bevy/plugin side to give it a visual, or doing some extra work on the asset side to give it a sprite. You could do the former by writing some Fn(&EntityInstance) -> Sprite entity that creates an orange rectangle sprite, then putting it on your bundle w/ the #[with] attribute macro: https://docs.rs/bevy_ecs_ldtk/latest/bevy_ecs_ldtk/app/trait.LdtkEntity.html#with
Provides a constructor which can be used for spawning entities from an LDtk file.
Awesome, thanks for the info!
@vagrant summit is there any way to get the borders of the current room? i wanna improve my camera, it looks like you've planned to write doc for it but haven't done it yet?
You basically need to get the raw level data from the assets resource. The platformer example does something like this: https://github.com/Trouv/bevy_ecs_ldtk/blob/main/examples/platformer/camera.rs#L43
Sorry I'm going to bed now, if you have more questions I won't see them
bevy 0.18 is now try-able:
https://github.com/Trouv/bevy_ecs_ldtk/pull/396
Sorry if this is a silly question, I've been trying to figure out how to do Entities that are animated/spritesheets. I had a look through the book and tried searching the docs-rs but couldn't really come up with anything.
I came across this video but Chris is doing it very manually here, is there a better way?
drag-and-drop LDtk levels in a Bevy App
https://github.com/rust-adventure/yt-bevy-ldtk-drag-and-drop-levels
@waxen finch I think this is not the best place for this question since it is not related with ldtk or the crate itself...
However, answering it, I am doing the animation manually too. There is a Bevy example for it:
Sprite Animation https://share.google/UzN86axOMk53JpOsE
Bevy is a refreshingly simple data-driven game engine built in Rust. It is free and open-source forever!
Right, do you put some metadata on the ldtk side and read that from in bevy (like number of sprites in the anim), or do you just recognise certain entities and hardcode the spritesheet configuration in bevy and use the ldtk entity as more of a "marker"?
I just assumed animated sprites would be a pretty common thing for a 2d game editor like ldtk. But I can see why ldtk wouldn't want to get into supporting it if it is trying to be purely a level editor.
I'll need to check, but I'm pretty certain you just need to add the animation code into bevy. And ldtk can load the spritesheet if you set it up right.
Ultimately, LDtk and the plugin don't build-in a solution for animation, but it is pretty flexible for you to add some "application-defined" data. I am aware of users that are encoding animation indices for LDtk entities using entity fields. I think this is a good approach. The plugin has APIs for then accessing those fields if you have the EntityInstance (either by using a #[with(foo)] on the LdtkEntity-derived bundle, or by just querying for it).
See LdtkFields trait: https://docs.rs/bevy_ecs_ldtk/latest/bevy_ecs_ldtk/ldtk/ldtk_fields/trait.LdtkFields.html
Convenience methods for accessing field instances.
Hi everyone! Quick q regarding Worldly usage. Is this valid?
#[derive(Bundle, LdtkEntity)]
#[worldly]
struct MyBundle {
// fields
}
Or should I do it like
#[derive(Bundle, LdtkEntity)]
struct MyBundle {
// fields
#[worldly]
worldly: Worldly,
}
Thanks a lot! 😄
Only the second works