Loading...
Loading...
2D level layout as data: Tiled/LDtk import, rooms, endless chunks, seeded levels, jump reachability.
npx skill4agent add tipoli5890/unity-dev-skills unity-2d-levelA level that exists only as painted Tilemaps can be looked at and played, and nothing else. It cannot be diffed, generated, converted from another editor, validated outside the Editor, or asked "can the runner reach that pickup". Asking a Tilemap "is this cell solid" is a native call per cell; its bounds grow when painted and never shrink when erased; and its collider catches up with its tiles later in the frame. None of that is a bug — a Tilemap is a renderer. The level is the small data structure it was painted from.
| The situation | Read |
|---|---|
| "Which Tilemap layers do I need": which Tilemaps a level needs, which collide, where each sorts; painting entities as marker tiles | |
| "Load this level from JSON": the level file's keys (tile ids, spawn, gate, pickups, entities), cell indexing, ids instead of asset references, versions, asset or JSON | |
| |
| Rooms and doors, their enter event, a room graph, soft locks, "stitch chunks for an endless runner", the difficulty ramp, additive room scenes | |
| "Import my Tiled map"; Tiled and LDtk: what they export, the row flip, global tile ids and flip bits, object anchors, converter or importer package | |
| SpriteShape terrain: hills, caves and bridges as splines; corner sprites; the collider a shape generates | |
| "A pickup is unreachable", "generate a level from a seed": the reach rule the validator applies; generating so the gate is reachable by construction; seeds and determinism | |
| Creating a Tile Palette, building a rule tile and its rule order, hex and isometric palette sizing | |
| Composite and tilemap collider settings, one-way effectors and their arcs, a body that tunnels or snags on seams | |
| Sorting layers and order across the stack, sorting by position, 2D lights, parallax; the runner behind and in front of one wall | |
| Confining the camera to the current room; a runner camera; blends between rooms | |
| Gap, ledge, step and door sizes from the controller's numbers | |
| The motor that walks the level: grounding, slopes, one-way drop-through | |
| Cell coordinates, neighbours, paths and turn order on a board | |
| Invariant shapes and ids; the brief's invariants; the lane-run generator this pattern extends | |
| A journey that plays the level; recorders, situations; the 2D never-inside invariant | |
| Slicing the tileset, pivots, 9-slice borders | |
| Frame cost of a load or a tile edit | |
| Tiles with hairline gaps or shimmer between them, pixel snapping | |
resources/LevelData.csTilemapLevelLoader.csRoomBounds.csChunkStitcher.csresources/Editor/TilemapLayerStackBuilder.csTiled .tmj ── tiled_to_level.py ──┐
a generator, from a seed ─────────┼──► level JSON ══ LevelData ──► level_validate.py exit 1: unreachable
a painted stack ── Export JSON ───┘ │
└──► TilemapLevelLoader ──► six Tilemaps + entities| Piece | Knows about | Never knows about |
|---|---|---|
| size, layers of tile ids, spawn, gate, pickups, entities with fields, its version | |
| the level file and three jump numbers | Unity |
| the id → tile table, the six layer names, a spawn delegate | what a sentry does |
the game's | an entity's type, position and fields | which editor the level came from |
resources/Editor/TilemapLayerStackBuilder.csreference/layer-stack.mdtemplates/sample-level.jsonreference/level-data.mdpython3 scripts/level_validate.py templates/sample-level.json \
--jump-height 2.85 --jump-distance 5.17 --fall-multiplier 1.5"verdict":"ok"launch-1pickup-2pickup-3--metrics metrics.jsonunity-gameplayscripts/level_metrics.pyloader.spawnEntity = (entity, position) => _spawner.Spawn(entity.type, position, entity);
loader.Load(LevelData.FromJson(levelJson.text)); // throws on a bad shape or an unbound tile id
_runner.position = loader.SpawnPosition;SetTilesBlockLoadreference/runtime-tilemap.mdloader.Verify(level)templates/LEVEL_INVARIANTS.md| The level is | What is different | Read |
|---|---|---|
| Hand-built and linear (side run) | Nothing — the five steps above | |
| A graph of rooms with gated doors | Rooms are rectangles at least one screen large; doors are data; the camera listens to a room event | |
| An endless run | Chunks whose entry height equals the last exit height, pooled, ordered by a seed | |
| Seen from above (depot) | | |
| Drawn in Tiled or LDtk | The editor's file is the source; a converter flips the rows once and decodes tile flags | |
| Generated | The path is built first and decorated after; every level is checked, not a sample | |
| Curved, organic ground | A spline with a generated collider, outside the cell search | |
| A board of rect, isometric or hexagonal cells (sorting yard) | Cells are the gameplay, not just the art | |
LevelData.IsSolidTilemap.GetTileTilemapLevelLoader.SetCellLevelData.Problems()scripts/level_validate.pySetTilesBlockProcessTilemapChanges()System.RandomUnityEngine.Randomunity-tilemapunity-physics-2dunity-2d-renderingunity-2d-controllerunity-2d-grid