bevy_ecs_tiled

repository·main·Indexed 41 days ago

https://github.com/adrien-bon/bevy_ecs_tiled

A Bevy plugin for loading Tiled maps (version 0.13.4) that integrates 2D tilemaps into an entity-based workflow. It supports Orthogonal, Isometric, and Hexagonal maps, mapping Tiled layers, tiles, and objects directly to Bevy entities. The plugin allows for data-driven game logic via Tiled custom properties, automatic physics collider spawning for engines like Avian or Rapier, and a structured entity hierarchy for efficient querying and transform propagation.

Tokens
26.1K
Snippets
67
Records
112
Agent score
48%

What's inside bevy_ecs_tiled

  1. Overview of bevy_ecs_tiled

    main
    bevy_ecs_tiled is a Bevy plugin designed for integrating 2D tilemaps created in the Tiled map editor into Bevy games. It uses rs-tiled for parsing map files and bevy_ecs_tilemap for high-performance rendering. The plugin handles the technical complexities of map loading, rendering, and entity management, allowing for a data-driven workflow.
  2. Use Text Objects and Group Layers in v0.12

    main

    Version 0.12 introduced support for Tiled text objects and hierarchical group layers:

    • Text Objects: Tiled text objects are spawned with TiledObjectText and TiledObjectTextBox components.
    • Group Layers: Hierarchical organization is supported. When working with layers or objects, use the get_layer_from_map() and get_object_from_map() helper functions, as they are designed to traverse group layers automatically.
  3. Understand Z-ordering for Tiled layers in Bevy

    main

    In bevy_ecs_tiled, the rendering order of layers is determined by an incremental Z offset applied to the layer hierarchy. This ensures that layers higher in the Tiled stack appear in front of lower layers in Bevy.

    The Z transform is calculated as follows:

    • Topmost layer (Tiled): Z transform = 0
    • Next layer down: Z transform = -1 × OFFSET
    • Subsequent layers: Z transform = -n × OFFSET

    By default, the OFFSET is 100. Using a sufficiently large offset is important to avoid rendering conflicts with bevy_ecs_tilemap chunks, which also apply small Z offsets.

  4. How Z-ordering works for objects on a layer

    main

    Objects placed on a Tiled layer inherit the Z offset of their parent layer. To prevent "Z-fighting" (flickering caused by identical Z values), bevy_ecs_tiled automatically applies a small, unique additional Z offset to each individual object within that layer.

    If you require precise Z-positioning for specific objects (e.g., for custom sorting or gameplay-driven depth), you should:

    1. Listen to map events to detect when objects are spawned.
    2. Manually adjust the Z transform of the object after spawning.
    3. Implement custom logic to set Z values based on object properties.
  5. Understand the Entity Hierarchy and Marker Components

    main

    When loading maps with bevy_ecs_tiled, the library spawns a structured parent/child hierarchy of entities. This organization allows for efficient querying using marker components and enables component inheritance (like Transform and Visibility) from parent entities down to their children.

    Hierarchy Structure

    • World (TiledWorld): The top-level entity when loading a .world asset. It contains the TiledWorldAsset and global settings.
    • Map (TiledMap): The top-level entity when loading a .tmx asset. In a Tiled world, multiple TiledMap entities exist as children of the TiledWorld.
    • Layers (TiledLayer): Children of the Map. Use the TiledLayer component to distinguish between layer types (e.g., Tiles vs. Objects).
    • Objects (TiledObject): Children of a TiledLayer::Object.
      • For TiledObject::Tile variants, the object entity has a child with a TiledObjectVisualOf marker, which holds the actual Sprite or TiledAnimation.
    • Tiles (TiledTile):
      • Under a TiledLayer::Tiles, there is one TiledTilemap per tileset used.
      • TiledTile entities are children of the TiledTilemap.
    • Physics Colliders (TiledColliderOrigin): Spawned as children of their source (either a TiledLayer::Tiles or a TiledObject). The source entity will have a TiledColliders component listing the attached colliders.
  6. How bevy_ecs_tiled works: Core Concepts

    main

    The plugin uses an Entity-Based Architecture to represent Tiled data within Bevy.

    • Hierarchy: Every Tiled item is a Bevy entity. Layers are children of the Map entity, while tiles and objects are children of their respective layers.
    • Automatic Propagation: Visibility and Transform properties are automatically propagated through this hierarchy.
    • Data-Driven Components: You can use Tiled custom properties to automatically insert custom Bevy components onto objects, tiles, or layers, allowing you to drive game logic directly from the Tiled editor.
    • Physics Integration: The plugin can automatically spawn colliders for tiles and objects using Rapier or Avian physics engines.
  7. Key features of bevy_ecs_tiled

    main

    The plugin provides several advanced features for tilemap management:

    • Map Types: Supports orthogonal, isometric, and hexagonal maps, including finite or infinite layers and various tileset configurations (external, embedded, atlases, or multiple images).
    • Tiled Feature Support: Integrates animated tiles, image layers, tile objects, and Tiled worlds.
    • Entity-Based Hierarchy: Every Tiled element (layers, tiles, objects) is a Bevy entity. Layers are children of the map entity, and tiles/objects are children of their layers. Visibility and Transform propagate through this hierarchy.
    • Physics Integration: Automatically spawns colliders for tiles and objects using either Rapier or Avian physics engines.
    • Data-Driven Workflows: Tiled custom properties can be automatically mapped to Bevy components on objects, tiles, or layers.
    • Hot-Reloading: Changes made in the Tiled editor are reflected live in the Bevy game without requiring a restart or recompile.
  8. Understand `TiledEvent<E>` context and helper methods

    main

    All bevy_ecs_tiled events are wrapped in a TiledEvent<E> structure. This wrapper provides essential context about the event's origin and includes helper methods to access related Tiled data. For instance, an event for a specific object will also provide access to the layer and map containing that object, allowing you to traverse the hierarchy easily.

    use bevy::prelude::*;
    use bevy_ecs_tiled::prelude::*;
    
    fn handle_event(
        mut object_events: MessageReader<TiledEvent<ObjectCreated>>,
    ) {
        // Even though we receive an event for a Tiled object,
        // we can retrieve information about the Tiled map
        for e in object_events.read() {
            let object_entity = e.origin;
            if let Some(map_asset) = e.get_map_asset() {
                info!("Received TiledEvent<ObjectCreated> for: '{:?}'", map_asset);
            }
        }
    }
  9. Integrate Physics and Colliders with Tiled Maps

    main

    The bevy_ecs_tiled ecosystem allows for automatic physics collider spawning based on map data. In the platformer example, this is used for:

    • Static Colliders: Spawning colliders for platform tiles and static objects.
    • Dynamic Colliders: Spawning colliders for moving entities like enemies and the player character.

    When using physics engines like Avian, you can leverage these colliders to trigger game logic events (such as teleportation or dead zones) when a player enters a specific zone defined in the map.

  10. Choosing between Tiled and LDTK for Bevy projects

    main

    When deciding whether to use bevy_ecs_tiled (which uses Tiled maps) or an alternative like bevy_ecs_ldtk, consider your map requirements:

    Use Tiled (bevy_ecs_tiled) if you need:

    • Isometric or Hexagonal maps: Tiled has native support for isometric layouts and hexagonal grids (including both "pointy-top" and "flat-top" orientations).
    • Animated tiles: Tiled includes built-in support for tile animations.
    • Advanced features: Like auto-tiling, custom properties for gameplay data, and multi-map world layouts.

    Use LDTK (bevy_ecs_ldtk) if you need:

    • Orthogonal maps only: If your project is strictly grid-based/orthogonal and you prefer a more modern editor interface, LDTK is a strong alternative.
  11. Integrate Tiled User Properties with Bevy Components

    main

    You can define game logic directly in the Tiled editor by attaching custom properties to objects. bevy_ecs_tiled automatically instantiates Bevy components on map load based on these properties.

    Workflow:

    1. Add marker components to objects in the Tiled editor (e.g., PlayerSpawnPoint, Enemy, PatrolRoute, or Trigger).
    2. The plugin automatically instantiates these components on the corresponding Bevy entities when the map is loaded.
    3. Implement game logic by using Bevy On<Add> observers or standard Query systems to react to these components.
  12. Custom property placement and Resource support

    main

    When using custom properties, keep these constraints in mind:

    • Tiles: To add properties to tiles, you must edit the tileset directly. You cannot add properties to the tileset itself.
    • Layers/Objects/Maps: Properties can be added to these elements normally.
    • Resources: You can define types that load as Bevy Resources, but they must be added as properties to the Map level. If you add a resource-type property to a layer or object, it will be ignored because resources are global and not attached to specific entities.