#bevy_ecs_tilemap

1 messages · Page 3 of 1

oak roost
#

Was doing my upgrade to 0.11 and when using iso in diamond mod the shader fails. Staggered works fine. Any tips or is it a known error of the release?

2023-07-28T20:33:37.762230Z ERROR bevy_render::render_resource::pipeline_cache: failed to process shader:
error: unknown type: 'MeshOutput'
   ┌─ /home/edgarssilva/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs_tilemap-0.11.0/src/render/shaders/diamond_iso.wgsl:12:58
   │
12 │ fn get_mesh(v_index: u32, vertex_position: vec3<f32>) -> MeshOutput {
   │                                                          ^^^^^^^^^^ unknown type
   │
   = unknown type: 'MeshOutput'
oak roost
#

I just saw the last commit on the main branch 😛 Will try it out

oak roost
#

That fixed it thx

shy osprey
#

Curious if there's plans to release 0.11.1 soon?

brisk path
shy osprey
#

cool, thanks

oak roost
#

Currently the rapier debug renderer (using bevy gizmos) appears behind my map, is there an easy for this?

unreal condor
worldly spire
final veldt
#

How can I get position of a tile in a storage from a shader?

final veldt
#

Also I found a bug: I get wrong values of uniforms.
This is the material:

#[derive(AsBindGroup, TypePath, TypeUuid, Clone)]
#[uuid = "9114bbd2-1bb3-4b5a-a710-8965798db745"]
pub(crate) struct TileMaterial {
    #[uniform(0)]
    pub(crate) test: f32
}

impl MaterialTilemap for TileMaterial {
    fn fragment_shader() -> ShaderRef {
        "shaders/post_processing.wgsl".into()
    }
}

This is the shader:

#import bevy_ecs_tilemap::common process_fragment
#import bevy_ecs_tilemap::vertex_output MeshVertexOutput

@group(1) @binding(0)
var<uniform> test: f32;

@fragment
fn fragment(in: MeshVertexOutput) -> @location(0) vec4<f32> {
    let color = process_fragment(in);

    return vec4(vec3(test), 1.);
}

And this is how I spawn the tilemap:

commands
    .entity(tilemap_entity)
    .insert(Chunk::new(chunk_pos, ChunkType::Tile))
    .insert(MaterialTilemapBundle::<TileMaterial> {
        grid_size: TilemapGridSize {
            x: TILE_SIZE,
            y: TILE_SIZE,
        },
        size: CHUNKMAP_SIZE,
        storage: tile_storage,
        texture: TilemapTexture::Single(block_assets.tiles.clone_weak()),
        tile_size: TilemapTileSize {
            x: TILE_SIZE,
            y: TILE_SIZE,
        },
        spacing: TilemapSpacing {
            x: 2.,
            y: 2.
        },
        transform: Transform::from_xyz(0., 0., 2.),
        material: materials.add(TileMaterial {
            test: 0.
        }),
        map_type: TilemapType::Square,
        visibility: default(),
        global_transform: default(),
        computed_visibility: default(),
        frustum_culling: default(),
    });

So, obviously, the value of the test uniform in shader should be 0, but it's not.

brisk pasture
#

Does this support hot reloading?

#

because after saving the map tiles just go away

ember hazel
#

Hello, how can I add Y sorting for my game (including sorting sprites and sprites & tilemap)? Is this crate capable enough?

celest matrix
#

The crate says:

Fast rendering using a chunked approach.
How "fast" is this and in comparison to what? I mean let's say instead of using this crate, I just do the naive thing of spawning X times Y normal bevy entities with SpriteBundles and Transforms such that the sprites lines up on a grid. So that I effectively render what appears as an X times Y tilemap. How much faster will this crate be in rendering?

As a really simple test, I tried increasing the map_size in the many_sprites bevy example to 1280, which is the same map size used in the bench example in bevy_ecs_tilemap. Bevy's many_sprites example then gave me an FPS just under 100, while the bevy_ecs_tilemap bench only gives me a framerate of around 40 (both tests built in release mode). But maybe this isn't a fair comparison somehow? I'm just kind of curious what benefit this crate brings with regards to performance as I can't really easily see what the benefit is from this super simple test.

It'd be nice if the README showed some stats or had some comparison benchmarks or something to show how exactly the rendering is faster (and compared to what).

unreal condor
#

I don't think perf has been looked at closely in a long time. At a glance I think the comparison is somewhat fair. "fast" is meant to be relative to naively spawning one sprite per tile. bevy_ecs_tilemap should be doing one draw call vs. one per sprite. But in reality, perf in bevy can be dominated by extraction overhead and visibility/transform propagation/etc and all of that has been through quite a lot in the past few release cycles. 2d frustum culling is relatively new to bevy as well and sped that example up significantly.

Would definitely be worth taking a closer look to make sure we didn't introduce a major perf regression at some point.

brisk path
#

I just got back from vacation and will try to spend some time maybe tomorrow evening on cleaning stuff up and getting another release out.

unreal condor
#

Welcome back! Hope that was refreshing.

brisk path
celest matrix
#

It'd be great if there was some benchmark showing the performance benefit 🙂 - obviously the test I did was quite rudimentary so perhaps with a different setup, the performance benefits are more obvious

final veldt
final veldt
#

The first two binding indices (0, 1) are random values, and starting from binding index 2 and greater it panics with the error:

2023-08-21T13:13:28.709983Z ERROR wgpu::backend::direct: Handling wgpu errors as fatal by default    
thread 'main' panicked at 'wgpu error: Validation Error

Caused by:
    In Device::create_render_pipeline
      note: label = `tilemap_pipeline`
    Error matching ShaderStages(FRAGMENT) shader requirements against the pipeline
    Shader global ResourceBinding { group: 1, binding: 2 } is not available in the layout pipeline layout
    Binding is missing from the pipeline layout
final veldt
final veldt
unreal condor
#

I looked into that briefly a little while back and the change suggested in #455 did not fix the issue, as far as I could tell.

unreal condor
#

o_O

final veldt
#

Did you set the group index to 3 in the shader?

#

of the uniform

unreal condor
#

No idea at this point. I tried all sorts of stuff.

If you open a PR I'll take a look / get CI moving.

final veldt
#

In my local fork of bevy_ecs_tilemap I did the change suggested in #455 and it fixed the bug, but you need to set group index to 3

#

Like this

#import bevy_ecs_tilemap::common process_fragment
#import bevy_ecs_tilemap::vertex_output MeshVertexOutput

@group(3) @binding(0)
var<uniform> test: f32;

@fragment
fn fragment(in: MeshVertexOutput) -> @location(0) vec4<f32> {
    let color = process_fragment(in);
    
    return vec4(vec3(test), 1.);
}
final veldt
final veldt
#

Also I noticed that there is no way to get position of a tile in a storage that is a very useful information

#

I see that is being provided to the vertex shader but not exposed in MeshVertexOutput

#

I added a new field to MeshVertexOutput

#

And in the vertex shader I did

#

And it works

celest matrix
#

I'm trying to spawn a tilemap in an OnTransition schedule but it doesn't seem to work. It works fine if I move the system to the Startup schedule and keep everything else the same. What could cause this?

#

Unrelatedly, is there a way to set the actual size (not pixel size) of tiles? I'd like all my tiles to be 1.0 x 1.0 but the tile images are obviously not 1 pixel. And I don't want the tilemap to change size based on the tile resolution. Setting the grid size to 1.0 x 1.0 results in weird results.

ember hazel
#

Hello, how can I apply a color to the whole tilemap (akin to what you can do with the TileColor component). I've been using a system that applies a computed color to TileColor components, but it's pretty slow as there is no way to filter tiles (TileBundle does not have a ComputedVisibility component), which makes it really slow on larger tilemaps (at least 128x128).

spring lintel
#

I'm getting the following error when I try to use the code from the iso_diamond example:

error: unknown type: 'MeshOutput'
   ┌─ C:\Users\willi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs_tilemap-0.11.0\src\render\shaders/diamond_iso.wgsl:12:58       
   │
12 │ fn get_mesh(v_index: u32, vertex_position: vec3<f32>) -> MeshOutput {
   │                                                          ^^^^^^^^^^ unknown type
   │
   = unknown type: 'MeshOutput'
spring lintel
#

iso_staggered works fine btw

unreal condor
#

this was fixed in the main branch but the fix has not been included in a release yet.

spring lintel
#

I see. Thank you

spring lintel
#

I get this error if I make the x and y of tile_size in iso_diamond too small. (10, 10) is too small for example:

2023-09-18T04:24:35.503840Z ERROR wgpu::backend::direct: Handling wgpu errors as fatal by default    
thread 'Compute Task Pool (0)' panicked at 'wgpu error: Validation Error

Caused by:
    In Device::create_texture
      note: label = `texture_array`
    Dimension Z value 8710 exceeds the limit of 2048

', C:\Users\willi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\wgpu-0.16.3\src\backend\direct.rs:3019:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `bevy_ecs_tilemap::render::prepare_textures`!
thread 'Compute Task Pool (6)' panicked at 'called `Result::unwrap()` on an `Err` value: RecvError', C:\Users\willi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_render-0.11.2\src\pipelined_rendering.rs:143:45
unreal condor
#

TileSize should match the width/height of the tiles in the sprite sheet texture.

That error message is "I'm splitting the sprite sheet into a texture array based on tile size, and holy cow there are just way too many tiles in here."

spring lintel
#

The tiles I'm using are 12x12 pixels and there is roughly 5,000 of them. I suppose I'll use a different tile set

#

I just grabbed a good looking one off of itch.io

#

This one specifically

unreal condor
#

Yeah, that is one of the drawbacks of the current array texture implementation. You might be able to use the atlas feature instead.

bevy_ecs_tilemap is also able to multiply the tile color by another color, so if you have a 1bit tilemap you don't necessarily need color variations in the tileset itself.

spring lintel
#

This is good to know. I don't see an atlas example in the examples provided. Is there a specific one I should look at for this?

unreal condor
#

just enable bevy_ecs_tilemap's atlas feature in your Cargo.toml

spring lintel
#

Would it be a viable solution to break the tileset into multiple files and then load them separately?

unreal condor
#

I think only if you can break them up in such a way that you only need one tileset per tilemap.

spring lintel
#

Right, okay thanks.

hollow ingot
#

Hi, I have a problem, at some zoom level and window size 1 pixel gaps between tiles appear, it's very annoying, I have no idea why that's happening and how to fix that. Here's the video that shows the problem.

hollow ingot
unreal condor
woeful orbit
#

i seem to get this panic/error every so often when loading a new chunk (i think thats the issue?)

2023-09-30T20:07:41.543810Z ERROR bevy_ecs::system::commands: Failed to 'insert or spawn' bundle of type bevy_ecs_tilemap::render::extract::ExtractedTileBundle into the following invalid entities: [1124v2, 10v3, 3625v3, 3912v3, 3909v3, 3907v3, ... LOTS OF MORE ENTITIES IN THIS LIST ... , 3623v3, 3621v3, 3622v3, 32v4, 3618v3, 3619v3, 2383v3, 3616v3, 3615v3, 3614v3, 3613v3, 3612v3, 3611v3, 3610v3, 3609v3, 3558v3, 3557v3, 3556v3, 3555v3, 3554v3, 3553v3, 3552v3, 3551v3, 3550v3, 3549v3, 3548v3, 3547v3, 3546v3, 3545v3, 3544v3, 3543v3, 3542v3, 3541v3, 3540v3, 3539v3, 3538v3, 3537v3, 3536v3, 3535v3, 3534v3]
2023-09-30T20:07:41.544020Z ERROR bevy_ecs::system::commands: Failed to 'insert or spawn' bundle of type bevy_ecs_tilemap::render::extract::ExtractedTilemapBundle into the following invalid entities: [3684v3, 3723v3]
2023-09-30T20:07:41.544028Z ERROR bevy_ecs::system::commands: Failed to 'insert or spawn' bundle of type bevy_ecs_tilemap::render::extract::ExtractedTilemapTextureBundle into the following invalid entities: [3684v3, 3723v3]
thread 'Compute Task Pool (2)' panicked at 'called `Result::unwrap()` on an `Err` value: NoSuchEntity(3684v3)', /Users/ramin/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs_tilemap-0.10.0/src/render/prepare.rs:87:55```
woeful orbit
#

Did some digging and it seems this error happens when:
/// Returns `Ok` if all entities were successfully inserted into or spawned. Otherwise it returns an `Err` /// with a list of entities that could not be spawned or inserted into. A "spawn or insert" operation can /// only fail if an [`Entity`] is passed in with an "invalid generation" that conflicts with an existing [`Entity`]

shell crater
#

I have the same issue @woeful orbit . I'm strugging to debug it.

For me it appears when I delete/re-add the tiles. The very first time launching the game, but after a gameover (arcade style), I have those error messages and I encounter some glitches (part of the tiles are missing or in the wrong place)

unreal condor
unreal condor
shell crater
#

It didn't work, but I might just had an idea about what does not work. I do the despawning with an OnExit scheduling, it might not be finished when the OnEnter of the next state starts spawning the tiles again.

unreal condor
#

That seems plausible

shell crater
#

I just tried, it works! 😄

#

I have added a buffer time of 0.1s (a bit overkill) and now there is not error nor glitch anymore

#

there is probably a more elegant solution I guess, but that will do for now

undone yoke
#

Hi all, I have a square TilemapBundle for my map. Some of the tiles have a component of Wall which I want to see if they collide with my player (which has a transform). Why TileBundle doesn't contain a transform component? I can only query TilePos but it's unclear to me how to get the actual transform of the tile

idle mauve
#

Hey, I have been checking out the bevy ecs tilemap, and I wanted to know if there is possibility for supporting custom "TilemapTypes". My use case is to take an existing TilemapType and feed in a matrix and it's inverse as a pre-processing step for calculating world positions for Hexagon grids. I want to get a grid that looks like this to work.

@unreal condor
Actually, it seems to me all that would need to be done would be to use the hexagon grid as is and add some matrix for the shader into the Vertex Input. If this is done correctly, you can skew tiles however you want, which in my case, I want a rotation and slight skew over the hexagonal tiles.

idle mauve
#

@unreal condor

Hello, is there currently functionality for effecting draw order for tiles when chunking. In this case, the bottom right tile is drawn first and the top left tile is drawn, the draw orders should be reverse so that I can overlay. Is this possible without a custom shader, and if it possible with a custom shader, can you provide some advice?

unreal condor
idle mauve
#

Oh okay, y_sort seems to be for sorting chunks. I could chunk as 1x1, but that basically turns off any real GPU advantages. I figure that it probably has to be done, at shader. @brisk path, if you are seeing this, any advice?

brisk path
idle mauve
#

ok, yeah, using y_sort plus chunking with 1x1 worked, just got to adjust the tiling.

brisk path
#

For a little better performance

idle mauve
#

I can get close to the effect I want, but I still need some sort of Mat2 skew to line things up perfectly.

#

Because the Ordering is wrong both on the X and Y axis, chunking fails for (map width, 1), only (1,1) achieves the effect.

It also needs a custom Axial skew to align everything, I believe.

#

@brisk path, could a Setting be added for Custom Hexagon Mat2's to deal with Skewed Hexagons? Finding the correct numbers for the Mat2 for the rotation and skew will be a little hard for me right now, but you can kind of see that by moving the tiles a bit, it produces a better grid. Directly controlling the Axis from a Mat2 would let me adjust perfectly for my weird tileset I am inventing.

idle mauve
#

Okay, so it should be possible to fix by using a custom shader instead of a custom axis, all I need to do is provide a Material that can hold a Mat2D and I should be able to adjust that Material and get perfect line up. It just means that all the helper functions tied to the type don't work. It is quite weird that only the Shader controls the positioning, but I guess it make sense as a point of GPU optimization.

idle mauve
#

Btw if StarToaster happens to read this eventually, I would appreciate a more in-depth description of the Depth Buffering Issue and whether it is set to be resolved.

brisk path
brisk path
#

doesn't play super nice with transparency but

#

its fast

#

I've rendered 40m+ iso tiles that way.

idle mauve
brisk path
idle mauve
#

To be clear, I do not understand. Does the pipeline not allow for specialization to have a depth buffer or something?

brisk path
#

Bevy's 2d cameras don't have a depth attachment in the render pass

#

And bevy sprite isn't setup to write or read depth

#

This is a fixable problem in bevy

idle mauve
#

When I get time, probably will need to experiment then.

brisk path
# idle mauve When I get time, probably will need to experiment then.

I think a good starting point would be to add the ability to pass in settings to the bevy 2d plugin. From there you could specify if you want a depth buffer for 2D and then the rest is. Just making sure that the death buffer gets created and the relevant pieces of code respect the fact that there is a depth buffer.

#

Bevy ECS tile map will have to be updated to make sure it properly writes to the death buffer in the vertex shader.

#

One thing I do want to point out is that I don't think the way that bevy ECS tile map renders tiles is necessarily what we would want for a 3D isometric or 3D hexagon tile map renderer. You can get much better performance by doing vertex pulling instead of chunking.

idle mauve
#

Hmm… to me this kind of just reads as some level of extension to the bevy_ecs_tile map to use an alternative renderer that is developed for 2.5D tiles wherein faking depth is necessary.

Basically edit shaders and pipeline descriptors to improve performance and control for overlaid Isometric and hexagonal tiles.

I might try developing my use case first, but I might split it out into a Cargo Crate to provide some extra functionality for anyone else interested in mainly Isometric map/hexagonal rendering.

brisk path
#

Bevy sprites need depth too though

bronze flower
#

How would you get rapier to work with this plugin, since the tiles are positioned with TilePos internally rather than using a Transform. Do people roll their own collision/physics systems?

mint reef
#

maintainers, just FYI

#

the bugfix for tilemaps with Entity generation > 0 not rendering was never made into a patch release

#

i just wasted my whole afternoon debugging my game

#

to figure out why my tilemaps were not rendering

#

i am feeling so demoralized and angry right now

#

i traced it down to the entity generation

#

only to discover it was a known bug that was fixed on main

#

but never released

#

please dont do this

#

if you fix bugs, make patch releases

#

a bug like "tilemap mysteriously does not render sometimes, even though the setup code is literally exactly the same as the basic example in the repo, just in a more complex app" is pretty critical

unreal condor
#

I am sorry about that and I can sympathize. You've characterized that bug very well and it's nasty. There are a great deal of outstanding PRs, issues, and a release overdue. But I don't know if making strong demands of a maintainer who is already time-constrained is helping.

My "bevy time" lately has been spent largely trying to make sure my own projects don't get broken by Bevy 0.12. There are huge areas of the bevy_ecs_tilemap that I just frankly don't care about so there's not a huge amount of motivation to spend time reviewing PRs or trying to reproduce issues. But I have been trying to help out here and there with that anyhow, including that bug fix.

I have also been doing my best to guide folks to the main branch when it sounds like they are experiencing that bug here.

I am not able to help out with publishing releases. edit: (nor do I particularly want to have that responsibility)

mint reef
#

ok i am sorry for the abrasive tone

#

i understand FOSS maintainership is hard and we cant have expectations and demands

#

but sounds like this bug has wasted other ppl's time too, not just mine

#

and it would be nice if, whoever merged that PR, had made a release back when it was done

#

just a lesson to be learned i guess

unreal condor
#

Thanks. I totally get where you're coming from and personally agree with everything except the tone 🙂

brisk path
#

@mint reef I'm sorry about this. This def rests on my shoulders for blame. I simply haven't had the time to vet and roll up another release. If anyone does want release permissions and is active enough in the bevy community I will consider giving them access. I will try to roll out a release tomorrow, but my time is very limited right now.

mint reef
#

ive worked around it already in my project, now that i know what the issue is. i dont want to rush you. but it would suck if more ppl run into this and end up being frustrated and wasting their time because of it.

mint reef
#

okay, so i am noticing another bug. is this also a known issue? TileColor does not seem to behave like Bevy's sprite color does. it results in "washed out" looking colors, which my guess would be might have something to do with gamma correction?

#

rendered with bevy sprites

#

rendered with tilemap

brisk path
mint reef
#

yeah they look incorrect, lighter than expected

brisk path
#

Probably an srgb thing

mint reef
#

i am using LCHA color values, but i dont think that is at fault, because im pretty sure everything gets converted to RGB internally by the time it is used for rendering

brisk path
mint reef
#

🤔 oh wow bevy's sprites have gotten hella optimized

#

perf with bevy_ecs_tilemap seems ... surprisingly ... worse actually

#

i just did a quick comparison with a bigger map (hexagon with radius 96, that's roughly 18k-19k tiles) on my M1 Pro, and macos activity monitor reports somewhat less CPU usage with tilemap, but with sprites i get around 25-30% GPU usage, while tilemap is 45-50% GPU usage

#

im looking at cpu and gpu usage with vsync on to lock the frame rate

mint reef
#

im going to keep both in my game because im very curious how the two will compare going forward

brisk path
#

This crate should be faster, something changed and we dropped performance a bunch. I need to look into it

mint reef
#

if you ever want to test using my game, lmk 🙂 i'll happily tell you how to get it running using the open-source version of my game from the public repo

#

having both tilemap and sprites in the game for side by side comparison is kinda fun

#

i might create a better and more reproducible test later

mint reef
#

ok im now at feature parity between the two backends, and just tried running with vsync off to measure fps

#

yes tilemap is faster by about 2x when camera is zoomed out and most of the map is on-screen. 🙂 when zoomed in, they perform similarly (which ig is good news, it means frustum culling is effective in both cases)

#

🙂

#

interesting why when i enable vsync, tilemap shows higher GPU util % than sprites

#

tilemap renderer good 🙂

#

thank you for your amazing work

#

if i find some time i might try to go and fix it

brisk path
#

@mint reef I released a 0.11.1 version. Just contains everything in main after I validated the release by testing.

#

Hopefully I can find time to get another fix release out

undone umbra
#

Hello, I was trying to follow along with the basic tilemap example but I can't get anything to show to the screen. I'm getting ar error that the "render" feature is disabled and I don't know if that's what's causing the issue. My code is exactly the same as the "basic.rs" example but I'm getting this one error and don't know how to resolve it. Here's some screenshots of my dependencies in my Cargo.toml and the error I'm getting in my code (Sorry if this is an odd question, I'm still new to rust!)

undone umbra
#

Nevermind! A bit of debugging and throwing random things at the wall worked! Looks like I accidentally commented out the line where I add the TilemapPlugin 😅

forest fox
#

Hi, how can I set the order of tiles individually in bevy_ecs_tilemap? My tiles are overlapping with each other.

forest fox
#

Ok I found another coord system Staggered seems to be the solution. But its order is inverted from what I expected. How can I invert that back?

maiden walrus
#

so working with tilemap and followed the hexagon_row example practically just copy pasted but i get ```
thread '<unnamed>' panicked at 'index out of bounds: the len is 25600 but the index is 25600', <path>\bevy_ecs_tilemap-0.11.1\src\tiles\storage.rs:51:9

#

I am curious whwere I could have gone wrong

#

I also removed the camera controls for now since I don't care about that atm

maiden walrus
#

turns out had an extra *2 somewhere

maiden walrus
#

So I am trying to use fill_tilemap_rect_color but it only works if I also supply a texture in the TilemapBundle. if I don't it just comes out grey. if I do it like layers the colors.

forest fox
#

Hi, I'm now learning rendering with bevy_ecs_tilemap. What does the binding group inside TilemapViewBindGroup stands for? Seems like that is is a combination of binding groups of view and global_buffer. I can't understand it.

unreal condor
#

Anyone else working on a 0.12 migration? I got things compiling (but silently not rendering). Getting to the point in the exercise where I realize I should have tried to see if anyone else had already done this work :).

unreal condor
surreal bear
#

Anyone using this with Tiled ? I'm trying to extend it for Object layers (whereby objects are a tile from a tileset texture and / or a collider). I've already extended it to support colliders on their own, but I want to also load objects with a texture. It's proving to be really awkward just by how assets are getting loaded and organized via tiled, ecs_tilemap, and the Tiled helper.

opal spoke
#

yeah for objects I have a module that maps custom properties to arbitary logic (usually adding components)

surreal bear
#

That's not quite what I mean.

opal spoke
#

For textures in particular I just set a custom property to a path, which I map to a texture

maiden walrus
#

I am having issues with dertimining HexNeighbors and what actually translate to which direction?

maiden walrus
#

figured it out.

silk saddle
#

i have a 16*16 tiles but I want then to appear bigger in my game. like 2x or something. How can I scale them? Using Transform.scale or there are other approaches?

surreal bear
#

Help would be appreciated (It's relevant to ecs_tilemap for the Tiled helper) : #1169994150310064292 message

surreal bear
#

Also, why does nothing show up in the docs for atlas ? Does the atlas feature not actually use TextureAtlas from Bevy ? Very confused... I am essentially just doubling up my assets just so I can use the tilset for object sprites...

unreal condor
#

atlas just exists for better compatibility with webgl2. It's about internal stuff and isn't required for loading texture atlases. Just determines whether or not that atlas will be converted to an array texture.

#

But either way, it does not use TextureAtlas from bevy.

surreal bear
#

I see

#

Well I'm trying to just load sprites from my tileset for objects in Tiled

#

and actually having a loaded, usable texture atlas to do that is quite a pain

#

I'm just building off of what is already in the tiled_helper

#
pub struct TiledMap {
    pub map: tiled::Map,

    pub tilemap_textures: HashMap<usize, TilemapTexture>,
    pub atlases: HashMap<usize, Handle<TextureAtlas>>, // Added a hashmap for getting sprite for objects.

    // The offset into the tileset_images for each tile id within each tileset.
    #[cfg(not(feature = "atlas"))]
    pub tile_image_offsets: HashMap<(usize, tiled::TileId), u32>,
}

    fn load<'a>() {
...
                    }
                    Some(img) => {
                        let tile_path = tmx_dir.join(&img.source);
                        let asset_path = AssetPath::new(tile_path, None);
                        let texture: Handle<Image> = load_context.get_handle(asset_path.clone());
                        dependencies.push(asset_path.clone());

// My code starts here
                        let texture_atlas = TextureAtlas::from_grid(
                                texture.clone(),
                                Vec2::new(tile_size.x, tile_size.y),
                                tileset.columns as usize,
                                ((tileset.image.as_ref().unwrap().height as u32 + tileset.spacing
                                - tileset.margin)
                                / (tileset.tile_width + tileset.spacing))
                                as usize,
                                Some(Vec2::new(tile_spacing.x, tile_spacing.y)),
                                Some(Vec2::new(tileset.offset_x as f32, tileset.offset_y as f32)),
                            );

                        let loaded_atlas = LoadedAsset::new(texture_atlas).with_dependency(asset_path.clone());
                        load_context.set_labeled_asset(&format!("{}_Atlas", tileset_index), loaded_atlas); // I can't do this because cannot borrow immutable `*load_context` as mutable.

// My code ends here
                        TilemapTexture::Single(texture.clone())
 ...
#

And in process_loaded_maps :

...
objects_layer.objects().for_each(|obj| {
                                    let mut obj_ent = commands.spawn_empty();
                                    
                                    if let Some(tile) = obj.get_tile() {
                                        if tileset.as_ref() == tile.get_tileset() {
                                            println!("sometle{}", tile.id());
                                            obj_ent.insert(SpriteSheetBundle {
                                                sprite: TextureAtlasSprite::new(tile.id() as usize),
                                                texture_atlas: atlas_handle.clone_weak(),
                                                ..Default::default()
                                            });
                                        }
                                    }
...
surreal bear
#

So I dediced to move it into load (i wanted to do this initially, but it was too confusing for me.. but now it's necessary)

unreal condor
#

Hm, seems like something like that could work. Might need to collect atlas handles and add them to the context outside of that loop? I'm no wiz with writing asset loaders though.

surreal bear
#

Well i've only been Rustling for like 2 months so i have no idea

full sequoia
#

Is it possible to have larger tiles inside a tilemap? for a example a tree or a house would need to be larger than a regular tile.

silk saddle
#

is it true that TilePos { x: 0, y: 0 } is a bottom left corner tile?

#

or am I doing something wrong here

maiden walrus
#

it is

#

and there can't be negative coords (they are u32's)

silk saddle
#

hm.... I thought that 0.0 is at top left 8(

surreal bear
full sequoia
#

When is this updating to bevy 0.12.0?

unreal condor
north shadow
#

Hi! I am creating a tilemap in a similar way to the example on Github.
I want to make an update function in order to update the tilemap if any of the texture indices in a vector has changed. How should I go about doing that?

north shadow
#

To be more specific, how can I access the tiles' texture indices and if I change it, how can I make the change apply on screen (if it isn't applied automatically). I did check this example on Github https://github.com/StarArawn/bevy_ecs_tilemap/blob/main/examples/accessing_tiles.rs but it has got some custom stuff and is specific for the task it is doing so it isn't very clear what should be done in the general case.

north shadow
#

I think I got up to a certain point but I am not sure how get the TileBundle component from the tile Entity

pub fn update(tile_storage_query: Query<&TileStorage>) {
    for tile_storage in tile_storage_query.iter(){
        for tile in tile_storage.iter(){
            let x = //get TileBundle from tile &Option<Entity> and get its index
            println!("{}", x);
        }}}
unreal condor
#

TileBundle isn't a component, but you can use a normal Query after you have an Entity to retrieve a component. See bevy docs for Query::get.

north shadow
#

But if it's not a component, how can I access the TileTextureIndex from the tile entities?

unreal condor
#

a Bundle is a convenient collection of components just for spawning them. You can't query for entire bundles, but you can query for individual components, or tuples of individual components.

You can see this in action in accessing_tiles.rs

mut tile_query: Query<&mut TileTextureIndex>,
// ...
if let Ok(mut tile_texture) = tile_query.get_mut(*neighbor_entity) {
    tile_texture.0 = color as u32;
}
north shadow
#

I just found that part at the example on my own and implemented it and it works now. Thank you!

frigid coral
#

how should I rotate individual tiles without using multiple textures? I specifically need to rotate by 90° increments when building a map with tiles facing a certain direction

maiden walrus
#

could change the tiles indivual transfrom.rotation

frigid coral
#

the tiles don't have transforms though, only a position and a flip

maiden walrus
#

they will have a transfrom to be positioned

unreal condor
full sequoia
#

Is it possible to have tiles with sprites larger than the tile size?

unreal condor
#

@brisk path I think that PR's ready for you. There's one other important bug fix PR (481) that would be great to release as well.

Let me know if I can do anything else to help out.

silk saddle
#

any news on that?

restive geode
#

Could someone tell me if I'm getting the profiling chart right?
Looks like the biggest performance hog is bevy_ecs_tilemap::render::extract::extract
I am indeed playing with quite a large tile grid of 2048 x 2048.
Is there some obvious optimisation I am missing?

hollow spindle
#

what was the trick for getting rid of tile seams?

#

(i vaguely recall there being one but not what it was)

brisk path
hollow spindle
#

ty<3

unreal condor
#

Was that meant to be in the kayak thread?

brisk path
#

Yes

#

😓

unreal condor
#

😅

clear crow
#

hey, how do I load entities with sprites above tiles and allow them to walk to other tiles?

unreal condor
#

generally, spawn an entity with a z value > the tilemap's. you can use TilePos::center_in_world to get world coords from a tile position. you may need to offset that by the tilemap's position.

whatever pathfinding you do can use TileStorage to get the tile entity (so you can query its data) by position.

clear crow
#

spawn an entity as a tile as well? where is this z value? TilePos only has x and y

brisk path
clear crow
#

ok, I did that, but to make it walk I need to link sprites and tiles somehow and keep track of their position relative to one another

brisk path
#

If you want to use the tile map you need to use Layers

brisk path
#

Tile storage can give you neighbor information

clear crow
#

so, an entity with sprite and position, that when walking, queries the tilestorage, and filter the curernt tile and it's neighbors by the entity position?

brisk path
#

I would recommend looking at the examples on how to access tiles via queries.

clear crow
#

nice, ty

#

it is easier than I thought

#

one last thing, how do I make an entity with sprite snap within a tile? so it doesn't look like 2 separate things, or risk overflowing the grid

brisk path
#

Sprites are center positioned

clear crow
#

hmm nice

woeful delta
#

There appears to be an issue w.r.t the Tiled helper. Someone ran into it previously https://github.com/StarArawn/bevy_ecs_tilemap/issues/484. Since I encountered it yesterday, I added a minimal example. Seems simple to fix; I added a small fix in my example, but idk if it is optimal code-wise.

clear crow
#

how would one do to make a tiled movement than happens in +50 but instead of snapping from one position to another, it makes an flowing progress that depends on the player speed?

brisk path
#

I have no desire to maintain tiled editor support.

#

and strongly think it should live in a separate repo

brisk path
#

first thought that comes to mind

clear crow
#

I managed the snappy movement:

if input.just_pressed(KeyCode::W) {
  transform.translation.y += 50.0;
}

I just want a flowing "effect"

brisk path
#

Is to have the known end position and lerp between it and the current position

clear crow
#

lerp?

brisk path
#

interpolate

clear crow
#

what should I search for?

brisk path
#

bevy has interpolation for vectors already built in

#

I can't remember if its called lerp or smooth or something else.

#

Looks like its called lerp

clear crow
#

found nothing about lerp in bevy, google, unoficial wiki, youtube

woeful delta
woeful delta
unreal condor
brisk path
brisk path
woeful delta
#

For some reason, I just like tiled better, since its so minimal.

woeful delta
brisk path
woeful delta
#

Yes, it is quite a feat with all the chunked rendering pieces. I definitely support this technology to be in a separate repo.

clear crow
#

how do I spawn a sprite above the tilemap? mine is below it independent of the order I spawn them

unreal condor
#

make the z position larger than the tilemap's z position.

clear crow
#

where is this z position set?

#

o, chagpt helped me, ty for the direction

clear crow
#

I'm kinda lost trying to despawn a creature. I must have done something wrong in the way I structured things, but I don't know what it is

#
#[derive(Bundle)]
pub struct CreatureBundle {
    pub name: Name,
    pub health_points: HealthPoints,
    pub speed: Speed,
    pub position: Position,
    pub sprite: SpriteBundle,
}

I want to despawn a creature whenever it's health_points get to 0, but...
to spawn it with a sprite, I need to make the struct a bundle, but queries doesn't work on bundles... how do I query it to despawn if I can only get the &HealthPoints?

unreal condor
#

Do despawn something you need its Entity, which is an identifier. You can query for this the same way you query for other stuff. (But use Entity, not &Entity).

clear crow
#

o, soh it was the &...

#

ty

paper turret
#

https://github.com/StarArawn/bevy_ecs_tilemap/pull/376 I found this open PR and I was wondering if there was a compelling reason for it to not be implemented. Is anyone able to share some expertise with me about it?

I am trying to transition some hand-written tilemap code to bevy_ecs_tilemap. The way my implementation currently works is:

  • I want to render a 144x144 unit tilemap. Each tile has a texture. My sprite assets are 128x128px.
  • I load my 128px asset, render the sprite, and use custom_size: Vec2::splat(1.0). This results in me having a grid which is 144px. Then, I adjust my camera's projection.scale and zoom in on my grid until it minimally covers the viewport.
  • This approach has the benefit of being able to talk about my grid in 1-unit sizes throughout my code. Numbers feel less magical.

I attempted to recreate this approach using bevy_ecs_tilemap yesterday, but struggled. By default, the plugin expects to render with the same dimensions read from the spritesheet. The plugin does not respond well to adjusting the tilemap scale.

I can make this work without modifying the plugin by changing math in my code. My code would need to understand that grid tiles are 128px, not 1px. This isn't especially complicated, but doing math with 1's is always nicer.

I can also make this work by modifying the plugin, applying the above PR, and preserve my current approach.

I'm not experienced enough in this area to know if I should favor one approach over the other. Is there a "standard" mindset I should have here? Or are both ways equally valid and the plugin just lacks flexibility in this regard?

GitHub

As bevy_ecs_tilemap stands now, each tile's size in-world is tied to the pixel-size of the tile in the source atlas.
If I however want my tiles to be of unit size or any particular scale that I...

unreal condor
#

No compelling reason afaik, just stalled due to bikeshedding.

paper turret
#

Okay. I reviewed the PR yesterday and found it surprisingly simple. I am going to fork the pending 0.12 PR's branch, apply the solution discussed in the PR with the non-physical naming, and when 0.12 is merged I'll offer it up as a new PR.

#

Thank you

paper turret
#

Semi-related question

#

Prior to adopting bevy_ecs_tilemap, I was making use of a texture atlas w/ padded offsets to eliminate f32 bleed when adjusting my camera's projection scale

#

It seems that this plugin used to support texture atlases, but doesn't anymore, and StarArawn has a large writeup on a GitHub issue describing the benefits of moving to array textures

paper turret
# brisk path Atlases are supported

Okay, thanks. I'll look around for an example, I must've missed it. I have the feature enabled and I'm targeting WASM, so I guess array textures aren't applicable to me, but it looked like TilemapBundle was expecting texture: Handle<Image>

brisk path
#

we have support for atlas images, but not for atlases using bevy's atlas code.

#

Its certainly something we can add

#

Behind the scenes bevy_ecs_tilemap takes an atlased image and splits it up into individual textures, it uploads them as an array texture. This allows us to avoid as many bleeding artifacts as possible.

#

The most "ideal" way to load textures is to split them individual into KTX2 files with mipmaps. This ensures optimum quality and reduces texture memory, but its currently not a very user friend process.

paper turret
#

Not too big of a deal I don't think. I was trying to emulate this behavior:


fn create_texture_atlas(texture_handle: Handle<Image>) -> TextureAtlas {
    TextureAtlas::from_grid(
        texture_handle,
        Vec2::splat(120.0),
        3,
        16,
        Some(Vec2::splat(8.0)),
        Some(Vec2::splat(4.0)),
    )
}

and I attempted to do so by setting TilemapTileSize to 120 and TilemapSpacing to 8.0 but it continues to bleed where this solution doesn't bleed using Bevy's texture atlas.

I think I'm just going to extrude the colors around my sprites to fix the bleed issue at the asset level. I'm not confident there's anything I can do directly with the plugin at this point in time.

brisk path
#

Can you show an example of the bleed?

#

bleed can happen for quite a few different reasons

#

if you aren't using the "atlas" feature there should be mininmal bleed.

paper turret
#

and if I zoom in:

#

Building for WASM so atlas required

brisk path
#

that looks like alias bleed 🙂

#

turn off msaa

paper turret
#

Okay. I'll try that. Sorry if I'm making noob mistakes, first game and all that. Half the time fixes for issues I experience use terminology I've never heard of

brisk path
#

if you target webGPU you should be able to use everything like on desktop

paper turret
#

Awesome, thanks for the heads up and the quick responses.

brisk path
#

Also, for everyone, I know bevy_ecs_tilemap has been on the back burnner in terms of merging PR's and getting a bevy 12 release out, but as soon as I fix up Kayak my plan is to swap over my attention to bevy_ecs_tilemap. I think this will happen soonish.

paper turret
paper turret
brisk path
brisk path
#

Hello! Kayak UI port to 0.12 is complete. This means my focus is now moving towards bevy_ecs_tilemap to bevy 0.12. I've merged several PR's today as well as fixed a few small issues with the existing bevy 12 PR which is now also merged in.

Thank you to everyone who has been contributing and sorry for my absence as of late. I've also narrowed down some performance issues I was seeing in bevy_ecs_tilemap when you have milions of tiles. You can read a bit more about it here: #ecs-dev message
I'm hoping I can figure out specifically what we are triggering in the propagate_transform bevy system and avoid doing that to increase performance. If we solve that issue we should gain 11ms of performance which will be a massive improvement.

unreal condor
#

I thought propagate_transform wasn't using change detection and just has to do its thing every frame. Maybe I'm thinking of visibility propagation? It has been a while, but I looked at this exact thing once.

silk saddle
#

is it true that if I want to render few tilemap layers then I just need few TilemapBundle in same position but with different z-index?

brisk path
#

Its usually helpful to have a resource to keep track of the layers

#

and have some sort of constants as well like:

pub GROUND_LAYER: u32 = 0;
pub TREE_LAYER: u32 = 1;
..
#

In the future it is possible that we'll provide a higher level API around this, but its typically very different depending on the use case.

silk saddle
#

well, I have something like this for map layers:

pub struct GameMap {
  pub layers: HashMap<MapLayerType, Flat2D<bool>>,
}

it contain just boolean value of whether some kind of terrain should be there or not. now I have to create multiple TilemapBundles and put correct tile indexes there

brisk path
#

Hmm its probably easier/better to store the entity to the tilemap

silk saddle
paper turret
#

I kind of assume it's not acceptable to truncate to u32 but then IDK what to do about the Hash

solid cloud
#

If I have a layer with a bunch of objects (say stones or trees) and I want to do y-sorting with my player sprite, how do I proceed? Does the entire layer share a z-index from the TileMapBundle?

#

(I mean, I know how to proceed in general, with a YSort component, and measuring from the top, but I'm having a hard time figuring that out for tilemaps)

#

Or should I construct my layer by making separate horizontal rows?

dreamy mantle
#

Hi, I was trying to use bevy_mod picking with bevy_ecs_tilemap but it doesn't detect the entities. Any idea how to fix it?

native granite
#

Quick question regarding animations: instead of having tiles that are animated within a single tileset I have the entire tileset animated, e.g. water as attached and I have 12 variants (for each frame) as a separate tileset each. That means I'd preferrably like to cycle through entire tilesets every few frames. I have seen something about texture vectors but it looked more like separating a single tile into multiple files. Also they are mutually exclusive with an atlas if I'm not mistaken. I was now wondering if it's possible to swap the tileset while still keep the same tile atlas indices or whether I should just merge all frames into a single texture.

unreal condor
#

You can swap the tilemap texture. This actually happens in the basic example. I'm not sure if there are any performance considerations.

native granite
#

Oh yeah I didn't think of checking the "basic" example kekw Thanks for letting me know.
Curious to see whether StarToaster can share details about perf considerations.

unreal condor
#

I think it should be fast. Though when using a texture atlas (but without the atlas feature), the first time a texture is used, there's some extra work done to create an array texture for it. That work is cached though, so I don't think there should be any penalty to doing this at all after the first time it is used.

unreal condor
solar zephyr
#

Hello, I have a problem loading a tiled map. So I put the file in my assets

#[derive(AssetCollection, Resource)]
pub struct MapAssets {
    #[asset(path = "maps/test_map.tmx")]
    pub tiled_map: Handle<tiled::TiledMap>,
}

and load it via this code:

fn load_tiled(mut commands: Commands, maps: Res<MapAssets>){
    let tiledmap: Handle<tiled::TiledMap> = maps.tiled_map.clone();

    commands.spawn(tiled::TiledMapBundle {
        tiled_map: tiledmap,
        ..Default::default()
    });
}

This is the output from bevy:

2024-01-30T10:58:17.923416Z  INFO test::maps::tiled: Loading tile image from maps/assets/castle_window.png as image (2, 3)
2024-01-30T10:58:17.923428Z  INFO test::maps::tiled: Loading tile image from maps/assets/castle_turret.png as image (2, 2)
2024-01-30T10:58:17.923435Z  INFO test::maps::tiled: Loading tile image from maps/assets/castle_door.png as image (2, 1)
2024-01-30T10:58:17.923439Z  INFO test::maps::tiled: Loaded map: maps/test_map.tmx
2024-01-30T10:58:17.951571Z  INFO test::maps::tiled: Map added!

Additionally, I've copied this file to my project:
https://github.com/StarArawn/bevy_ecs_tilemap/blob/main/examples/helpers/tiled.rs

But I only get my player image, and no tilemap. So how would i proceed here?

GitHub

A tilemap rendering crate for bevy which is more ECS friendly. - StarArawn/bevy_ecs_tilemap

unreal condor
maiden walrus
#

did a pr for 0.12 ever release?

unreal condor
#

no, there hasn't been a crates.io release for 0.12

solar zephyr
#

So, im still kind of confused, but I'm using a tileset and now multiple images, I would need the atlas feature wouldnt i?

solar zephyr
#

Ok so ive changed the tiled helper file and removed all cfg lines containing atlas and some paths, but it still won't load my map

unreal condor
#

@brisk path with 0.13 on the horizon, can I ask what your plans are for bevy_ecs_tilemap in the next few weeks?

I'm still not interested in dedicating a bunch of time to the project, but I wouldn't mind testing / merging small fixes and doing a release for 0.12 and/or 0.13.

Or if there's some tedious piece of work that would help out, e.g. stripping tiled/ldtk stuff from the repo, updating a bunch of examples as a part of some planned overhaul or whatever, let me know.

brisk path
unreal condor
#

Just feel free to DM or ping on GH or whatever if there's some way I can help out.

brisk path
unreal condor
#

Yeah, should no problem to fix it up.

boreal narwhal
brisk path
unreal condor
#

The changes are very manageable this cycle. Will update that again closer to release.

how naive I am, lol. rendering crew coming in hot with late breaking changes and a super vague migration guide.

Updated the draft RP to latest bevy though.

brisk path
unreal condor
#

lots of things have been going through a deprecation cycle lately which is a nice trend, but rendering still seems pretty wild-west.

#

Things need to break, but not nearly enough effort being given to helping users unbreak their code, IMO.

#

I still have 3 open issues about inadequate rendering migration guides open for bevy 0.12.

brisk path
#

12 was such a pain

unreal condor
#

Yeah, 12 almost broke me.

brisk path
#

if I had time I would try to keep up on changes more and review rendering PR's, but I just don't have time 😦

brisk path
#

Thank you

unreal condor
unreal condor
#

Neat, no merge conflicts with the 0.13 draft.

unreal condor
#

Updated the 0.13 PR to use the release and took it out of draft mode. I don't think anything else broke since I last checked in.

brisk path
unreal condor
#

Awesome, much appreciated. I'm free tonight so feel free to ping.

paper turret
#

After updating to Bevy 0.13, and pointing at main for bevy_ecs_tilemap, I seem to have a race condition where sometimes my tiles aren't visible. Has anyone else experienced this?

#

It's not clear to me (yet) if it's a z-index issue or if it has to do with the TextureAtlas changes, but I am assuming the latter.

brisk path
#

There might be some bugs with the 0.13 update it's not fully tested yet

paper turret
#

Yep, that's fine, happy to help do some of that testing

#

I'll look through the changes more carefully

brisk path
#

Yeah that would be great it would help if someone ran through all of the examples the visibility example comes to mind.

paper turret
#

https://github.com/StarArawn/bevy_ecs_tilemap/issues/522 did a first pass on auditing them but need to check in a WASM context to see if some of the issues I experienced are due to my Docker environment (or I guess check out older branch and see if they reproduce) (ok confirmed it's just my side, examples all seem fine according to multiple people)

GitHub

Hello! I'm auditing all of the examples on main. At least one doesn't appear to be working in my environment, but I'm running inside of a Docker container and forwarding the display out...

#

I didn't encounter a race condition ever when testing all the examples though, so it's possible the issue is on my end, maybe with z-index or something, idk

paper turret
#

okay well I tried to create a MRE and I can't repro this intermittent lack of visiblity, so now I am becoming very confident it's on my side but no idea where, don't think this concern should block a release though

paper turret
#

Just to provide an update on this. I've been going through my codebase commenting out large swaths of systems in an attempt to track down the issue. I think I have tracked it down to something I wouldn't expect - my UI layer. This is like.. egui windows etc. If I stop rendering them then I never seem to be able to reproduce the issue, but I have absolutely no idea why. They seem like entirely distinct concepts.

I am now very sure that calling add_plugins(EguiPlugin) introduces the issue. I suspect it has to do with the calls to apply_deferred it runs in PreStartup or PreUpdate but am working on confirming

brisk path
#

There were changes to the UI camera stuff in Bevy 12 iirc

paper turret
#

Yeah, I don't think egui cares about that though. I'm still working on trimming code down. I feel like my two repos are identical but still not seeing it reproduce in the one I built from scratch. Hopefully close to understanding the issue though

paper turret
#

Okay so if Bevy's multithreaded feature is disabled (either implicitly by running in a WASM context or explicitly for native builds) then I am able to somewhat consistently reproduce the issue with a MRE

brisk path
#

Can you see if render doc shows the draw calls?

brisk path
paper turret
#

I'm going to keep digging too, just wanted to keep you updated

paper turret
brisk path
paper turret
#

Here is what I see

#

When it works:

#

When it doesn't:

#

Not sure if I'm looking at the right data though, just playing around w/ the tool now

#

I'm guessing since there isn't a 2nd color pass that it isn't getting drawn at all?

paper turret
#

I was able to eliminate egui from the MRE. It's starting to look like it's a bug in Bevy not in bevy-ecs-tilemap

paper turret
unreal condor
#

So wacky...

#

I do think that at some point various apply_deferreds were removed, so stuff not working without auto apply enabled in the render app makes sense to me.

#

I was going to suggest diffing trace-level log output between good/bad runs, but I don't think we have any logging when commands are applied?

#

So RenderSet::Queue itself is ordered / chained with these other sets.

ManageViews
Queue
PhaseSort
#

So if RenderSet::Queue didn't previously have a command flush, I guess sticking a system with Commands in there might introduce one? (If phasesort/manageviews or maybe any of the other sets have a system with Commands?)

#

Why that would break bevy_ecs_tilemap is a bit of a mystery.

paper turret
#

okay

#

Well thanks for sharing that, I didn't realize there was a chained ordering to the sets but of course there is that only makes sense

#

You're right that sticking a system into the set won't cause an automatic command flush between the two systems in the set (since not ordered) but will cause it to occur after the set itself to respect intra-set ordering

#

So this is working as intended from the perspective of Bevy

#

I wonder if that's relevant here even though it's the Render schedule? No idea.

paper turret
#

We don't really add that many systems to the Render schedule. There's:

  • prepare_textures in PrepareAssets

  • prepare_removal and prepare in PrepareAssets

  • queue_transform_bind_group in PrepareBindGroups

  • prepare_materials_tilemap in PrepareAssets

  • queue_material_tilemap_meshes in Queue

  • bind_material_tilemap_meshes in PrepareBindGroups

and that's it.

The ordering of these is a little weird. I think this is where the non-determinism comes into play.

PrepareAssets is not part of the Prepare set. It is chained such that it must run after ExtractCommands and before Prepare. That's the only limitation imposed upon it.
PrepareBindGroups is part of the Prepare set. The Prepare set is chained such that it comes after ExtractCommands and after Queue.
Queue is chained such that it comes after ExtractCommands and before Prepare.

This means that the ordering of PrepareBindGroups and Queue is fixed. PrepareBindGroups will always run after Queue.
This means that the ordering of PrepareAssets is not fixed. It may run before or after Queue as either position sufficiently fulfills the requirement of running after ExtractCommands and before Prepare

So, if a mut command is added to Queue then systems which run within the PrepareAssets set may get a flushed command buffer, or they might not.

#

This means that prepare_textures prepare_removal and prepare_materials_tilemap could all be affected. Let me take a closer look

#

(Also, I wonder if it's a bug that PrepareAssets isn't part of the Prepare set? Seems unlikely but the naming of the set implies otherwise)

#

Also, I note that there's:

    /// Flush buffers after [`PrepareResources`](RenderSet::PrepareResources), but before ['PrepareBindGroups'](RenderSet::PrepareBindGroups).
    PrepareResourcesFlush,

which implies flushing at an appropriate timing is quite important here

paper turret
#

okay so

#

I pulled down a local copy of bevy and bevy_ecs_tilemap to muck with stuff some more

#

and I find that if I change bevy's code to:

#
  schedule.configure_sets(
      (
          ExtractCommands,
          PrepareAssets,
          ManageViews,
          Queue,
          PhaseSort,
          Prepare,
          Render,
          Cleanup,
      )
          .chain(),
  );

  // schedule.configure_sets((ExtractCommands, PrepareAssets, Prepare).chain());
#

then the issue no longer reproduces

queen galleon
#

How do I change the size of my tilemap? I tried to in Bevy_editor_plz but could not.

paper turret
# queen galleon How do I change the size of my tilemap? I tried to in Bevy_editor_plz but could ...

let map_size = TilemapSize { x: 144, y: 144 };

commands.entity(tilemap_entity).insert(
    TilemapBundle {
        size: map_size,
        ..default()
    },
);

something like this but you'd need to provide a few other defaults, I would suggest taking a look through the examples: https://github.com/StarArawn/bevy_ecs_tilemap/blob/main/examples/basic.rs

GitHub

A tilemap rendering crate for bevy which is more ECS friendly. - StarArawn/bevy_ecs_tilemap

queen galleon
paper turret
slim forge
#

has anyone successfully implemented pathfinding with this crate?

paper turret
#

I don't really treat this crate as a simulation/model concern - just a rendering concern. I know that conflicts with what some people are doing with it (i.e. it wouldn't need to support serialization if people weren't using it as a source of truth), but, if I needed pathfinding, I wouldn't be looking to build it ontop of this.

brisk path
#

imo though its better to have a collider storage alongside the tilemap

#

In some cases your pathfinding grid might be larger or smaller then your tilemap's rendering grid.

paper turret
#

btw @brisk path I'm back to thinking there's an issue with bevy-ecs-tilemap for bevy 0.13 and it's not a bevy issue. I talked to some people and someone said they experienced a similar issue with Hanabi.

like one could argue it's an issue with Bevy, but I think the fix would be bad for performance, and so it's more on consumers of Bevy to ensure proper functionality since there's nothing technically wrong with what Bevy's doing with their own code

#

going to try and spend the day hunting it down, gotta learn a lot more about bevy-ecs-tilemap's internals though

paper turret
#

yeah, it's nice to have the motivation to learn the internals rather than just throwing my hands up and letting the library do its magic

unreal condor
# paper turret going to try and spend the day hunting it down, gotta learn a lot more about bev...

I remember when I was trying to migrate bevy_ecs_tilemap to Bevy 0.12 being super confused about the new render sets. I had the system that's in Queue in QueueMeshes which felt right, but it just sorta didn't work. (My branch ultimately was not the one that got merged anyhow, I was in way over my head)

But I wouldn't be surprised at all if we have something in "the wrong set" or we are missing an ordering constraint that we are supposed to be adding or whatever.

#

Might be handy to generate one of those for bevy_ecs_tilemap and compare to bevy's material / sprite stuff.

paper turret
#

I have seen it. That's not a bad idea. I'll keep it in mind!

slim forge
paper turret
#

Lets see if I can just get lucky. Going to make the most obvious change based off of the Hanabi PR and see if it "just works"

paper turret
#
    /// A sub-set within [`Queue`](RenderSet::Queue) where mesh entity queue systems are executed. Ensures `prepare_assets::<Mesh>` is completed.
    QueueMeshes,
#

Where I observe that if I force PrepareAssets to run in a fixed ordering ahead of ManagedViews then the issue no longer reproduces, but if I try to put PrepareAssets in a fixed location later then the app panics because some of the systems need to run earlier.

#

So PrepareAssets is allowed to run in a semi-ambiguous location and some of the systems added to it may choose to run earlier or later than Queue of their own volition

#

And the comment in QueueMeshes seems to acknowledge that this could be problematic for some usecases and so it exposes finer granularity to allow for running later

#

Do you recall what "just sorta didn't work?"

#

Interestingly the issue still reproduces if I change to using QueueMeshes so it's not just that

#

I'm just going to keep monologuing in here while I figure this out, please bear with me 😄

#
WORKED:
2024-03-19T18:50:21.506250Z  INFO bevy_ecs_tilemap::render::material: prepare_materials_tilemap
2024-03-19T18:50:21.506328Z  INFO bevy_ecs_tilemap::render::prepare: prepare_removal
2024-03-19T18:50:21.506376Z  INFO bevy_ecs_tilemap::render::prepare: prepare
2024-03-19T18:50:21.513728Z  INFO bevy_ecs_tilemap::render::material: queue_material_tilemap_meshes

DIDN'T WORK:
2024-03-19T18:50:47.587285Z  INFO bevy_ecs_tilemap::render::material: prepare_materials_tilemap
2024-03-19T18:50:47.597988Z  INFO bevy_ecs_tilemap::render::material: queue_material_tilemap_meshes
2024-03-19T18:50:47.599581Z  INFO bevy_ecs_tilemap::render::prepare: prepare_removal
2024-03-19T18:50:47.599628Z  INFO bevy_ecs_tilemap::render::prepare: prepare

Instead of running the tool I just added some basic logging and ran a couple of times until I got a successful and unsuccessful run. Here's the ordering in which the relevant systems bound to PrepareAssets and Queue executed for each.

#

so the obvious thing is that prepare_removal and prepare ran after queue_material_tilemap_meshes (which is allowed because PrepareAssets can run after Queue) and that doesn't exhibit bad behavior if no command is added to the Queue set

#
queue_material_tilemap_meshes::<M>.in_set(RenderSet::Queue)
    .after(prepare::prepare),

This appears to fix the issue!

#

But I don't understand the problem enough yet so I'm going to try and understand why a bit better now

unreal condor
#

I also have a vague memory of some bevy_ecs_tilemaps systems being called "queue something" but they were actually doing "prepare stuff," or maybe vice versa. And maybe there was some discussion about potentially renaming some systems and that either happened or didn't. Super useful, commentary lol.

I'm re-reading https://bevyengine.org/learn/migration-guides/0-11-to-0-12/#reorder-render-sets-refactor-bevy-sprite-to-take-advantage now and trying to figure out if we're generally doing what it says to do.

#

The PR description from that change mentions potentially needing to order systems after mesh/material prepare, actually, if I'm reading right. So it seems like you may be onto a proper fix.

paper turret
#

Yeah, I feel good about this change at this point.

#

I observe a few other things:

#

if I write:

queue_material_tilemap_meshes::<M>.in_set(RenderSet::Queue)
    .before(prepare::prepare),

and I change my test code to omit the noop commands:

if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
    // render_app.add_systems(Render, test_system.in_set(RenderSet::Queue));
}

Then the issue continues to reproduce even though I have not inserted a system int Queue which would require flushing commands

#

I think this makes sense because prepare::prepare relies on commands. It calls commands.spawn with some of the chunk information and that is then read by queue_material_tilemap_meshes. If the command hasn't been applied yet then queue_material_tilemap_meshes fails to work against it

#

However

#

If I omit ordering entirely (so it can run before or after) and also omit my test code (i.e. code is what is currently shipped) then I observe the ordering always happens to be correct. I think this is due to how the scheduler is choosing to attempt to parallelize some functions. It happens to be choosing an order in which queue_material_tilemap_meshes runs after prepare::prepare due to their function signatures

#

Once I add a system that depends on commands to Queue that changes the order in which it decides to run things (which is a distinct issue from command buffering) and now happens to choose an order in which prepare::prepare may run after queue_material_tilemap_meshes

#

So it's kind of funny. On the surface, the issue appears to be one where adding a dependency on commands is causing the command buffer to be flushed at an inopportune time. In actuality, the issue is that introducing that dependency causes a reordering that isn't desirable. It's not really about command buffering itself because prepare::prepare will have its commands flushed afterward automatically.

#

Anyway, I'll put up the fix now

unreal condor
#

Fascinating

queen galleon
#

How do I turn TilePos into world pos?

queen galleon
#

How would I make it so that the TilePos origin was at the world origin. I could just multiply and divide if I did that.

paper turret
#

lol I think I wrote that manually

#

let me see if they equate to the same result and I can simplify my code a bit

sick halo
#

what kind of performance should i expect? i'm running a 300x300 map and i'm getting single digit fps. is this normal?

unreal condor
#

I would expect better for that size of map.

sick halo
#

yap, using the first 2

brisk path
#

What hardware?

sick halo
#

ryzen 3600, rx 6650xt and 32gb ram

brisk path
#

In the console the output should tell you what GPU Bevy picked

#

Can you post that here?

sick halo
#

it's a desktop, so it has to be using the 6650xt

#

but here you go
2024-03-28T23:58:45.808025Z INFO bevy_winit::system: Creating new window "App" (0v1)
2024-03-28T23:58:45.886780Z INFO bevy_render::renderer: AdapterInfo { name: "AMD Radeon RX 6650 XT (RADV NAVI23)", ven
dor: 4098, device: 29679, device_type: DiscreteGpu, driver: "radv", driver_info: "Mesa 24.0.3-arch1.2", backend: Vulkan
}

#

i'm just running the basic example from the repo

brisk path
#

On Linux even with one GPU you can get the software driver

#

But that doesn't seem to be the case here

#

Can you open up an issue in GitHub? I'll try to take a look. I don't have an amd GPU though

sick halo
#

sure, but i might do it tomorrow, i was about to go to bed

sick halo
#

seems like it was only in bevy_editor_pls, so false flag, my bad

lilac trout
stray lake
#

Is there a way to blend tiles together? Like the effect of prison architect tilemaps.

grave wadi
#

Getting strange behavior using the master branch of bevy_ecs_tilemap where when it set the scale on the Transform of the tilemap to 2.0 on the x and y axis it seems to only set it to 1.25 scale until i set and unset the x or y scale field in bevy_editor_pls. Unsure if this is a bug or a misuse of the library or the consequence of me using master

#

Pre and post me setting the y axis scale to something else and back to 2.0. The information tab is open to the small sprite i placed at about the expected height

grave wadi
#

If I modify the y translation of the map in the editor at all it immediately jumps to the 2nd screenshot

mental turret
#

I feel really silly, but is there anything special I need to do to have the tilemap be able to use different parts of a texture?

I currently have:

TilemapTexture::Single, a texture with a size of 128x128, a tile size of 32x32 and a TileTextureIndex(1). But only TileTextureIndex(0) renders something (namely the first tile in the larger image). Am I missing a step here? Sadly I can't find anything in the documentation or examples

grave wadi
#

Do have any code examples or the image in question of what you are doing

mental turret
#

I am not sure, but after re-opening the project today it started working?? coolcry

I have no idea what the problem was yesterday...

mental turret
#

I am back with another question!

Is it possible to change the origin of the tiles being drawn? Some of the tiles I want to draw are bigger, and I want them to be drawn from the top-left

#

for example, the white square is the current position cursor, and I'd want the purple square to not be centered.

#

Well, time to see if I can figure this out

grave wadi
#

You can modify the transform of the tilemap to achieve this

#

It requires some math through

mental turret
#

But if I change the transform of the tilemap, the individual tiles will still be centered, right? 🤔

#

The two colored squares are in the same column, and should be aligned on the left side (and similarly for rows)

#

I could achieve this with multiple tilemaps that have different gridsizes, but I want them all to share the same gridsize but have different tile sizes

velvet hornet
#

I have an issue where the isometric/diamondpos tilemap is offset vertically by the difference -(tile_size.y - grid_size.y) / 2.. I've narrowed it down to the fact that I have tile atlas images of size 256x512 and grid size 256x128, which results in a difference of (512-128)/2 == 192 (or 1.5 tiles).

This is all fine for rendering purposes, but it throws off all of the helper functions for centers and such. The black X in the above image is worldspace 0,0 and the tilemap's center comes back as 0.

I think I can live with it by adding the offset everywhere but I figured I'd ask here if anyone knows of a way to deal with this or knows its a bug or whatnot. I started reading the source code but haven't gotten to the spot that handles this yet.

faint glade
#

I too have encountered something like this where the y is offset by the level size (-512 px). Both gizmos and rapier2d collision boxes require manually modifing queries. I am using bevy_ecs_ldtk but given @velvet hornet post and that bevy_ecs_tilemap does the rendering it might be an issue at render?

velvet hornet
trail lion
#

When creating a TileStorage with a TilemapSize, is the size in number of pixels per tile, or number of tiles in the texture?

#

wait, nevermind, me dumb

trail lion
#

idk why, but the version 0.12.0 of bevy_ecs_tilemap, seems to be compiling with bevy 0.12, even though the github lables it as having a 0.13 bevy dependency

velvet hornet
#

the 0.13 version of tilemap (which had the bevy 0.13 dependency) didn't make it to crates.io before 0.14's release cycle started, so on github you're likely just looking at the 0.13 version without an updated version field

trail lion
#

ahh

#

Is there a way I could access the 0.13 version of tilemap, without crates.io?

velvet hornet
#

you can use it as a git dependency, yeah

velvet hornet
# trail lion Is there a way I could access the 0.13 version of tilemap, without crates.io?

like it says in this issue, although you've want to specify the current commit rev as well: https://github.com/StarArawn/bevy_ecs_tilemap/issues/516

GitHub

Opening this issue so we have a central place to talk about a release that supports Bevy 0.13. bevy_ecs_tilemap has not yet done a crates.io release that is compatible with Bevy 0.13. The latest re...

unreal condor
#

The code in the main branch on github is ahead of the latest release. There was never a crates.io release targetting Bevy 0.13. You can use git = "https://github.com/StarArawn/bevy_ecs_tilemap" in your Cargo.toml though.

trail lion
#

yalp, that did it, thanks!

unreal condor
#

Whoa oops, discord wasn't showing me the latest messages. I'm late to the party.

echo niche
#

I looked into the chunking example on the github (https://github.com/StarArawn/bevy_ecs_tilemap/blob/main/examples/chunking.rs) where 4x4 a chunk size is used (each chunk seems to be a separate tilemap entity). Then there is also the render_chunk_size porperty of the render_settings (line 49) which seems to be set to 8x8 tiles. So my question is: What is the difference between the CHUNK_SIZE and the RENDER_CHUNK_SIZE and why is the second one 2 times the first one?

GitHub

A tilemap rendering crate for bevy which is more ECS friendly. - StarArawn/bevy_ecs_tilemap

atomic roost
#

Hello there! I'm struggling to use bevy_ecs_tilemap for my game project and would really appreciate any help. My game is using a pixel art style and so the tiles need to be considerably scaled up in order to look correct and I am struggling to see how to achieve this. The first image shows what it looks like initially. As you can see the character on the left is far larger than the tiles. So far I have tried three approaches to this issue. The first one was to increase the "grid_size" of the tilemap bundle which resulted in the second image. As far as I can tell this made the tiles appropriately spaced but still far too small. The next approach I tried was increasing the scale of the transform for the tilemap bundle which made everything seem exactly as I wanted but caused it to be culled far too early and disappear while it was still covering the screen. The last approach I took was to increase the "tile_size" of the tilemap bundle but that causes a nasty crash that I have not been able to decipher. ```
2024-06-20T12:50:56.125864Z ERROR log: Device::create_texture error: Dimension Z is zero
2024-06-20T12:50:56.125891Z ERROR log: Handling wgpu errors as fatal by default
thread 'main' panicked at /home/churst/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wgpu-0.19.4/src/backend/wgpu_core.rs:3006:5:
wgpu error: Validation Error

Caused by:
In Device::create_texture
note: label = texture_array
Dimension Z is zero

I'm sorry if this is a silly issue but I'm very lost on what to do here.  I'm happy to provide any more information if that would be helpful. I hope someone can figure this out!
unreal condor
#

Unfortunately you can't do what you want with the various "_size" properties, so that's a dead end. Adding a property that does this is a common request and someone attempted a PR once but it fizzled out.

I am surprised that scaling the tilemap bundle with its transform is causing culling issues. I feel like that should work.

But perhaps you want to scale the camera instead? https://bevy-cheatbook.github.io/2d/camera.html#scaling-mode

atomic roost
shell estuary
#

Hey i'm trying to load a tiled map and i'm using the exact example helper function done in the examples.

What i want to do is access the "TileData" for each tile i process during the map gen so i can do some custom process, with the collision info to be precise.

I can see the data is available but if I do

match layer_tile.get_tileset().get_tile(layer_tile.id()) {
        Some(d) => d,
        None => {
                continue;
        }
};

dbg!(extra_tile_info);```

here, "extra_tile_info" is a type "Tile" which has a "data" field of type "TileData" which contains the collision info.
My problem is that "data" is a private field with no getter associated. 

Am I missing something or going about this the wrong way?
unreal condor
#

Reading through the docs, it seems that Tile derefs to TileData.

shell estuary
# unreal condor Reading through the docs, it seems that `Tile` derefs to `TileData`.
match layer_tile.get_tileset().get_tile(layer_tile.id()) {
        Some(d) => d,
        None => {
                continue;
        }
};

let extra_tile_info = *extra_tile_info;```
```cannot move out of dereference of `tiled::Tile<'_>`
move occurs because value has type `TileData`, which does not implement the `Copy` traitrustcClick``` 
Sorry i'm still fairly new to rust but looking through the impl this looks like this should work to me? 
```impl<'tileset> std::ops::Deref for Tile<'tileset> {
    type Target = TileData;

    #[inline]
    fn deref(&self) -> &'tileset Self::Target {
        self.data
    }
}```
shell estuary
# shell estuary ```let extra_tile_info = match layer_tile.get_tileset().get_tile(layer_tile.id()...

I've gotten this working with:

match layer_tile.get_tileset().get_tile(layer_tile.id()) {
  Some(d) => d,
  None => {
        continue;
  }
};

let extra_tile_info = extra_tile_info.clone();
let collision_info = extra_tile_info.collision;

dbg!(collision_info);```

But i can't help but feel this is bad, using a clone this many times in a loop cant be good for perf. I'm going to move it out but i still can't help but feel like i'm going the long way around.
unreal condor
#

Possibly dbg!(&*extra_tile_info) would have worked, not actually totally sure what that dbg macro is doing myself, really.

Doesn't seem like you should need to clone the entire Tile, but depending on how you're using the data maybe you need to do something like (*extra_tile_info).collision.clone() or whatever.

stray oak
#

What are some examples of things that shouldn't use a tilemap?

Obviously the map itself is going to be on tiles, but I'm wondering at which point entities (players, intractable things) should or shouldn't be manually drawn on top.

A player for example that can move freely (think Stardew valley) seems like something that shouldn't be on a tilemap. But something like a tree I'm less sure about, since that might potentially span multiple tiles, some of which might be collidable etc (eg. I think I'd want a single "tree" entity).

A bit of rambling I know! But any general guidance to help my line of thinking is appreciated ♥️

velvet hornet
#

I've been using images that are 4x tall compared to a given tile. 256x512 for images compared to 256x128 and its been working fine.

stray oak
#

Interesting, I suppose that would work. Didn’t realize layers could have different tile sizes.

#

Thanks!

#

Do you have any cases where poles overlap each other? e.g. the base of one pole is two “small” tiles above another

#

If they’re each a whole tile, presumably on the same layer, can they both still be rendered, one behind the other (slightly offset)?

velvet hornet
#

I've had a number of different maps before I switched to using depth values in my current project, and they all were working just fine in an isometric map. Some samples of the maps here, although they rendered the same in bevy as shown

#

multiple layers, tall tiles stacked side-by-side or in front of each other.

#

anything that is "tile sized" works

#

with the depth values I started using, its even more granular. per-pixel layering effectively, but the crate without the depth values should work as-is for tile-sized stuff and multiple layers

stray oak
#

Thanks for all the info!

I saw your other posts about using the depth buffer on top of ice’s PR. Pretty neat idea; a lot more granular.

velvet hornet
#

yeah, it doesn't have to be that granular either. could just set it to be based on the render chunk position or whatnot

#

but bevy_ecs_tilemap already works as-expected with tile-size based items and sorting

brisk path
#

@velvet hornet Thanks for updating to bevy 0.14. Can you give me a DM when that branch gets merged and I'll look into doing an actual release.

unreal condor
velvet hornet
#

@unreal condor I pushed up the removal of those unused features we needed to remove. I think that's all that was left

#

ran a few of the examples and they work as expected still

unreal condor
#

Cool, spot checked on webgl2 / wepgu as well. Will merge once I get the official green light from CI.

unreal condor
#

@velvet hornet I think the only concern left is the version number bump -- I'm pretty sure the current alignment is coincidental, and the next version should be 0.13.

Though I'd probably actually just not touch it and let StarToaster do that release prep.

brisk path
velvet hornet
unreal condor
#

cool cool

#

merged

brisk path
#

Just fyi I can't deploy tonight, about to head to bed.

#

I'll try to do it tomorrow

shell estuary
#

Does anyone know the best way to do a valid "find nearest valid tile" sort of search?

I'm building my gameworld in Tiled and have it all loading with collisions and extras really nicely but it occurs to me the best way for me to visually map the spawn points would be to paint an invisible layer in my Tiled map which i can then, hopefully, query and make use of.

The problem is i'm not sure what to query and access to get each tile info?
Alternatively does anyone know how to search out the nearest tile given some world coordinates?
Either way i need the tile info i suppose 🤔

velvet hornet
#

If you're using tiled then you're probably using tiled-rs which has all the tile and layer data too

silver shale
#

Hello all, I have a question, is there a recommended way to render animatedentities, that ocupy multiple tiles? I trying to allow building structures that can vary in size

velvet hornet
# silver shale Hello all, I have a question, is there a recommended way to render animatedentit...

There's a few different ways you can set up your grid to support overlapping, including adjusting the TilemapGridSize: https://docs.rs/bevy_ecs_tilemap/0.12.0/bevy_ecs_tilemap/map/struct.TilemapGridSize.html or just having a second layer with a larger tile size.

If you have a lot of things that are many different sizes that don't fit into tiles, you may just not want to use the tilemap functionality at all for those items and use sprites instead.

silver shale
#

yes my idea right now was to use the tiling for information, floor texture and collision, and usingthe position to renderthe sprite, but wanted to see if there was another way!! thanks, I'll check the docs you sent!

stiff ore
#

I'm trying to get started with tiled.

I've added the "helpers" folder and copied the relevant code into my main.rs as follows:

use bevy::{
    prelude::*,
    render::{
        settings::{PowerPreference, WgpuSettings},
        RenderPlugin,
    },
};
use bevy_ecs_tilemap::prelude::*;
mod entity;
mod helpers;
pub use crate::entity::entity_util;

fn load_map(mut commands: Commands, asset_server: Res<AssetServer>) {
    let map_handle: Handle<helpers::tiled::TiledMap> = asset_server.load("test-map.tmx");

    commands.spawn(helpers::tiled::TiledMapBundle {
        tiled_map: map_handle,
        ..Default::default()
    });
}

fn main() {
    App::new()
        .add_plugins(
            DefaultPlugins.set(RenderPlugin {
                synchronous_pipeline_compilation: false,
                render_creation: WgpuSettings {
                    power_preference: PowerPreference::LowPower,
                    ..Default::default()
                }
                .into(),
                ..Default::default()
            }),
        )
        .add_systems(Startup, load_map)
        .run();
}

this files has no errors and is fine, the issue is the tiled.rs file in the helper folder is ate up with errors, and I'm not sure why?? Am I missing dependencies or something??

unreal condor
stiff ore
#

I just responded - really appreciate it!

#

trying LDTK now

unreal condor
#

Yeah, bevy_ecs_ldtk might be a quicker way to get up and running.

Though as far as I know, there isn't a branch or release that is compatible with Bevy 0.14 yet.

It's a bit of an awkward situation, as they depend on bevy_ecs_tilemap, but bevy_ecs_tilemap hasn't had a release on crates.io even for the last version of Bevy, so they can't do one either.

It looks like they're moving to just asking users to use them as a git dependency, but they just haven't gotten to updating for Bevy 0.14 yet.

The bevy_ecs_ldtk channel is over https://discord.com/channels/691052431525675048/1037525851362840636 here, and they might know more.

high zinc
#

Hey, so I recently decided to create bevy_ecs_tiled and see if I can help to fill that gap in the ecosystem starting with the helpers in bevy_ecs_tilemap. I've already added a bunch of new things including support for infinite tilemaps, better nesting of maps/layers/tiles, and ability to unload/reload maps. I also applied the PR for supporting non-embedded tilesets (TSX files).

I'm in the same boat as bevy_ecs_ldtk regarding being unable to push a recent version, but hopefully this can be remedied "soon".

Hoping this might also take some pressure off bevy_ecs_tilemap w.r.t. Tiled support too

stray lake
#

Is it possible to use a 64x64 tileset on a 32x32 grid without overlap? So that it scales down instead of overlapping.

#

Or alternatively use 64x64 gridsize and scale down the mesh somehow?

velvet hornet
velvet hornet
#

I don't think there's a combination of settings that will scale a larger tile into a smaller tile (like 64 into 32) though, since the sizes overlap instead of scaling.

stray lake
#

Ok, thanks. I think the best solution then would be to adjust everything to fit with 64. Had a small hope that it could work 🙂

velvet hornet
#

also I'm pretty sure you could do it in a custom shader if you really wanted to but honestly I'd just resize the images to fit what they're intended to be myself

unreal condor
#

it's a common feature request and there was a PR to add it, but it got stalled out.

paper turret
#

I'm not 100% sure, but I think you might be referring to the PR I contributed to? The code works as-is, I use it in Symbiants fine, I just didn't get a response from anyone regarding the initial blocking feedback and ways to accomodate it

#

so yes, stalled out in terms of getting merged in, but functionally fine

unreal condor
# paper turret so yes, stalled out in terms of getting merged in, but functionally fine

Hadn't looked at the PR in a long time, didn't mean to imply any particular party being responsible for the stall or any technical issues, just that progress had stopped.

It has been a while since I looked at the PR, but at a glance, I'd like to answer the questions in https://github.com/StarArawn/bevy_ecs_tilemap/issues/337#issuecomment-1381883272 and if this is the best solution, at least brainstorm some other names for the type.

And things are just sort of stalled in general -- with bzm3r no longer being involved with anything bevy-related, and StarArawn being super busy. I can press the merge button, but only with a GH approval from someone with write permissions.

paper turret
#

No worries, I wasn't taking any offense

unreal condor
#

@velvet hornet any interest in getting merge rights to the repo if StarArawn is willing?

velvet hornet
paper turret
#

Unrelated, but I was wondering if the GPU frustum culling work done in Bevy 0.14 would allow for any simplifications here? Or are they entirely distinct things? I know there's a frustrum culling example in the repo but I don't really know much beyond that

velvet hornet
#

I just took a quick scan and the frustum culling implementation is really not that many lines of code in tilemap

unreal condor
#

I wonder if bevy_ecs_tilemap's frustum culling predates even Bevy's cpu-based 2d frustum culling. It might.

paper turret
#

Thanks for doing that

unreal condor
#

@brisk path If you have a moment soon, a quick scroll through today's chat and issue 541 would be appreciated!

brisk path
#

@unreal condor @velvet hornet I'll try to find time to add maintainer permissions for everything. In terms of upstreaming @earnest spruce was onboard with it at one point, and had some sort of rough process outlined. I'm not sure if that's more fleshed out yet or not.

earnest spruce
#

Yep, I'm still down to have "some sort of first-party tilemap solution", which I expect will learn heavily from this crate and let you deprecate it

#

Trade-offs are more complex and there's less of a clear winner than with picking though, so there would need to be some design work first 🙂

brisk path
#

Honestly the biggest blocker might be performance, but if I remember right it was caused by the transform propagation system eating up CPU cycles on tile entities that had parents but not transforms it was odd to me that the system didn't have some kind of filter on the queries to avoid iterating on non-transform entities.

#

That was bevy 12 though

#

Looks like that is still the issue

earnest spruce
#

And Static marker components should help even more

brisk path
#

Could probably just add an IgnorePropagation component.

velvet hornet
#

Avian 0.1 reworks all of the transform propagation systems to use custom implementations that only traverse trees with physics entities. This is done by marking ancestors of physics entities with an AncestorMarker<C: Component> component that indicates that some descendant of the entity has the given component. This can be used to skip traversing trees that have no effect on the simulation.

brisk path
stray lake
#

I am experimenting with custom shaders and wonder if it is possible to get the tile id of the neighbors of the currently processed tile?

I am not using Atlas feature, so I need the id to fetch the color from.

velvet hornet
#

@unreal condor I believe we're all set to do a release. I've got the required access to git and crates afaik.

There's a couple PRs we could merge that are low-risk. Mostly deriving Eq and such.

#532 and #465 (needs a rebase).

We could also potentially merge #536

I'm thinking I'll do the rebase/merge of these tomorrow unless you're against merging before release. and then executing a release for 0.14 after that.


#431 was the only other "previously approved" PR, but it looks like it needs a rebase and is enough code that I'd like to review it more thoroughly first before merging. So let's leave this out for a future point release.

#

I'd like to do a release before the jam starts on Saturday if we can agree to that

unreal condor
velvet hornet
#

ci green, merging

#

@unreal condor everything we wanted in is in and I'm going to attempt a release in 30 min.

unreal condor
#

Sounds good

velvet hornet
#

looks good to me

unreal condor
#

Looking good over here too in my app.

#

I wonder if we could use a component hook on TileStorage to sidestep the "transform propagation perf" issue. It seems like our examples use bevy's hierarchies solely to make it convenient to despawn tilemaps and their associated tiles (tiles do not have transforms). A hook could just take care of that.

brisk path
#

or transform propagation could have an opt out component tag. 😛

unreal condor
#

I was going to open an issue about the perf problem (are you aware of one existing already?), but I dug up another issue describing a very similar situation here https://github.com/bevyengine/bevy/issues/9228.

I feel like "fixing transform propagation so it only does stuff with things that have transforms" has a better chance of getting merged.

But I feel like a hook would be pretty invisible to users and they could generally just keep doing what they are doing and this would simplify the process of spawning a tilemap.

brisk path
unreal condor
#

I guess some or most folks would expect that to work 😦

brisk path
#

A NoTransformPropagation component tag that the propagation system filters with would work just as well and we could hide it in the tile bundle.

unreal condor
#

Actually, do scenes rely on that behavior right now?

unreal condor
#

Seems plausible

earnest spruce
brisk path
#

it would be such a small change to do With<GlobalTransform> :p

earnest spruce
#

Do it 😈

velvet hornet
#

haha, I'll put it up if that's acceptable

unreal condor
#

Seems like there shouldn't be any issue with gltfs / scenes

brisk path
brisk path
#

I remember getting push back on this before so I suspect the PR will probably not get approved.

queen galleon
#

This is not Bevy 0.14...

#

What do I do?

brisk path
#

Check out crates.io its bevy 14 and open an issue in the repo to update that table.

queen galleon
queen galleon
queen galleon
#

(I don't know how to do that)

queen galleon
#

Does it make much sense to change the size of a tilemap every once in a while?

velvet hornet
velvet hornet
#

My first thought is that only rendering small portions of a large tilemap would be a chunking use case (which is supported) and changing tilemap dimensions might change where things render (although I'm not sure about this part)

earnest spruce
#

I've seen tilemaps change in size when the map needs to grow

velvet hornet
earnest spruce
#

Get some performance wins on smaller maps

#

Factorio and Minecraft both do dynamic as-needed world generation

velvet hornet
#

right, and bevy_ecs_tilemap has TileStorage and frustum culling, so I think that's the case today (but I need to verify to be certain)

#

I suppose now that I remember the storage fills all the tiles with None though

#

puts some experiments on his todo list

brisk path
brisk path
#

For quick look up this is the fastest method

#

I could of used a hashmap but performance isn't great

shell estuary
velvet hornet
shell estuary
queen galleon
#

Is this what I should use to make a level editor?

velvet hornet
# queen galleon Is this what I should use to make a level editor?

that really depends on your needs. I think if you need a level editor for the game jam, I would've went with something already written like LDtk. Its certainly possible to build a level editor on top of bevy_ecs_tilemap, but you have to build the whole thing yourself.

stray lake
#

Is there an easy way to disable chunking? Experimenting with shaders again and I am seeing that storage_position is repeating over the chunks.
So if I am trying to access x:1,y:1 , then I will color 4 tiles, but I only wanted to modify one of them by the shader. Is there a workaround to this?

brisk path
#

It's been a while , but I'm pretty sure turning off the GPU chunks won't solve the issue.

stray lake
trail lion
#

Is there a standard way of adding colliders (bevy_rapier2d, specifically), to some of the tiles? I found a work around by adding/updating a transform bundle and a collider, but I was curious if there was a different way.

alpine veldt
#

Hi, has anyone had any luck using file_watcher with bevy_ecs_tilemap? I noticed that changing the image file registers correctly with bevy, but any tilemaps that are rendered do not update. I confirmed it with my own project and also the basic.rs example (the texture does change there, but only when you cycle the texture).

unreal condor
alpine veldt
#

Thank you. I will read into the PR a little more as well

velvet hornet
unreal condor
velvet hornet
#

they've been carrying that forward for a year it looks like

#

(and by "I" I mean you can ping me if something needs a rebase like that)

unreal condor
#

eh, was scared to write to their branch and didn't want to just yoink their code without asking.

unreal condor
#

alright, I can just open a fresh PR.

paper turret
#

I really appreciate both of you stepping up and working more on this project. It's made me more excited to contribute, too. I just ordered some new PC parts to try and halve my Rust compile times and am going to work on that PR for the "physical tile size" over the next couple of days and see if I can't get something shippable. I want to stop depending on a fork of a fork in my own codebase and figure I should achieve that by getting this stuff upstreamed.

#

Just a heads up cuz I'll probably start hounding you with questions here soon 🙂

velvet hornet
#

its pre-existing in the type so /shrug but a bit strange. maybe just vestigial?

velvet hornet
unreal condor
#

Cool, will look closer in the morning. Initial thought is that it really would be great to clean some of that up with a macro or two similar to how the original PR did, but without the lossy conversion from f32 -> u32.

But I don't mind the manual impls in the meantime, especially with the added tests.

velvet hornet
#

yeah fine by me. I don't love the way macros obscure the impls in docs but I don't have a strong opinion

alpine veldt
#

Just tested file_watcher after the new pull request was merged! I can confirm that it is working as expected on my end. Thank you for your help!

stray lake
#

Is there a way I can have a tileset with more than 2048 tiles in it? Got an error that this was the max size when I exceeded this size.

brisk path
stray lake
#

Ah. Thanks. Will look into creating another layer then, I already have two, so I am a little hesitant on adding yet another one. Might be the best solution tho.

brisk path
#

Lastly you can turn off texture arrays and use the atlas directly but that can result in unwanted artifacts appearing.

#

Also keep in mind that textures will have some max size too

#

for example a 8192x8192 texture could have a max of 262,144 16x16 tiles in it.

queen galleon
#

I can't bevy ecs tilemap.

#
const TILE_SIZE: TilemapTileSize = TilemapTileSize::new(32.0, 32.0);

pub fn _setup_debug_tilemaps(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    array_texture_loader: Res<ArrayTextureLoader>
) {
    let map_size = TilemapSize::new(32, 32);

    let ground_texture_entity = asset_server.load("ground.png");

    let tilemap_entity = commands.spawn_empty().id();

    let mut tile_storage = TileStorage::empty(map_size);
    
    for x in 0..map_size.x {
        for y in 0..map_size.y {
            let position = TilePos::new(x, y);
            let tile_entity = commands.spawn(
                TileBundle {
                    position,
                    tilemap_id: TilemapId(tilemap_entity),
                    ..default()
                }
            ).id();
            tile_storage.set(&position, tile_entity);
        }
    }


    let grid_size = TILE_SIZE.into();
    let map_type = TilemapType::default();

    commands.entity(tilemap_entity).insert(TilemapBundle {
        grid_size,
        map_type,
        size: map_size,
        storage: tile_storage,
        texture: TilemapTexture::Single(ground_texture_entity.clone()),
        tile_size: TILE_SIZE,
        transform: get_tilemap_center_transform(&map_size, &grid_size, &map_type, 0.0),
        ..default()
    });


    array_texture_loader.add(TilemapArrayTexture {
        texture: TilemapTexture::Single(ground_texture_entity),
        tile_size: TILE_SIZE,
        ..default()
    })
}```
#

Nothing appears.

velvet hornet
#

do you have a camera spawned?

queen galleon
velvet hornet
#

looks like tiles are spawning to me

#

I'm unfamiliar with that editor (is it bevy_editor_pls?), but can you check the components on those entities in any way?

#

I bet you'll see that they're tiles

queen galleon
#

And yes, they are.

velvet hornet
#

bevy-inspector-egui is the ui I'm familiar with, but that doesn't mean you have to use it

#

so if the tiles are spawning, and you have a camera, I'd start checking the texture asset loading next. It's not giving a warning about a missing asset is it?

#

I'm assuming you're also using the default 2d camera right?

queen galleon
#

Wait.

#

There is an error.

velvet hornet
queen galleon
#

I might switch just for that reason.

velvet hornet
#

ah right, I think I saw you using the git branch in #general

#

its less featureful but there is a 0.14 release for bevy-inspector-egui

#

what you showed in the screenshot is basically this:

use bevy::prelude::*;
use bevy_inspector_egui::quick::WorldInspectorPlugin;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugins(WorldInspectorPlugin::new())
        .run();
}
queen galleon
#

Thanks!

velvet hornet
queen galleon
velvet hornet
#

if you are looking for a higher-level solution, there is an integration for ldtk built on top of bevy_ecs_tilemap called bevy_ecs_ldtk, and it does have a 0.14 version out.

#

that enables an integration with https://ldtk.io/ which is a nice 2d tilemap editor

LDtk (Level Designer Toolkit) is an open-source 2D level editor for indie devs, with a strong focus on user-friendliness.

#

you can of course, build anything you want yourself if you so desire, but I figured I'd mention it

queen galleon
#

I want to attempt to make my own.

velvet hornet
#

nice, that's fun

queen galleon
#

I did nothing but add the new editor.

#

It doesn't work without it.

velvet hornet
#

and you're on bevy 0.14 right?

cargo tree -i bevy
queen galleon
#

It only works if I have bevy_editor_pls...

#

*Sigh*

velvet hornet
#

that seems strange, I wonder if bevy_editor_pls is adding its own additional plugins or something

queen galleon
#

Now I need to figure out how to make it work without bevy_editor_pls.

velvet hornet
#

did you remove bevy_editor_pls from your Cargo.toml and app?

queen galleon
#

Add them back in and it works.

#

What do I do now?

velvet hornet
#

I really don't know why remove bevy_editor_pls would affect anything

#

it definitely shouldn't be affecting the tilemap rendering afaik. They do use renderlayers but it looked like that was only for the UI rendering

queen galleon
velvet hornet
#

353 repos 💀 . metadata I didn't need to know lmao

queen galleon
#

(Never organized a GitHub repo with more then one person)

velvet hornet
#

settings -> collaborators

queen galleon
#

Done.

velvet hornet
#

cool, taking a look

queen galleon
velvet hornet
#

misnamed iirc, there's a different repo called corgo-bot

#

probably just a mistype

queen galleon
#

I want a corgi bot.

#

Is my code any good?

velvet hornet
#

oh its the projection

#

comment out the projection in the camera2d and it should come back

#

the default for the Camera2dBundle Orthographic projection is different than the OrthographicProjection's defaults

velvet hornet
#

you just fell victim to IMO a bit of a footgun when it comes to customizing the OrthogrpahicProjection

velvet hornet
#

IMO = in my opinion

velvet hornet
#

use the camera2dbundle's default values

#

so specify the near and far values in addition to any values you want to change, like scale

queen galleon
velvet hornet
#

specifically, at least this:

 OrthographicProjection {
            far: 1000.,
            near: -1000.,
            ..Default::default()
        }
velvet hornet
velvet hornet
#

the reason is that OrthographicProjection can be used in 2d cameras and 3d cameras, and the values need to be different to define what actually gets rendered

#

you're effectively defining a box, and values outside of that box's dimensions are excluded from rendering

queen galleon
#

Kay.

#

Shouldn't 2d cameras be different?

#

Works!

#

Thanks!

velvet hornet
#

great!

queen galleon
#

Is there a shortcut to check if a Vec2 is on a tile or do I do that manually?

sweet edge
#

I'm having a helluva time finding the offset I need to set to the x,y position for an object using the Tiled helper. I know that the helper positions the tilemap so the center of the map is at 0,0 but I'm looking at the offset for my map it's like -1008, 0?

velvet hornet
#

In particular I've definitely had to do some manipulation of colliders position defined on oversized isometric tilesets in the past

trail lion
#

Is there a way to have a 2d tileset, as opposed to a 1d array?

velvet hornet
trail lion
#

unless I missed something, which is distincltly possible

velvet hornet
#

do you have that impression because the examples use texture atlases that look like that? it is not a restriction of the crate

trail lion
velvet hornet
#

horizontal based as in they go 0-10 in the first row, then 11-20 in the second, etc

#

rather than column-based

trail lion
#

ah

#

that makes much more sense, appologies for the confusion and thanks!

velvet hornet
#

no stress, happy to clear it up

sweet edge
velvet hornet
#

the tile png dimensions that is

rare bramble
alpine veldt
#

When working with an entity that exists in the tilemap grid-space but needs to move around between tiles, do you normally create an entity with a TextureAtlasSprite and just keep it updated with the tilemap manually, or does bevy_ecs_tilemap have a more idiomatic solution?
I have had success with TextureAtlasSprite but it just feels a little strange sometimes to have tiles which are rendered one way and dynamic entities in another.

unreal condor
#

Do you mean literally "between tiles" / "off grid" / animating its position from one tile to the next? If so, you're doing the right thing.

alpine veldt
#

Yeah so in my example I have units on a top down grid, they are almost always exactly "on" a grid position, but they need to animate between tiles.

sweet edge
# alpine veldt Yeah so in my example I have units on a top down grid, they are almost always ex...

You could do something like this, basically have a system that looks at the transform and the entity's grid position. If they don't fall under some tolerance level (1 or 2 px for example) then you flag animating. The other systems like your move system or whatever can wait until the animation system is completed.


pub fn update_entity_position(
    mut query: Query<(&Position, &mut Transform)>,
        time: Res<Time>,
    mut ev_wait: EventWriter<GraphicsWaitEvent>
) {
    for (position, mut transform) in query.iter_mut() {
        let mut animating = false;

        let vec = grid_coords_to_translation(position.to_grid_coords(), IVec2::new(TILE_SIZE, TILE_SIZE));
        let target = Vec3::new(
            vec.x, 
            vec.y, 
            transform.translation.z
        );

        let d = (target - transform.translation).length();
        if d > POSITION_TOLERANCE {
            transform.translation = transform.translation.lerp(
                target,
                LERP_SPEED * time.delta_seconds()
            );
            animating = true;
        } else {
            transform.translation = target;
        }

        if animating {
            ev_wait.send(GraphicsWaitEvent);
        }
    }
}```
high forum
#

I'm getting an issue with mismatching TilemapTileSizes, Expected all provided image assets to have size TilemapTileSize { x: 544.0, y: 320.0 }, but found image with size: TilemapTileSize { x: 160.0, y: 128.0 } Is there any good way to figure out which image is causing the issue? And any good way to resolve this?

brisk path
high forum
#

There are like 10 different tile sets. I have no idea which one is causing this error.

brisk path
#

I can't recall what triggers this error, but I would check to make sure your tile sizes are setup correctly.

high forum
#

The error is coming from bevy_ecs_tilemap-0.14.0/src/render/extract.rs:118:25

#

I'm not sure what correctly means in this context, it's all working fine in Tiled.

turbid pier
#

Hello, how can i place the red dot in tile center ? i'm trying to inverse map transformation but i'm not fully aware of everything that happens, how can i map the tile world center to my mouse position ?

for (map_size, grid_size, map_type, tile_storage, map_transform) in q_tilemap.iter() {
            // needed in order to match tile with cursor
            let position = cursor_pos.0;
            let cursor_in_map_pos: Vec2 = {
                // Extend the cursor_pos vec3 by 0.0 and 1.0
                let cursor_pos = Vec4::from((position, 0.0, 1.0));
                let cursor_in_map_pos = map_transform.compute_matrix().inverse() * cursor_pos;
                cursor_in_map_pos.xy()
            };

            if let Some(tile_pos) =
                TilePos::from_world_pos(&cursor_in_map_pos, map_size, grid_size, map_type)
            {
                if let Some(tile_entity) = tile_storage.get(&tile_pos) {
                    let node_entity = commands
                        .spawn(MaterialMesh2dBundle {
                            mesh: meshes.add(Circle::default()).into(),
                            transform: Transform::default()
                                .with_scale(Vec3::splat(16.0))
                                .with_translation(position.extend(1.0)), // here
                            material: materials.add(Color::from(RED)),
                            ..default()
                        })
                        .id();

                    let center =
                        Vec4::from((tile_pos.center_in_world(grid_size, map_type), 0.0, 1.0));
                    let c = (map_transform.compute_matrix().inverse() * center).xy();
                    println!("({}, {})", c.x, c.y);
                    println!("({}, {})", position.x, position.y);

                    commands.entity(tile_entity).insert(Node(node_entity));
                }
            }
        }
#

tldr: i want to place the red dot on tile center and not just under my cursor

turbid pier
#

managed to have the correct center

 // compute tile center
                    let center = {
                        // center in world coordinates
                        let center_world = tile_pos.center_in_world(grid_size, map_type);

                        // we apply map transformation to world coord
                        // in order to get tile center in map coordinate
                        let center_window =
                            map_transform.compute_matrix() * Vec4::from((center_world, 0.0, 1.0));

                        center_window.xy()
                    };
velvet hornet
#

basically a matrix * vector translates the vector, so going one way (map -> world) you want to go one direction and going the other way you want the inverse (world -> map)

#

if you need a background in linear algebra, 3blue1brown has a great overview you can play through. Not all of it is necessary, but the lead up to and inclusion of matrix multiplication is worth it: https://www.youtube.com/watch?v=fNk_zzaMoSs

Beginning the linear algebra series with the basics.
Help fund future projects: https://www.patreon.com/3blue1brown
An equally valuable form of support is to simply share some of the videos.
Home page: https://www.3blue1brown.com/

Correction: 6:52, the screen should show [x1, y1] + [x2, y2] = [x1+x2, y1+y2]

Full series: http://3b1b.co/eola

Fu...

▶ Play video
turbid pier
velvet hornet
#

world space is centered on the world, and map space is centered on the map. The centers don't necessarily live in the same place. (and there's actually a third space, viewport, which is handled when setting the cursor position in that example via viewport_to_world_2d )

turbid pier
#

dumb question but the map space is for the tilemap right ?

velvet hornet
#

yeah

turbid pier
#

thanks

velvet hornet
#

the viewport is like the pane of glass that represents the camera lens, the world is what you'd get if you spawned something at 0,0, and the map could be offset in the world by lets say an arbitrary 1000,1000, so the map's center isn't the world's center

turbid pier
#

ok viewport is just another space that is from the camera sight, is related to window in some ways ?

velvet hornet
#

yeah its basically exactly the window in this case. It uses some odd coordinates, so a value from -1..1 for x and y axis, where 0,0 is center of the window.

turbid pier
#

oh

velvet hornet
#

that's why you have to use the viewport_to_world2d, because the camera could be moved around too

#

a camera that's at -500,-500 wouldn't be showing anything at the world origin 0,0 (most likely)

#

so you have to translate the -1..1 from the viewport into world space to figure out what coordinate you just clicked at

turbid pier
#

thanks you a lot, i have another little question, you extend 2d vectors to 4d with (0,1), i understand that you need to match the matrix shape to multiply, but with not (1,0) ?

#

i have knowledge in linear algebra but i don't see why that choice

velvet hornet
#

I believe that means "include w", but honestly my knowledge gets a little sketchy around w

turbid pier
#

w ?

velvet hornet
#

4 dimension vector is (x,y,z,w)

turbid pier
#

ah

#

ok

#

thanks a lot, i understand way better now

velvet hornet
#

happy to help 🙂

paper turret
paper turret
#

So I did a bit of reading

#

and I actually have a kind of weird question

#

Should this feature even be implemented?

#

I don't think godot supports it

#

https://forum.godotengine.org/t/resize-tile-in-tilemap/17073
https://www.reddit.com/r/godot/comments/14yp1l2/how_do_i_scale_tilemap_squares/

both these have people asking how to do it and both responses say you should just resize the asset instead

Reddit

Explore this post and more from the godot community

#

and my use case is pretty uh, bad, where I just have basically full squares of a single color so scaling them up is fine, it doesn't invite any weirdness with scaling some pixel art

#

but if I were to make my art better then I think I wouldn't want to scale the tile I would just want to make my art the right size for my tilemap

#

Anyway, I was just hoping to use godot's approach to influence my answers to https://github.com/StarArawn/bevy_ecs_tilemap/issues/337#issuecomment-1381883272 and then was surprised to see it didn't support it seemingly

GitHub

I believe it should be in TilemapBundle, but I may be wrong. Currently, TilemapBundle::grid_size cuts images off if smaller than TilemapBundle::tile_size or adds padding to the left and above if la...

#

Well I dunno, I guess actually I have it backwards, my assets are large and then I scale them down to a unit size - but that might (probably?) has unintended consequences

velvet hornet
#

"you should scale your images to the size you intend to use them" is not an unreasonable response in the meantime imo

paper turret
#

I'm going to try and hit up the wider Bevy community tomorrow about my specific use case and see if I am doing something wrong and/or inviting problems with my approach. I feel like it's kinda useful to express my grid tiles in 1x1 unit sizes and then handle sizing my map properly by zooming in on the viewport, but I had some weird artifacting with bevy_ecs_tilemap when doing that. I fixed it by disabling MSAA, but I wonder if that was the wrong solution.

#

It doesn't make a ton of sense to resize my tile sprites to 1x1 though since that'd be uhh, weird. It's just nice to be able to talk about the grid without having to multiply offsets by the tile size in a few spots.

#

but yeah my whole use case for this is physical_tile_size: TilemapPhysicalTileSize { x: 1.0, y: 1.0 },

#

anywho, for a later day

golden oriole
#

how are z indexes handled? my terrain is appearing on top of my character. my character has a z of 1.0 and the tiledmapbundle has a z of 0

#

oh interesting it looks like one of the child elements of the tiledmap has a transform of 100 by default

#

if i set my character to > 100 it appears on top

#

so i basically need all my stuff that should be "on top" of the terrain to be at least (100 * terrain layer count)

rare bramble
golden oriole
#

i'm not sure if i'm doing something wrong or this is unsupported in the library rn

golden oriole
#

hmm it seems like i am doing something wrong, avian2d seems mostly designed for side scrolling physics simulations with gravity pointing "down"?

rare bramble
#

No, I did not play a lot with either avian or isometric maps. You can change gravity in avian2d but indeed I'm not sure how it would translate for a 2d top down isometric view.
If you add colliders and see that they are not at the correct place / don't have the proper shape compared to what you see in Tiled, that may be an issue in bevy_ecs_tiled.

golden oriole
#

Yeah the latter is what's happening. I think avian2d is just not suitable for what I am trying to do, which is fine, I don't really want physics simulation, just collision detection.

So now I'm trying to figure out how to automatically add colliders to tiles by looking at how you did it in insert_tile_collider. I am pretty sure if I copy your logic directly the colliders will end up in the wrong location. Beyond that it seems kind of useful to have bevy_ecs_tiled be able to add the collider shapes without using avian2d/rapier so you can do what you want with them.

stuck flower
velvet hornet
#

@stuck flower at least one issue that I see is that you're using tile_size and grid_size as the same number. I believe you want 16/16 for tile and 16/8 for grid

#

because the "3d" will overflow the flat grid, basically. so the grid is like the flat image, and the "extra" tile pixels render above that

#

looks like there's still another issue after that though

stuck flower
#

In the render setting of the grid

velvet hornet
#

its supposed to have y_sort: true for this, which you already have afaik

#

there's a 3d_iso example in the repo, but it uses tiled so it might be a bit confusing

#

tldr that's 3 layers, and you're only working with one here

stuck flower
#

i have added these into render settings but not sure if using chunk_size like that has any drawbacks or problems

     render_settings: TilemapRenderSettings {
            render_chunk_size: UVec2::new(2, 1),
            y_sort: true,
            ..Default::default()
        },
#

i have seen that in a comment some where can't remember where, not sure thats the correct way to do it.

velvet hornet
#

chunk size is basically "how many tiles get batched together on the gpu in a mesh to render", so I can see why it would have an effect, but when correctly set up it should not have a visual effect like that

stuck flower
#

interesting. got any other ideas to test out. i was thinking to reverse loop

velvet hornet
#

there's something else different between your current application and the 3d_iso demo in the repo. not sure what it is yet

#

nothing pops out to me at the moment, but it may just be late for me

stuck flower
velvet hornet
#

I can tell you its not the "order of spawning of the tiles"

#

that shouldn't matter at all

stuck flower
#

I'm having an issue with mouse positioning involving isometric tiles. Specifically, when hovering over 3D isometric cubes, the mouse position feels offset or inaccurate compared to when hovering over tiles that are using square images

cube tile is 16x16 pixels
while the square is 16x8 pixels

#

i just noticed that cursor is not getting captured sadly

#

but in any case the first video mouse position isn't correct

#

isometric-grid (Square)

#

github here source code for anyone want to test to understand my problem

stuck flower
#

how can i offset each tilecell half it size visualy

#

as if i changed its origin from center to top

velvet hornet
#

selection that looks like it is selecting from the top of the tile?

#
let cursor_pos = Vec4::from((cursor_pos + Vec2::new(0., -4.), 0.0, 1.0));

you can offset the cursor's world position if you want to offset it like that

stuck flower
#

i have one more question i am trying to make a building game should i create another grid on top of the original grid to build on if so is there any example showcasing how to handle buildings that i like for example 2x2 2x1 or any sizes also if i have long tower for example how can i select tower not whats behind it if its a grid. i feel mouse selection that we are using wont work?

stuck flower
#

also is it possible to rely on ray casting because i feel ray casting is better overall but does that mean i have to have coilider on each entity.

velvet hornet
#

as for clicking "through" buildings, you'd have to allow the user to select which layer they meant to click or find some other way to ignore elements.

In your example, a player could place a 1 tile building behind that 2 tile building and the 1 tile building would be completely hidden, so you'll have to potentially figure out how to show that building anyway. (toggling visibility is possible, and using materials/custom shaders is also possible).

stuck flower
#

@velvet hornet I think I'll only need two layers in my game: one for the ground and another for the buildings. I don't want to deal with actual height differences right now. I'm trying to create a building system like in Age of Empires. The challenge is, this is my first game, and I'm not sure how people usually implement these systems. Do you have any resources or articles that explain this?

Another issue I'm facing is clicking and interaction. Should I track the mouse position, or should I use colliders? For example, a 2x2 building takes up more grid space (a larger footprint) than a 1x1 tile like a grass block. That's where I get confused—how can I design a grid system that handles different sizes efficiently?

Also, sorry to bother you—I'm new to Bevy, and it's been hard to learn so far.

rare bramble
stuck flower
#

@rare bramble What is that i didnt know there a powerfull package like that jEEZ thanks

#

ill play around and see how thing would work in my game

cold owl
#

I also have an AoE-like project using this crate so would be happy to see how you get the building UX working, whether by using the picking tilemap crate or not.

velvet hornet
sweet edge
#

Is there an easy way to find the offset of the overall map?

somber flame
#

how do i simply change a tile at position (x, y)?

#

can i query for a TileStorage and then do TileStorage.get(&tile_pos)?

#

how would i do this with multiple tilemap layers and chunks? like, what if i wanna do things in global space rather than local-to-chunk space?

unreal condor
#

The retained render world migration is pretty obnoxious. So many entity refs in this codebase. I think it's pretty unlikely that I'll find enough time to squash all the bugs before 0.15 releases.

#

(But everything in my branch is compiling and some examples sorta work, lol)

velvet hornet
#

unfortunate that it made it in so late in the cycle and needed the followups

#

I want to try to maintain a bevy_main branch during the 0.16 cycle

bleak scroll
#

@brisk path is it possible, somehow, to add support for rendering to 3D plane or something instead of 2D? I know this may sound weird, but my motivation here or my use case is that I have an Isometric 3D game that uses tile maps or 2D art for the environment (think ground, grass, trees, houses, bridges .. etc) in an Isometric way that appears to be 3D but it is in fact just 2D Sprite with transparent background (DDS, PNG .. etc).

Is something like that possible? If yes, please point me to these places in the code and I will do my best to get it to work.

bleak scroll
unreal condor
velvet hornet
#

the 0.15 release is out, I'm just writing up the release notes and putting the tag on the git release, etc and then I'll post about it

#

performance looks really good in 0.15 judging by our bench example. left is 0.15, right is 0.14

unreal condor
#

@velvet hornet https://github.com/StarArawn/bevy_ecs_tilemap/pull/580

Any feelings about this? I still have the same concerns as https://github.com/StarArawn/bevy_ecs_tilemap/issues/337#issuecomment-1381883272

I really don't love that users will have to do

let tile_size = TilemapTileSize { x: 16.0, y: 16.0 };
let grid_size = tile_size.into();
let in_world_tile_size = tile_size.into();

commands.entity(tilemap_entity).insert(TilemapBundle {
    // ... everything else
    tile_size,
    grid_size,
    in_world_tile_size,
});

This would be a breaking change anyway, so I'd like to carefully consider the API.

I suspect that combining these three components into a single TileSize { source, world, grid } with a TileSize::new(size) would feel pretty good, but I haven't tried it out yet.

velvet hornet
# unreal condor <@103513724052082688> https://github.com/StarArawn/bevy_ecs_tilemap/pull/580 An...

dont love the api. also some concerns about what feels like a vague use case that feels like it will likely lead to things like people wondering why their pixel art doesn't look like pixel art. camera scale also works for some of the use cases. I feel like we could come up with arbitrary potential use cases for this but I'd like to have something concrete to be supporting. Something that could be turned into an example ideally that isn't just "scale it up".

agree with comments about Transform::scale. Possible solution but setting scale values is kind of awkward as an end-user api.

scaling probably affects all math, including potential picking apis

iirc there was someone using 1px tiles and trying to scale them up to arbitrary sizes which doesn't feel like the use case.

on the other side, making art at the size that it needs to render is needlessly restrictive for people that don't have that requirement, and that makes mixing pre-built tilesets like kenney's and others together potentially awkward.

#

mostly I just want a concrete example for the examples folder so that we're clear about what we're supporting. arbitrary scaling doesn't seem particularly useful on its own in isolation.

unreal condor
unreal condor
#

oh wait, GH won't let me. Could have sworn that was possible at some point.

velvet hornet
#

yeah I didn't know if you'd be able to but I just left a review on it

stray lake
#

I am having issues with updating material tilemap handle in 0.15. 0.14 worked without issues. Took a while to figure out where the problem was located, but it seems when I am updating data of my custom shader for the tilemap, the screen flickers a lot. Seems to happen every time it is updated. So as you see in the video, it happens a lot in the beginning and then it completely stops. But every time it writes an update to it, a 1 frame black screen appears.

The code that writes to the shader:

pub fn handle_update_ref_image_event(
  mut er: EventReader<UpdateRefImageEvent>,
  mut material_query: Query<&mut MaterialTilemapHandle<TileMapBlendMaterial>>,
  mut materials: ResMut<Assets<TileMapBlendMaterial>>,
  mut images: ResMut<Assets<Image>>,
  map: Res<Map>,
  dt: Res<DayTracker>,
  mut ref_texture_image: ResMut<RefImageResource>,
) {
  er.read().for_each(|UpdateRefImageEvent(positions)| {
    if positions.is_empty() {
      return;
    }

    positions.iter().for_each(|pos| {
      let new_pixel = get_ref_texture_pixel(pos, &map, dt.season() == Season::Winter);
      ref_texture_image.0.put_pixel(pos.x as u32, pos.y as u32, new_pixel);
    });
    let image_handle =
      images.add(Image::from_dynamic(ref_texture_image.0.clone(), false, RenderAssetUsages::default()));

    let my_material_handle = materials.add(TileMapBlendMaterial {
      texture: image_handle,
      map_size: Vec2::new((map.map_width - 1) as f32, (map.map_height - 1) as f32),
    });

    let mut mat = material_query.single_mut();
    **mat = my_material_handle;
  });
}
velvet hornet
# stray lake I am having issues with updating material tilemap handle in 0.15. 0.14 worked wi...

might be worth noting that it looks like you're creating a new image and a new material and swapping the old material/image out every time the system runs. so this isn't really updating data so much as a complete swap and new image upload.

Is there a reason you aren't updating the image(/material) that is already in use?

either way, if you can reduce this to a minimal reproduction I'm happy to dig into it.

stray lake
somber flame
#

so this is my code for spawning tilemaps. how can i make it so my tiles are 1.0 x 1.0 in worldpsace? i'm not sure which variables to change.

#

right now, my 16x16 pixel tiles are 1:1 in worldspace. the chunks are 16 tiles across, so they are 256.0 x 256.0 in worldspace. i would like them to be 16.0 x 16.0 in worldspace units.

#

i think documentation is lacking. i would gladly contribute to bevy_ecs_tilemap's documentation! @velvet hornet, are you the project maintainer? co-maintainer? this "StarArawn" person doesn't have a matching discord username if they are here.

velvet hornet
somber flame
#

i use #![forbid(missing_docs)] in my codebase, so everything is documented. i'd urge bevy_ecs_tilemap to do the same, but i am aware that it is a lot of work. if need be, i would gladly go over the codebase and document everything.

brisk path
brisk path
# somber flame right now, my 16x16 pixel tiles are 1:1 in worldspace. the chunks are 16 tiles a...

why 16x16 in worldspace? the tiles are 16x16 pixels and typically with 2d a pixel will represent a single world space unit. There are a few ways around this though. You can:

  1. use grid size to change the tile positions to be 1x1 in size this will overlap tiles though as they wont scale
  2. Use the tile map's transform's scale which will scale each tile if you use 1.0 / 16.0 as the scale it'll scale everything down to 1x1 units.
  3. Lastly you can use the camera's transform to scale everything but this will scale all rendered game entities.
velvet hornet
somber flame
#

thanks though!

brisk path
#

there are helpers that do this

somber flame
#

every chunk has its own tilemap storage bc idk if there's a better way to do it. the example didn't help me. probably bc i didnt read it carefully.

brisk path
somber flame
#

yeah

#

well mostly infinite

brisk path
#

ahh yeah you'd have to have your own helpers to take chunk tile pos > world tile pos

somber flame
#

("mostly infinite" is kinda funny lolol)

#

yeah i was thinking of having GlobalTilePos

brisk path
#

I never added higher level chunk or layer support because honestly they're rather trivial to implement. Its just an entity that keeps track of "tilemap"(tile storage) entities.

somber flame
#

yeah

#

shouldn't the name be TilePos::from_local_pos()?

#

oh nvm, my bad. i thought the name was from_global_pos(), not from_world_pos() for a second.

brisk path
#

you should be able to take a look at the function and reuse the math there

#

its pretty basic

somber flame
#

yeah

brisk path
#

the only challenging part was hex/iso maps 😛

somber flame
#

well honestly i was just thinking of using from_world_pos() but subtracting the chunk size * the chunk coords from the position

brisk path
#

that'd work

somber flame
#

hex chunking sounds horrid to implement

#

just thinking about it makes me feel bad for anyone having to do it lol

brisk path
somber flame
#

my condolences man 🫂

unreal condor
#

I still want to continue the effort to improve the examples too though, probably going to be focusing on that personally.

earnest spruce
unreal condor
#

I wonder if we could make check_visiblity generic on VisibilityClass, and then if you want, you could just write your own system for your particular visibility class.

#

I haven't looked at the recent changes to this stuff closely enough to know if that makes sense

#

And it's not clear to me if it might harm perf to have serparate check_visiblity systems for the built-in classes.

unreal condor
earnest spruce
unreal condor
#

BTW bevy_ecs_tilemap people, we should really check in with a bevy-main tracking branch soon and see how cooked we already are for 0.16, lol.

velvet hornet
#

I can cut a 0.15.1 with what we've merged this week. I don't see anything in PRs that is pending for that, is there anything else you'd want to get in for 0.15.1 @unreal condor ? I might do a required components pr for that first

unreal condor
#

I don't know if any of the stuff I've done so far even warrants a patch release. I'd be okay with just waiting for required components if you're gonna do that.

velvet hornet
#

yeah I was mostly thinking if we're going to start making a bevy_main branch itd be nice to have a clean branch point. happy to wait for the rc work and then do it

bleak scroll
#

Hey, I've asked this before, but want to ask again, if I want to adopt this plugin to work for 3D, how hard would this be?

My use case is that my game has 3D for characters, mobs, NPCs, ..etc but for the other stuff like props it is 2D art design (see screenshots). Each part of this map is not actually a tile, instead it is a 256x256 DDS images as puzzle parts that needs to be placed together. My current method right here works well for small set of images, however in larger maps the game crashes OOM of wgpu. Each puzzle part (image) is just a plain 3d mesh plus a standard material with the image as the base_texture.

What I'm trying to understand if it is possible to levarage bevy_ecs_tilemap pluggin here, or even the core of it like caching and chunking in my case?

GitHub

Project Z: Learning gamedev with bevy engine and ECS - shekohex/projectz

velvet hornet
#

no changes needed to anything really

brisk path
#

You need to turn on depth buffers for 2d rendering. I think bevy has an option to do that now.

#

I'm also not sure if two cameras could share the same depth buffer.

#

probably

velvet hornet
#

yeah, and depth was added to the ecs_tilemap pipeline with the 0.15 upgrades

brisk path
velvet hornet
brisk path
#

by proper I mean high performant bevy_ecs_tilemap, last I checked which was a while ago, can't really utilize the depth buffer properly to avoid requiring iso tile chunks to be stored in tile rows. The whole goal of having a depth buffer was it didn't matter what order we drew the tiles at the end of the day the fragments would be properly sorted on the GPU.

#

This ofc comes with the downside of having issues with transparency specifically translucent sprites/tiles.

#

So you need OIT as well.

velvet hornet
#

there's an oit impl in bevy now, so theoretically could be referenced for 2d impl

bleak scroll
bleak scroll
velvet hornet
bleak scroll
bleak scroll
bleak scroll
velvet hornet
bleak scroll
pliant portal