#bevy_ecs_ldtk tile access help

121 messages · Page 1 of 1 (latest)

golden ibex
#

I want to get information about a cell at a certain position. how do i do this????

#

from the dependancy bevy_ecs_tilemap, it seems that you are supposed to use this:

#

using bevy_inspector_egui, I found one of those components

#

under the Walls layer of my LDTK file

#

how do i get access to this though?

#

it felt like there should be an LDTK resource to handle stuff like this but i dont think there is

#

id rather have direct access to the walls layer or some function to get it, but even so i dont know how to get a reference to a LoadedLevel in the first place

#

im very lost in this long chain components with no guide

#

added tags to this post, forgot to previously

#

if i can get the world, i can get the level, which has the layers i need to access

#

how do i even get a reference to the world within my player movement function???

#

ok, i guess i could query TileStorage with a Name that equals "Walls"?

#

this all feels so wrong

#

the LDTK tutorial itself wants me to create a Wall entity, register one for every tile, cache their positions on spawn, and seemingly go through all of them to check if its at the position you want

#

why are we reinventing this?? its a grid of tiles we literally know where the data for (5,5) is, why not just access it directly?

#

this is all so confusing

golden ibex
golden ibex
#

hep

lucid shadow
#

You can get access to the LDtk world through querying Handle<LdtkProject> and using the handle to get the actual asset from Asset<LdtkProjet>, after that there is a worlds() function on LdtkProject that can get you the world(s), or look at the other functions, some can give you access to level I think. I'm on my phone tho so none of this is tested, just looking at the doc.

golden ibex
#

ok, this is a start. how do i write that query exactly?

lucid shadow
#

Looking a bit more into it, once you have a LDtkProject, you can do ldtk_project.as_standalone() then you can get a LoadedLevel from that

golden ibex
#

i was looking at this before but was very lost. though i did see as_standalone() requires all my maps to be in one file? this is probably fine for now at least

#

i guess this also would make my function unable to be parallelized, because it would claim access to the LDTK world and not allow anything else to? (not sure if thats how it works)

lucid shadow
lucid shadow
golden ibex
#

ohhhh ok

#

that makes sense

lucid shadow
golden ibex
#

mhm, was just curious

#

should be fine until i end up needing that, which i hope by then ill have some more intuition on all of this

lucid shadow
#

Cursory looks tells me that they are somewhat different, but shouldn't be a problem for your use case as far as I can see, you get different methods for getting the LoadedLevel, but after that it looks like the same

golden ibex
#

yeah

#

i had a really hard time parsing the documentation, i could tell the tree structure that existed but was completely lost on how to get access on it

#

querying ldtkproject, but its a struct, i thought you queried entities?

#

anyways im very appreciative, ive been stumped on this for a while and this seems like the thing i needed!

lucid shadow
# golden ibex querying ldtkproject, but its a struct, i thought you queried entities?

We are querying the Handle for it, and handles are components, the actual asset is a Resource. You can query for components (which are structs or enums) and the entity id.

The way I see it, is that the query is a big filter over what kind of components the entity you are querying must have. Entities are just a bunch of components hiding in a trench coat with a serial number slapped on it. You can even see the Entity as a component that tags the group of components it's in as a particular entity, but that's not super correct and only in the point of view of a Query (i.e Query<(Entity, &MyComponent)> looks to me like we want an Entity component and a MyCompoment that are associated)

#

But anything you see in inspector_egui that's not an actual value is a component, even Children is a component

golden ibex
#

so ldtkproject is a component, that belongs to a resource?

#

i thought you could just require resources a different way

lucid shadow
#

No, LdtkProject is an Asset, which you access with Res<Assets<LdtkProject>>, the Handle for the project is a component however.

golden ibex
#

uhhhh

#

god im very new to this, but also I have to learn by doing something? especially since theres no like official tutorials. at least not past the basics.
let me double check some of these terms

#

i misread your original code snippet, there are two <LdtkProject> s, not sure why yet

lucid shadow
#

Taking the example from earlier:

  project_handles: Query<Handle<LdtkProject>>,
  assets: Res<Assets<LdtkProject>>, ...)
{
  // Get the handle from the entity
  for project_handle in &project_handles {
    // Get the actual asset from the handle
    let project_asset = assets.get(project_handle);
  }
}
golden ibex
#

LdtkProject is an Asset
oh so like how my character sprite is an asset? you mean this is like the reference to the actual file

lucid shadow
#

Most of the time an Asset is the data resulting from loading in a file, yes

golden ibex
#

ok, right. asset is kind of a term used for a lot of things so i wasnt connecting that right away

#

there wouldnt be more than one project_handle and project_asset unless i was loading two files at once right?

lucid shadow
#

then when you add it to the other assets, you get a Handle back, which is an id to be able to get back to that asset

golden ibex
#

maybe i could do the like, enforce that theres only one of them, query thing

lucid shadow
#

I you load only one I don't think it matters, but I'm not a software engineer

golden ibex
#

