Files

18 lines
1.9 KiB
Markdown

# MEMORY.md — Durable Facts & Decisions
## Godot 4.7 — Stage 2 TileMapLayer collision (verified in headless)
<!-- observed: 2026-11-03 | status: active -->
- **TileSet + TileMapLayer + polygon collision WORK in Godot 4.7 headless.** Verified: Fox drops onto a TileMapLayer tile and lands at the tile's polygon top edge (steps=13, vel.y=0, on_floor=true).
- **Headless physics pattern:** run via `flatpak run org.godotengine.Godot --headless --path .` with `run/main_scene` set to a scene whose root is a `Node2D` script with `_ready()` + `_physics_process(delta)`. The engine's main loop drives physics (no need for `PhysicsServer2D.step()` / `integrate_forces`).
- **Two headless gotchas for TileMapLayer:**
1. The moving body (Fox) must be a **direct child of the root Node2D**, NOT nested inside the `TileMapLayer`. A Fox nested inside TileMapLayer gets a null physics space (`body->get_space()` null → move_and_slide no-ops) and falls forever.
2. Fox must start **above** the tile polygon. TileSet polygon points are in tile-local coords with the tile's top edge at y=0 and downward positive. If Fox starts below y=32 it's already past the tile and falls away. Start at negative y.
- **Per-tile collision polygon API (Godot 4.7):**
- `TileSet.add_physics_layer()` (void, auto-indexed), `set_physics_layer_collision_layer(idx, mask)`, `set_physics_layer_collision_mask(idx, mask)`.
- `TileMapLayer.get_cell_tile_data(Vector2i coords)` → `TileData` object (returns a live/mutable ref; edits persist — verified re-read = 1).
- `td.set_collision_polygons_count(layer_index, count)`, `td.set_collision_polygon_points(layer_index, polygon_index, PackedVector2Array([...]))`.
- `get_cell_tile_data` is the correct accessor; there is NO `set_tile_data` on the atlas source and no `TileSetCollisionObject2D`.
- `add_child` is on `Node` (not `World2D`); `get_root()` returns a `Window`, not `Node2D`. Use a `Node2D` script as scene root for physics.