prometeu-studio/discussion/workflow/agendas/AGD-0004-tilemap-and-metatile-runtime-binary-layout.md

98 lines
3.6 KiB
Markdown

---
id: AGD-0004
ticket: tilemap-and-metatile-runtime-binary-layout
title: Tilemap and Metatile Runtime Binary Layout
status: open
created: 2026-03-26
resolved:
decision:
tags:
- packer
- legacy-import
- tilemap
- metatile
- runtime-layout
---
## Pain
The repository has conceptual alignment around map responsibility split and active-window residency, but still lacks a closed runtime binary contract for handheld maps.
Without a canonical decision:
- packer cannot close the output specification for map artifacts;
- runtime lacks one stable reading baseline;
- Studio cannot align authoring and preview schemas with one binary target.
## Context
Legacy source: `docs/packer/agendas/Tilemap and Metatile Runtime Binary Layout Agenda.md`
Domain owner: `docs/packer`
Cross-domain impact:
- `docs/vm-arch`
- `docs/studio`
- `docs/compiler/pbs`
Current discussion premises retained from source:
- visual and collision concerns should remain separated;
- map cells should not duplicate large metadata per tile;
- only a `3x3` active window of maps should remain resident in memory;
- a `64 KiB` target budget per map bank has been discussed;
- `map bank` and `tileset bank` do not need identical size rules.
## Open Questions
- [ ] Is `collisionId` with `5` bits (`32` classes) sufficient for expected projects?
- [ ] Should `flag0` be reserved for fast trigger semantics or contextual visual variation?
- [ ] Which optional chunks belong in `V1`, and which should wait for a later version?
- [ ] Must `map bank` stay strictly at `64 KiB`, or should capacity be variable with explicit metadata?
- [ ] What compression policy should the packer adopt by default for the stream?
## Options
### Option A - `u8` cells with auxiliary tables
- **Approach:** Store only one `metatileId` per cell and derive collision/flags from side tables.
- **Pro:** Smallest RAM and I/O footprint.
- **Con:** Pushes too much semantic meaning into external lookup tables.
- **Maintainability:** Medium.
### Option B - `u16` bit-packed cells
- **Approach:** Use `16` bits per cell, with a compact split such as `visualId`, `collisionId`, and `flag0`.
- **Pro:** Balances compactness, deterministic decoding, and enough expressivity for many handheld cases.
- **Con:** Leaves less room for inline per-cell growth than `u32`.
- **Maintainability:** Strong.
### Option C - `u32` cells
- **Approach:** Use larger cells to keep more event/flag space inline.
- **Pro:** Highest flexibility for per-cell triggers and future expansion.
- **Con:** Doubles memory cost versus `u16` without current evidence that it is needed.
- **Maintainability:** Weak for the current budget target.
## Discussion
The retained source already converged toward `u16` as the best baseline.
The suggested runtime shape is:
- fixed map header;
- contiguous cell stream;
- optional future-proof chunks.
The proposed `U16_PACKED_V1` split keeps visual and collision references compact while preserving predictable memory usage and straightforward streaming behavior for a handheld target.
## Resolution
Recommended direction: adopt **Option B** as the baseline.
Imported retained recommendation:
1. authorship stays JSON-oriented around compact ids;
2. build output packs deterministically into `U16_PACKED_V1`;
3. runtime active-window budget remains explicit;
4. any move to `u32` should happen only through a later versioned encoding with evidence of need.
Next step suggestion: convert this agenda into a decision that closes `U16_PACKED_V1`, propagation to `docs/vm-arch`, Studio editing schema alignment, and implementation planning for roundtrip tests.