Git Product home page Git Product logo

bevy_tilemap's Introduction

Bevy Tilemap

Bevy Tilemap logo

Chunk based tilemap for Bevy game engine.

Bevy Tilemap allows for Bevy native batch-rendered tiles in maps to be constructed with chunk based loading, efficiently.

Simple yet refined in its implementation, it is meant to attach to other extensible plugins that can enhance its functionality further. Hand-crafted tilemaps with an attentive focus on performance, and low data usage.

WARNING

This project is still experimental and the API will likely break often before the first release. It uses an experimental game engine which too may break the API. Semantic versioning will be followed as much as possible and the contributors will as much as they possibly can try to keep the API stable.

If you have API suggestions, now is the time to do it.

Features

  • Perfect for game jams.
  • Easy to use and mostly stable API with thorough documentation.
  • Endless or constrained dimension tilemaps.
  • Batched rendering of many tiles.
  • Square and hex tiles.

Build Features

  • Serde support
  • Extra types

Design

This is not intended to be just another Tilemap. It is meant to be a framework and extensible by design, like Bevy. As well as work done to keep it as close to Bevy API as possible while keeping in mind of Rust API best practices. It is not meant to be complicated and created to be simple to use but give enough functionality to advanced users.

Less time fiddling, more time building

Usage

Add to your Cargo.toml file:

[dependencies]
bevy = "0.5"
bevy_tilemap = "0.4"

Simple tilemap construction

At the most basic implementation, there is not a whole lot that is required to get the tilemap going as shown below.

use bevy_tilemap::prelude::*;
use bevy::asset::HandleId;
use bevy::prelude::*;

// Build a default Tilemap with 32x32 pixel tiles.
let mut tilemap = Tilemap::default();

// We need a Asset<TextureAtlas>. For this example we get a random one as a placeholder.
let texture_atlas_handle = Handle::weak(HandleId::random::<TextureAtlas>());

// Set the texture atlas for the Tilemap
tilemap.set_texture_atlas(texture_atlas_handle);

// Create tile data
let tile = Tile {
    // 2D location x,y (units are in tiles)
    point: (16,16),
    
    // Which tile from the TextureAtlas
    sprite_index: 0,
    
    // Which z-layer in the Tilemap (0-up)
    sprite_order: 0,
    
    // Give the tile an optional green tint
    tint: bevy::render::color::Color::GREEN,
    };

// Insert a single tile
tilemap.insert_tile( tile);

Of course, using the Tilemap::builder() this can be constructed with many more advanced features.

  • 3D and 2D tilemaps.
  • Texture atlas.
  • Dimensions of the tilemap.
  • Dimensions of a chunk.
  • Dimensions of a tile.
  • Adding Z render layers
  • Automated chunk creation.
  • Auto-spawning of tiles based on view.

With many more features planned for future updates to bring it up to par with other tilemap implementations for other projects.

Future plans

There is still a lot to do but the API is now stable and should be fine for a while now. The next release is focused on added automated methods and system.

  • Auto-tile: Picks the right tile based around the neighbours of the tile.
  • Tile import: Imports tiles from a file from multiple formats.

Building

bevy_tilemap is only guaranteed to work from stable Rust toolchain and up. This is to be inline with the rest of Bevy engine.

Once you have a development environment, Bevy Tilemap can be fetched using git:

$ git clone --recursive https://github.com/joshuajbouw/bevy_tilemap/

and then built using cargo:

$ cargo build --example random_dungeon

cargo can also be used to run tests:

$ cargo test

bevy_tilemap's People

Contributors

adamwhitehurst avatar alec-deason avatar arbrog avatar b-reif avatar blamelessgames avatar brettwitty avatar comet-flare avatar darthdeus avatar dependabot[bot] avatar inodentry avatar joshuajbouw avatar lamakaio avatar solarsail avatar stararawn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

bevy_tilemap's Issues

Hex isn't aligned perfectly on the Y-axis

Tilemap v. 0.4, master branch, Windows 10.

Run the random_world example and it ever so slightly is not centred on the Y-axis. Slightly down a few pixels. I'm not entirely sure as nothing is obvious as to why this is. For those that use the hex part of the library, I would love feedback and help on this.

It most certainly is an issue with the shader itself. I do not believe anything is overlapping. Could be a rounding issue.