hmm i should learn what exactly the <> signifies in rust

#

and what res<> is

#

the others seem to make sense

#

oh actually the code is throwing errors anyways

lucid shadow
#

Res and ResMut are to get Resources, the later for mutable ones

#

<> is for qualifying generics in rust

lucid shadow
golden ibex
#

adding your code to my code

lucid shadow
#

What's it complaining about?

golden ibex
#

the trait QueryData is not implemented for bevy::prelude::Handle<bevy_ecs_ldtk::assets::LdtkProject>

lucid shadow
#

Oh, interesting, I guess it's just to hold the handle that it's there then, odd.

#

but if you only have one, you can just iterate over the Res<Asssets<LdtkProject>>

golden ibex
#

i mean,

#

oh oops

#

nvm, misread that

golden ibex
#

i remember that kinda structure being somewhere in what exists of the bevy tutorials

#

im gonna find it

lucid shadow
#

No, like you pointed out we can't query the handle, so you can just

fn my_system(projects: Res<Assets<LdtkProject>>) {
    for project in projects.iter() {
      /* whatever you need */
    }
}

you'll need to handle it if you load multiple projects later on

#

But I do agree with you, this seems waaayyy convoluted just to get to a tile

golden ibex
#

i mean, the way the tutorial suggested, just seemed

#

weird

#

here we have a clearly defined spatially structured file, so it'd be possible to point to the data just from the coordinate (ehh unless you have overlapping tiles? maybe this isnt always true)

#

even if not, an entity is created for every tile, and for every int grid

#

and then it asks you to go and make new ones and cache their positions into a list and then search the list by coordinate

#

i have never ever seen anything like that

#

its like if you exported your level to json and string searched for the tile coordinates?

#

this way is also convoluted, but I know the underlying bevy_ecs_tilemap has functionality to get() tile by coordinate which seems like the reasonable thing that i actually want

#

but now i have to possibly deal with multiple project files, multiple loaded levels, all just to access a tile

#

at the very least it seems like something i should move to its own function or service or whatever, but im not sure how i'd do that

lucid shadow
#

Why are you trying to access this specific tile?

golden ibex
#

for any purpose?

#

right now specifically, im trying to port a physics system ive made before

#

lets say a simplified version is, you cant walk into a space if theres a tile there

#

but also just for any purpose, i can assume i will need to check tiles at coordinates and get information about them, in general

#

and the suggested approach, of create a structure for each purpose, and cache their positions, then search the list seems so weird

#

i really really want a get_tile_at_coordinate(), and all its related information, because i imagine this is the kind of thing id be using all of the time

#

i tried to downgrade to the dependancy itself, bevy_ecs_tilemap, because maybe i'd have finer control over things? but i couldnt even get the example to work

#

instead of like

spikes.contains(coords)
walls.contains(coords)
doors.contains(coords)

which seems convoluded

#

im imagining something more like tile = tiles.at_coords(coords)

#

and then having all the relevant information?

lucid shadow
#

LDtk (the program itself) allows you to tag tiles with an enum (for collision tagging, etc), so I would imagine that you should be able to access that pretty easily with bevy_ecs_ldtk

golden ibex
#

just.... it may be my stubborness because maybe i could just move on with this but... really, list.contains

#

seems so wrong

golden ibex
#

thats what im trying to figure out i guess

#

i thought this would be a good place to start, if i had sprites and a tilemap id be able to get pretty far and build some intuition and learn

#

who knew just the tilemap part would be so tedious

lucid shadow
#

Looking at the doc, I don't see any way to get to those values on the tiles. I think the person that made bevy_ecs_ldtk was expecting people to use entities for carrying data. And the only way I found to access tile data, was through what we've been talking about, getting to the LoadedLevel, Level, LayerInstance, and TileInstance, which is a flat array that you would have to filter.

golden ibex
#

entity based tiles just seems so wrong to me, and, ineffecient? queries, searches, get slower with count right? an index does not

#

what do i even do. should i fold and do it in a weird uncomfortable convoluded way

#

or give up or maybe theres a third option

lucid shadow
#

With what you have right now, I would query for Name and TileStorage, and check the name. Otherwise, I would use a IntGrid/Entity to carry the data, and leave the sprite on the TileMap, so you still get the benefits for rendering. Having extra entities isn't a big deal, especially if they are not rendered.

#

The only down side is that stuff is split in LDtk, and you have to remember to put both on your map

lucid shadow
#

If you go for the IntGrid/Entity to carry the data, and the sprite on the TileMap, they won't be connected, like they would if you had the sprite on the Entity directly, so you would have to put both of them on the map each time

#

But it might be smarter to test and see if using Entities with a sprite has a significant impact on render time or not

golden ibex
#

the tiles are already entities attached with sprites right?

#

i could just.... make my own tile renderer that only does what i need it to do...

#

i hate how my mind goes to this place because it could be a good solution but it also very likely could be outside of my skills

lucid shadow
golden ibex
#

yucky...

#

ah i dont like any of my options here sadly