reckfellENGINE

TileSet: atlas, collision and tile data

Create two tiles, define wall physics and reuse the resource across map layers.

On this page

Separate resource and map

TileSet defines available tiles and their meaning: imagery, collision shapes and custom data. TileMapLayer stores cells referencing that resource. Editing a tile in a shared TileSet affects every cell using it; store individual cell state separately.

The example has two 16×16 tiles: floor and a blue wall. Only the wall has a physics contour. The walkable=true/false values are metadata for your code, not automatic navigation or collision configuration.

Create the complete resource in code

Use Reckfell.NET.Sdk 1.0.0 and net10.0. Save ExampleTileSet.cs below. For a runnable level, add TileWalker.cs and TileLevel.cs from the map guide, run dotnet build and attach TileLevel.cs to an Entity2D root in a .rscene level.

Code generates the 32×16 atlas; no external artwork is needed. The corresponding editor concepts are texture selection, region size and tile creation; this example does not verify the exact editor interactions.

ExampleTileSet.cs
C#
using Reckfell;

public static class ExampleTileSet
{
    public const int SourceId = 0;
    public static readonly Vector2I Floor = new(0, 0);
    public static readonly Vector2I Wall = new(1, 0);

    public static TileSet Create()
    {
        using var image = Image.CreateEmpty(32, 16, false, Image.Format.Rgba8);
        image.Fill(new Color(0.12f, 0.14f, 0.18f));
        image.FillRect(new Rect2I(1, 1, 14, 14), new Color(0.17f, 0.19f, 0.23f));
        image.FillRect(new Rect2I(16, 0, 16, 16), new Color(0.2f, 0.38f, 0.9f));
        image.FillRect(new Rect2I(17, 1, 14, 3), new Color(0.4f, 0.57f, 1));
        var atlas = new TileSetAtlasSource
        {
            Texture = ImageTexture.CreateFromImage(image),
            TextureRegionSize = new Vector2I(16, 16)
        };
        var tiles = new TileSet { TileSize = new Vector2I(16, 16) };
        tiles.AddPhysicsLayer();
        tiles.SetPhysicsLayerCollisionLayer(0, 1);
        tiles.SetPhysicsLayerCollisionMask(0, 1);
        tiles.AddCustomDataLayer();
        tiles.SetCustomDataLayerName(0, "walkable");
        tiles.SetCustomDataLayerType(0, Variant.Type.Bool);
        tiles.AddSource(atlas, SourceId);
        atlas.CreateTile(Floor);
        atlas.CreateTile(Wall);
        atlas.GetTileData(Floor, 0).SetCustomData("walkable", true);
        var wall = atlas.GetTileData(Wall, 0);
        wall.SetCustomData("walkable", false);
        wall.SetCollisionPolygonsCount(0, 1);
        wall.SetCollisionPolygonPoints(0, 0, new[]
        {
            new Vector2(-8, -8), new Vector2(8, -8),
            new Vector2(8, 8), new Vector2(-8, 8)
        });
        return tiles;
    }
}

Distinguish dimensions and identifiers

ValueSampleMeaning
TileSet.TileSize(16,16)Map cell dimensions
TextureRegionSize(16,16)Base image region dimensions in pixels
SourceId0Source ID in TileSet
Floor(0,0)Floor tile coordinate in the atlas grid
Wall(1,0)Wall tile atlas coordinate, not pixel (16,0)
alternativeTile0Base version of the selected tile

Cell and artwork dimensions can differ. Larger artwork requires appropriate origin/offset and occupied regions; do not change TileSize merely to resize a texture. They match in this simple example to separate physics setup from complex artwork positioning.

Call CreateTile for each available region. Assigning Texture alone is insufficient: the map must reference a tile that actually exists in its source.

Configure physics

Create a physics layer in TileSet first. Its index 0 differs from its bitmask 1. The wall then receives a polygon count and points relative to its center, from −8 to 8 on each axis. These are not whole-atlas pixel positions or level cell coordinates.

The character body needs compatible collision layers/masks. A wall image is not collision; walkable=false does not create a shape either. The TileData polygon stops the sample actor, not the tile color or name.

Avoid adding another physics body over the same wall unnecessarily: duplicate contacts become harder to diagnose. The verified actor uses CharacterBody2D in Floating mode without gravity.

Add game metadata

First declare a TileSet custom-data layer named walkable with type Variant.Type.Bool. Assign values through TileData. When reading through GetCellTileData, check that a cell exists and uses an atlas source before calling GetCustomData.

These values belong to the tile type. If one door cell needs an open state, do not edit shared TileData as though it were unique to that cell. Store level state separately or select a suitable tile/alternative with the intended properties.

Save and extend

A TileSet can be saved as a .rdata resource and shared by multiple TileMapLayers. The native check saved the generated atlas, physics polygon and boolean metadata through ResourceSaver and loaded them through ResourceLoader. Check Error.Ok when saving and distinguish user:// user data from asset:// project resources.

Other tasks need separate configuration:

  • alternatives provide tile variants rather than independent cell state;
  • terrain connections require configured terrain and neighbor rules, not just suitable artwork;
  • navigation and light-occlusion contours differ from physics layers and are not generated automatically from them;
  • animated atlases require frame definitions and durations.

These advanced workflows are not implemented by this two-tile example. See TileSet, TileSetAtlasSource and TileData for exact properties.

Complete map and movement

Reckfell Engine documentationBack to top ↑
QUICK LINKSGetting startedEntity hierarchyC# & .NET 10Scenes and prefabs
Reckfell guides and full API K
reckfellENGINE
RECKFELL ACCOUNT

Sign in

Sign in to your Reckfell account.

One account for the entire Reckfell platform.