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

3.6 KiB

id ticket title status created resolved decision tags
AGD-0004 tilemap-and-metatile-runtime-binary-layout Tilemap and Metatile Runtime Binary Layout open 2026-03-26
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.