Hexagonal tile support

Support hexagonal tiles, so that this crate can be used to make efficient rendering for games with maps based on hexagons.

Background stopped updating on examples

Bevy version

Master

Operating system & version

Windows 10

What you did

Ran the examples to see how they are with latest Bevy 0.4 release. Background is failing to render when moving the character.

What you expected to happen

For the background to correctly render under the dwarves.

What actually happened

The background didn't render.

Panic when respawning a chunk with collisions

Bevy Tilemap version

Git master

Operating system & version

Ubuntu 20.04
Note : I have a slightly modified version of bevy_tilemap, it should not have any impact on this bug.
Edit : tested on master, same issue.

What you did

It seems that respawning a chunk with collisions that was previously despawned (using the auto_spawn feature) panics with
thread 'main' panicked at 'called 'Result::unwrap()' on an 'Err' value: NoSuchEntity', /home/timo/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_transform-0.4.0/src/hierarchy/child_builder.rs:65:22

The panic seem to be in the push_children command, probably the one used in spawn_collisions, where the chunk entity doesn't exist.

I tried to force the collision system to run after the tilemap system, it did not fix it.
Here is a slightly modified version of the physics_dungeon example where the bug can be seen. You just have to go far in one direction then come back for the crash to happen.
physics_dungeon.txt

Arbitrary data attached to tile

What problem does this solve or what need does it fill?

In games, tiles often need to store extra data. For example, in Minecraft, blocks have block states and block entity data.

Describe the solution would you like?

I would like Tilemap and Tile to be generic over T, allowing us to attach additional data T to each Tile. This could be something like this:

struct Tile<T> where T: ... {
    ...
    data: T,
}

Describe the alternative(s) you've considered?

While this could be stored separately, it would require implementing an additional system that functions pretty much identically to the existing Tilemap for spawning / despawning / etc.

How to update a single tile during gameplay?

I'm trying to develop a terrain generation system for a strategy game that may include seasons or other changes to tiles, I've been experimenting for a few days and haven't found a way to do this.

Chunks despawn when moving camera

Bevy Tilemap version

commit: 474bd2f

Operating system & version

Ubuntu 20.04

What you did

Modified hex_tile_odd_rows example to allow panning and zooming (re-scaling).

What you expected to happen

The view can be panned/zoomed, and the map remains static.

What actually happened

All chunks except (0,0) de-spawned immediately.

Additional information

bevy_tilemap_camera_chunks_bug

[Docs] Unit of measure for Tilemap dimensions

From the docs for Builder dimensions, it's not clear what units the dimensions are in. This could potentially be a number of tiles, a number of chunks, or even a number of pixels.

It would help to annotate this method with the unit it's expecting. Since this library expects a variety of different measures in various methods, it could also help to introduce newtypes to describe sizes and units of measure.

EDIT: From the source comments, it looks like it's measured in chunks.

Eliminate separate examples crate

What problem does this solve or what need does it fill?
The examples crate notes that being a separate crate was a constraint of using Bevy 0.4. Now that we are on Bevy 0.5, can we move the examples into the standard location so you can run cargo run --example at the repository root?

Describe the solution would you like?
Eliminate examples crate and add examples to top level Cargo.toml

Describe the alternative(s) you've considered?
N/A

Additional context
N/A

Ability to calculate the tile on-screen position

What problem does this solve or what need does it fill?

Right now, the crate forces you to let it render all of the objects on the tilemap itself. However, this isn't flexible - for example, currently animations aren't supported. There needs to be an ability to render parts of it yourself (sorry if such a solution is in the crate already, I couldn't find it). There's also a much more fundamental issue - not knowing the tile coordinates makes you unable to react to mouse clicks properly

Describe the solution would you like?

An API for getting tile positions, similar to the vertex shaders but in rust.

Describe the alternative(s) you've considered?

Adding all of the features users would possibly want to the Tile struct, possibly bloating it.

Compiler error with latest master (rendering apis)

On the latest git master (of both bevy and bevy_tilemap), as of today:

error[E0432]: unresolved imports `bevy_render::pipeline::BlendDescriptor`, `bevy_render::pipeline::ColorStateDescriptor`, `bevy_render::pipeline::DepthStencilStateDescriptor`, `bevy_render::pipeline::RasterizationStateDescriptor`, `bevy_render::pipeline::StencilStateDescriptor`, `bevy_render::pipeline::StencilStateFaceDescriptor`
   --> bevy_tilemap/src/lib.rs:201:13
    |
201 |             BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite,
    |             ^^^^^^^^^^^^^^^                               ^^^^^^^^^^^^^^^^^^^^ no `ColorStateDescriptor` in `pipeline`
    |             |
    |             no `BlendDescriptor` in `pipeline`
    |             help: a similar name exists in the module: `BindingDescriptor`
202 |             CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, PipelineDescriptor,
    |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `DepthStencilStateDescriptor` in `pipeline`
203 |             PrimitiveTopology, RasterizationStateDescriptor, RenderPipeline, RenderPipelines,
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `RasterizationStateDescriptor` in `pipeline`
204 |             StencilStateDescriptor, StencilStateFaceDescriptor,
    |             ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^^^ no `StencilStateFaceDescriptor` in `pipeline`
    |             |
    |             no `StencilStateDescriptor` in `pipeline`

error[E0560]: struct `bevy_render::pipeline::PipelineDescriptor` has no field named `rasterization_state`
  --> bevy_tilemap/src/chunk/render/mod.rs:12:17
   |
12 |                   rasterization_state: Some(RasterizationStateDescriptor {
   |                   ^^^^^^^^^^^^^^^^^^^ `bevy_render::pipeline::PipelineDescriptor` does not have this field
...
58 | / build_chunk_pipeline!(
59 | |     CHUNK_SQUARE_PIPELINE,
60 | |     2110840099625352487,
61 | |     build_chunk_square_pipeline,
62 | |     "tilemap-square.vert"
63 | | );
   | |__- in this macro invocation
   |
   = note: available fields are: `name`, `layout`, `shader_stages`, `primitive`, `depth_stencil` ... and 2 others
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0560]: struct `bevy_render::pipeline::PipelineDescriptor` has no field named `color_states`
  --> bevy_tilemap/src/chunk/render/mod.rs:20:17
   |
20 |                   color_states: vec![ColorStateDescriptor {
   |                   ^^^^^^^^^^^^ `bevy_render::pipeline::PipelineDescriptor` does not have this field
...
58 | / build_chunk_pipeline!(
59 | |     CHUNK_SQUARE_PIPELINE,
60 | |     2110840099625352487,
61 | |     build_chunk_square_pipeline,
62 | |     "tilemap-square.vert"
63 | | );
   | |__- in this macro invocation
   |
   = note: available fields are: `name`, `layout`, `shader_stages`, `primitive`, `depth_stencil` ... and 2 others
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0560]: struct `bevy_render::pipeline::PipelineDescriptor` has no field named `depth_stencil_state`
  --> bevy_tilemap/src/chunk/render/mod.rs:34:17
   |
34 |                   depth_stencil_state: Some(DepthStencilStateDescriptor {
   |                   ^^^^^^^^^^^^^^^^^^^ help: a field with a similar name exists: `depth_stencil`
...
58 | / build_chunk_pipeline!(
59 | |     CHUNK_SQUARE_PIPELINE,
60 | |     2110840099625352487,
61 | |     build_chunk_square_pipeline,
62 | |     "tilemap-square.vert"
63 | | );
   | |__- in this macro invocation
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

GLSL shaders

What problem does this solve or what need does it fill?
Right now everything is done with the CPU which is very much not ideal. These are textures after all and should be handled and buffered on the GPU.

Describe the solution would you like?
Have something similar to UBO Tilemap / Amethyst for bevy_tilemap.

Describe the alternative(s) you've considered?
n/a

Additional context
https://github.com/olsonjeffery/gfx/tree/master/examples/ubo_tilemap
https://github.com/amethyst/amethyst/tree/master/amethyst_tiles

(thanks pfox for the inspiration)

Update physics API and example

What problem does this solve or what need does it fill?
Rapier physics integration is very valuable, but the current API and examples do not use the latest API, and physics_dungeon is broken.

Describe the solution would you like?
Use the latest Rapier API including:

  • Using RigidBody and Collider components rather than RigidBodySet

Describe the alternative(s) you've considered?
Removing the physics example while non-functional?

Additional context
N/A

A few more small, instructive examples

What problem does this solve or what need does it fill?

A number of small examples to demonstrate the library just a bit further for newbies. It also will demonstrate your suggested solution to some common problems.

Describe the solution would you like?

Example code for the following situations:

  • Scrolling map: Something like the random_dungeon.rs, but for a map that is larger than 1 screen. Scrolling could be discrete or continuous.
  • Tinting: Tint the map between a few colours.
  • Scaling tiles uniformly: 16x16 tiles being presented as 32x32.
  • Zooming: Scaling the map in and out.
  • Benchmarks: Demonstrating the impact of dense vs sparse layers, or sizes of chunks (too big vs too small)

Describe the alternative(s) you've considered?

I have trouble finding other people's code using bevy_tilemap.

Tile Transforms

Right now TileMaps can have a local and global transform, but it seems to apply to the whole tilesheet. It would be useful, for animations or effects to be able to control the transform of each Tile as well to enable rotations, scaling, and other arbitrary distortions.

Background and Foreground sprites

What problem does this solve or what need does it fill?

Currently, there isn't a way to have textures placed on top of each other in a foreground / background method.

Describe the solution would you like?

Methods need to be added that fits in with the tiles and rest of the API that allow for foreground and background tiles.

Describe the alternative(s) you've considered?

n/a

Additional context

n/a

Layer Offset may not be working correctly

Bevy Tilemap version

0.4.0

Operating system & version

Windows 10

What you did

Tried to offset a tile layer to make tiles appear 3D using z_layers, add_layer, and layer_offset.

What you expected to happen

Two things:

  1. Originally I thought that each subsequent tile layer after the first would be offset by the amount specified in layer_offset, but then I thought ...
  2. Wouldn't the layer_offset just offset all layers as it is only a single value on the Tilemap, therefore the whole map would be offset and not individual layers? - is there a way to offset a single layer? Like on the add_layer function?

What actually happened

Nothing was offset.

image

Additional information

This was tested on an alteration of your Hex Tile Odd Rows example.

The only alterations being that I changed the hex to a 3d one and used just a single chunk.

As well as the below code.

image

image

I'm sorry if I'm getting something obviously wrong here, I've tried reading the doc comments on the function calls but I couldn't find any examples in the repo that used layer_offset.

Thanks for any help you might have, you've created an excellent extensible plugin here.

Tile flip flags

What problem does this solve or what need does it fill?
Right now, a tile only faces in the same direction as the image itself. It would be a huge improvement to be able to flip axis or even rotate!

Describe the solution would you like?
In the map system when placing the textures on the chunk check for X, Y, XY, YX etc. flags and iterate over the image as such placing in the correct orientation on the map.

Describe the alternative(s) you've considered?
n/a

Additional context
n/a

Handle zoom?

What problem does this solve or what need does it fill?

It'd be very nice for tilemap to handle (arbitrary, smooth) map zoom in addition to panning.

Describe the solution would you like?

As I see in the examples, panning is accomplished by manipulating the 2d camera translation directly. It happens that zoom in 2d works by scaling everything rather than moving the camera. It would be nice (but not essential) for this to all be accomplished in one interface.

(Super awesome bonus: smooth pan/zoom where you give target values and a system updates them over a number of frames.)

Describe the alternative(s) you've considered?

Coding it all myself rather than working on my actual game stuff. :)

Support 3D

What problem does this solve or what need does it fill?

Would be great to be able to use this library for procedurally generated 3D worlds.

Describe the solution would you like?

Same easy to use API, but 3D :)

WebGL Support

What problem does this solve or what need does it fill?

Currently, building bevy_tilemap with bevy_webgl2 using the bevy_webgl2_app_template does not work. This means that bevy_tilemap does not support webGL/WASM targets.

Link to failed build output dump: https://pastebin.com/8QzYPskv

A description of why this particular feature should be added

With WASM support being a large feature of Bevy and Rust's core principles, it should follow that bevy_tilemap should also be able to support WASM.

The solution you propose for the problem presented

bevy_tilemap should not import the entirety of bevy crate, rather it should only import what it needs based on flags in the cargo.toml

Question: How can I know which position is clicked by the player ?

It's just a question (but could be turn to be a feature request):

In my game the player can interract with the background. So I need to know which position/tile is clicked.
Is there a way in tilemap to give a screen coordinate (or a world coordinate) and get the matching position/tile ?

by the way thanks for this amazing crate !

Flickering edges during zoom/pan

Bevy Tilemap version

bevy = "0.5"
bevy_tilemap = "0.4.0"

Operating system & version

Ubuntu 20.04

What you did

  1. Created a 30x30 hex tile map
  2. Modified transform.scale of the 2d camera (zoomed out)
  3. Modified transform.translation of the 2d camera (panned)

What you expected to happen

No flickering lines along the edge of textures.

What actually happened

Observed white, flickering lines, mainly along left edge of tiles

Additional information

I've tried:

  • Modifying sampler properties of loaded textures (min_filter etc.)
  • Modifying pan to only move by multiples of the current scale
  • Changing GridTopology

The only thing that's had a major effect has been changing pan. Panning by whole numbers removes the lines at scale=1.0. Panning by a multiple of the scale removes the lines at scale=1.0 and stops the flicker at other scales, but doesn't remove the lines.

bevy_tilemap_flickering_edge

Interactive example

What problem does this solve or what need does it fill?

Currently there is no interactive example.

Describe the solution would you like?

What I would like done is for that example to be created with multiple chunks, scrolling screen, and a moving character! This will absolutely show the power of this library.

Describe the alternative(s) you've considered?

n/a

Additional context

n/a

Examples not working?

Hi,

I tried cloning this to run the examples:

nous% git clone --recursive https://github.com/joshuajbouw/bevy_tilemap/

But getting errors:

% cargo build --example random_dungeon
   Compiling bevy_tilemap_types v0.4.0 (/home/mark/projects/rust/bevy_tilemap/library/types)
error[E0432]: unresolved import `bevy::render::texture::Extent3d`
  --> library/types/src/lib.rs:36:9
   |
36 |         render::texture::Extent3d,
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ no `Extent3d` in `texture`

error[E0283]: type annotations needed
   --> library/types/src/dimension.rs:198:14
    |
198 |         impl From<&$vec> for Dimension2 {
    |              ^^^^^^^^^^^ cannot infer type for struct `Dimension2`
...
206 | dimension2_glam_impl!(Vec2);
    | --------------------------- in this macro invocation
    |
    = note: cannot satisfy `Dimension2: std::convert::From<&bevy::prelude::Vec2>`
note: required by a bound in `std::convert::From`
    = note: this error originates in the macro `dimension2_glam_impl` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0283]: type annotations needed
   --> library/types/src/dimension.rs:198:14
    |
198 |         impl From<&$vec> for Dimension2 {
    |              ^^^^^^^^^^^ cannot infer type for struct `Dimension2`
...
207 | dimension2_glam_impl!(Vec3);
    | --------------------------- in this macro invocation
    |
    = note: cannot satisfy `Dimension2: std::convert::From<&bevy::prelude::Vec3>`

And much more like this.

Versions:

% cargo version
cargo 1.57.0 (b2e52d7ca 2021-10-21)
% rustc --version
rustc 1.57.0 (f1edd0429 2021-11-29)

Any ideas what might be going wrong here?

Add auto tile features

What problem does this solve or what need does it fill?
Auto tile is immensely awesome with tile sets where you can have natural looking maps.

Describe the solution would you like?
The auto tile feature needs to be set so that the tiles when made know their tile neighbours and pick the correct sprite to create beautiful looking maps.

Describe the alternative(s) you've considered?
n/a

Additional context
n/a

Indicate how to have multiple texture atlases

What problem does this solve or what need does it fill?

As a new user of the library it was not clear if it is possible to have multiple texture atlasses at all, and while #7 indicates that users are supposed to solve this by using multiple tilemaps, that issue is not super easy to find.

Describe the solution would you like?

A note in the readme or somewhere else visible feels like the easiest and clearest way to inform the users how to achieve this.

Describe the alternative(s) you've considered?

Adding a note to some other place, like a wiki if this project gets one.

Additional context

none

Event is not automatically added

Bevy Tilemap version

0.4.0

What you did

In Bevy 0.5, the following pattern should work:

pub fn chunk_event_handler(mut reader: EventReader<TilemapChunkEvent>) {
    for event in reader.iter() {
        match event {
            TilemapChunkEvent::Spawned { point } => {
                println!("Spawned point: {:?}", point);
            },
            _ => (),
        }
    }
}

However, we get:

Requested resource does not exist: bevy_app::event::Events<bevy_tilemap::event::TilemapChunkEvent>

Perhaps the TilemapPlugin does not call app.add_event::<TilemapChunkEvent>()?

Minimap support?

What problem does this solve or what need does it fill?

Showing a minimap view with more context (but possibly simplified textures, or simply blocks instead of textured tiles) is pretty common in games. It'd be nice for this library to automatically support it.

Describe the solution would you like?

Ability to present a minimap

  • of arbitrary pixel dimenisions
  • mapped to a greater extent than displayed on screen
  • chunks updated in this area, of course
  • option for alternate texture atlas for mini versions

Describe the alternative(s) you've considered?

Could be done separately, but it seems like deep integration is actually really useful here

Issues while using this library for the first time

Currently I am evaluating bevy and the 3rd party plugins and have been toying around with bevy_tilemap as well. Unfortunately I had many issues to get up and running in the first place that I wanted to leave a feedback to make you aware of them:

  1. The section "Simple tilemap construction" is misleading as the code in there is outdated and the set_tile method no longer existing. Only by studying the square tile example I was able to deduce how to generate a tilemap myself.
  2. Speaking of that example, both your example and the one from the original bevy repository are needlessly complex when building a texture atlas. I do understand it's possible and nice to dynamically build an atlas of existing textures, but this is introducing serious cognitive overhead - especially with bevy being barely documented to begin with. I would've appreciated working with a single texture in the example that contains 2-3 different tiles already just to be able to focus on using bevy_tilemap itself rather than distinguishing bevy features and patterns itself.
  3. Generating new Tiles and adding them with Tilemap::insert_tiles caused me some headaches since the point member is apparently in tile units (and the dimensions of the tilemap in chunks rather than tiles). Units of measurement are pure guesswork and not documented properly.
  4. Even more confusing is that I haven't found any indication about the tilemap grid orientation whatsoever. You can imagine me being surprised that the map I have defined was suddenly growing towards the top-left (due to the grid using a classic cartesian coordinate-system with the origin being in the bottom-left rather than top-left for example) making it slightly more annoying to build a tilemap that is naturally built and flowing towards the bottom-right. Therefore when reading a map from a file I have to build the tilemap in a non-natural way and logical tile coordinates (like 2nd row, 3rd column) don't map nicely to their actual position in the tilemap since it may be something like (31, 3).

Example of spawning off-screen chunks

I'm prototyping a concept where the overmap is much larger than the visible map, and is made up of chunk types. Some distance from the map edge, I want to generate adjacent chunks off-screen, add them to the map, and potentially spawn in enemies/items/etc. I'd like to spawn chunks a bit away from the character, to allow for things like enemy troops to spawn a chunk or two away and advance on the player's position if they are detected. So it wouldn't be just-in-time, but maybe a screen or two of tiles.

Is there an example of this? I'm not thinking it has to be complex--just take the random world example and spawn in adjacent off-screen chunks.

In the meantime, I'm curious about how this currently works. Does autospawn just handle creating the chunks for me from a group of tiles, or does it detect when the camera is about to move off-screen and create a new chunk? I'm not sure whether the current chunk events are meant to tell me that I should run my map generators and create/add a chunk myself, or if it's up to me to detect when a new chunk is needed and do that myself.

Thanks.

Add support for minimum rust version in Cargo.toml

What problem does this solve or what need does it fill?

Minimum rustc versions should be specified by crates but there isn't any way to do this yet.

Describe the solution would you like?

rust-lang/rust#65262 has yet to be implemented. When it is stable, it should be added in. For now, everyone must documentation on how to build.

Tilemap not spawned until window is resized

Bevy Tilemap version

0.4

Operating system & version

Windows 10

What you did

Created a tilemap:

let mut tilemap = BevyTileMap::builder()
        .texture_atlas(atlas)
        .dimensions(24, 12)
        .chunk_dimensions(64, 64, 1)
        .auto_chunk()
        .texture_dimensions(16, 16)
        .auto_spawn(200, 200)
        .add_layer(
            TilemapLayer {
                kind: LayerKind::Dense,
            },
            0,
        )
        .finish()
        .unwrap();

Then added tiles using a loop (used println! to ensure loop was run). A iter of tiles is generated from these:

Tile {
    point: (x as u32, y as u32),
    sprite_index,
    ..Default::default()
}

The collected tiles are added to the tilemap:

 tilemap
        .insert_tiles(tiles)
        .expect("Unable to generate tilemap from tilemap data");

and then a TilemapBundle is created:

TilemapBundle {
    tilemap,
    visible: Visible {
        is_visible: true,
        is_transparent: true,
    },
    transform: Default::default(),
    global_transform: Default::default(),
}

What you expected to happen

Entire tilemap should be rendered.

What actually happened

The tilemap is built and component bundles spawned (verified by println!), but nothing is spawned until the window is resized.

Apr 14 22:41:39.174  INFO bevy_tilemap::system: Chunk (0, 0) spawned

XcHioc7Fw3

Additional information

This is intermittent, maybe 25% of runs?

Here is an extracted repo - https://github.com/will-hart/tiles. Run the example with cargo run --example editor.

Sparse and dense layers

What problem does this solve or what need does it fill?
Right now there is a single layer that is dense using Options. To reduce CPU cost, there should be different layers of sparse or dense maps. That way when updating, the sparse tile map can be cheaply updated.

Describe the solution would you like?
Add in different kinds of layers and a layer system in chunks.

Describe the alternative(s) you've considered?
n/a

Additional context
https://www.reddit.com/r/rust/comments/jntjp8/with_the_launch_of_bevy_game_engine_03_im/gb3u25f?utm_source=share&utm_medium=web2x&context=3

no_implicit_prelude does not work at crate level

Opened to track rust's fix.

no_implicit_prelude is handy if you want to know exactly what you are using in your library, allowing you to slim it down later as you typically have all your new prelude imports altogether. Cuts down on code as well, cleaning things up drastically.

The issue is that #![no_implicit_prelude] at lib level used to work fine. Then Serde support was added and it wouldn't build Serde since it too uses no_implicit_prelude. There was a work around though which worked. Problem is, now that workaround is broken. While the project will build fine, this is problematic for documentation.

See: rust-lang/rust#80372

Temp workaround: #83

Quality of Life Improvements for Procedural Tilemap Generation

What problem does this solve or what need does it fill?

The following list of features is designed to address some Quality of Life challenges the current implementation has for dealing with procedurally generated tilemaps of potentially enormous size.

  1. TilemapChunkEvent Spawn & Despawn currently only include the point which triggered a spawn/despawn and not the extents of the chunk or wether or not the chunk was loaded back into the tilemap from cache.
  2. Tilemap should optionally call a populate method on a trait object or call a function pointer with a provided user data reference such that when a new chunk not in cache is needed, the method can be called such that the chunk can be populated.

Describe the solution would you like?

  1. Adding some metadata to the TilemapChunkEvent.
pub enum TilemapChunkEvent {
    Spawned {
        point: Point2,
        extents: (Point2, Point2),
        cached: bool,
    },
    Modified {
        point: Point2,
        extents: (Point2, Point2),
    },
    Despawned {
        point: Point2,
        extents: (Point2, Point2),
    },
    AddLayer {
        layer_kind: LayerKind,
        sprite_layer: usize,
    },
    RemoveLayer {
        sprite_layer: usize,
    },
}```

2. Add an Option<TilemapPopulator> parameter to TilemapBuilder::auto_spawn() 

```rust
pub trait TilemapPopulator {
    fn populate(tilemap: &mut Tilemap, extents: (Point2, Point2))
}

pub fn auto_spawn(self, width: u32, height: u32, populator: TilemapPopulator) -> Self {/* ... */}

Describe the alternative(s) you've considered?

Using the existing event system with a is_none check for a point in the spawned chunk.

Support multiple Tilesets

What problem does this solve or what need does it fill?
It is ideal not to just use a single tileset but to actually define which tileset to use per tile. They MUST be identified by a integer and not a Handle to reduce cost of bytes per tile.

Describe the solution would you like?
This is mostly a Tile implementation level feature. There should be logic that has a HashMap at the Tile Map level of all handles and then the Tiles simply reference the index location.

Describe the alternative(s) you've considered?
n/a

Additional context
https://www.reddit.com/r/rust/comments/jntjp8/with_the_launch_of_bevy_game_engine_03_im/gb3u25f?utm_source=share&utm_medium=web2x&context=3

Examples/documentation for single chuck map with origin in corner

What problem does this solve or what need does it fill?

People following tutorials (such as the Rust Roguelike Tutorial) may not have a clear grasp of how chunking helps with map management, or how to convert between the coordinate system used in the tutorial to the one used by Tilemap.

Looking at the existing examples and documentation, I think the following are unclear without delving into the code itself:

  • The relationships between map, chunk, and texture dimensions.
  • Guidance on choosing a chunk size and how many to spawn initially.
  • How to work out the dimensions I need for a map that just fills particular screen or window size.

Most tutorials I've seen start with the following constraints:

  • A small, self-contained map (something like 10x10 or 80x50)
  • An origin in the top left or bottom left corner of the map (for simple conversion between tile coord and index into a vector).

These constraints get gradually lifted in later chapters or tutorials, of course, but the initial constraints make it easy to focus on learning the basics of movement, collisions, working with tiles, etc.

I think a simple example that follows these constraints, coupled with some documentation to help people understand when and how to use chunks for map management, would make this a simple transition for people following or adapting tutorials.

I don't know if this is better served with a more carefully annotated random_dungeon or a new tutorial_dungeon example that is closer to the old, single-chunk version of random_dungeon (but with an origin in the corner).

Massive bevy_tilemap overhaul

It has come to really overhaul bevy_tilemap to be the generics that I wanted it originally to be. This will also create the pieces needed to create tilemap2d and tilemap3d. What the whole goal of this overhaul will be to absolutely preserve the API as much as I can while making it robust enough to create a 3D version of the library. This will also produce the tools, primitives, and generic traits to make your own custom tilemap from the tiles to the chunks and engine.

  • Make generic traits which can work without the Tilemap struct.
  • Recreate the Tilemap as Tilemap2D
  • Create Tilemap3D

Add in system that handles on-screen / off-screen spawning / despawning

What problem does this solve or what need does it fill?
This wasn't really meant to originally be a system of the library but I understand why most would want it, including myself, to be in the library. Its meant to fill the need of a crate level system that is able to do the spawning and despawning logic of the chunks.

Describe the solution would you like?
There should be a system that handles a camera's position with screen dimensions that will easily spawn and despawn chunks as they come in and out of existence.

Describe the alternative(s) you've considered?
n/a

Additional context
https://www.reddit.com/r/rust/comments/jntjp8/with_the_launch_of_bevy_game_engine_03_im/gb3u25f?utm_source=share&utm_medium=web2x&context=3

Example use with LDtk

What problem does this solve or what need does it fill?
An example integration with LDtk would be excellent. Folks wanting to use LDtk output would be able to get things integrated a bit more quickly.

Describe the solution would you like?
A simple example showing how to load & use an LDtk map.

Describe the alternative(s) you've considered?
N/A (maybe using another crate, but this one seems to be one of the best, and has all of the building blocks needed)

Additional context
Just looking for a quick way to load and use an LDtk map.

Control over texture filtering mode? Mipmap support?

I want to have nice quality downscaling, to support "zooming out" the camera (increasing the scale). The current rendering looks ugly (looks like the filtering is probably nearest neighbor with no mipmaps). I want to have control over this, so that my tilemaps can look nice when scaled down.

memory leak when updating tiles?

Bevy Tilemap version
0.4

Operating system & version
MacOS 11.3

What you did
tried to update tiles using Tilemap.get_tile_mut(..)

What you expected to happen
expected the memory usage to remain flat (~80 MB)

What actually happened
memory usage slowly grows and grows (2 GB and counting), visually looks correct.

Additional information
if i comment out the single line of code that does the modification, the memory issue goes away.

Collision improvements

Collisions right now are handled in the tilemap_system directly but, it would be ideal to have it in its own system. Since rapier2d physics is not part of bevy core library, it is also best to pull out all rapier collisions into its own feature and make it optional. Likewise, there should be a way to handle 2D old school tile collisions using rapier though this is not a priority. Further it has been recommended to me to provide access to collision user_data as it is there, might as well use it.

  • Separate out rapier into its own feature
  • Separate rapier collisions from tilemap_system and move to tilemap_collision_system
  • Potentially give access to the underlying collision data

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.