prometeu-studio/docs/packer/learn/tile-bank-packing-contract.md
2026-03-24 13:42:57 +00:00

4.2 KiB

Tile Bank Packing Contract

Original Problem

After the generic pack execution boundary was closed, tile bank still lacked one explicit producer contract.

The repository needed to settle:

  1. how selected tile artifacts become one packed payload;
  2. how palette identity is declared and normalized;
  3. which runtime fields are derived for AssetEntry;
  4. which structural problems block packing before byte emission.

Consolidated Decision

The first-wave tile bank producer contract is:

  1. one canonical TILES/indexed_v1 payload per asset;
  2. 1 artifact = 1 tile;
  3. artifacts are normalized by explicit artifacts[*].index;
  4. the emitted sheet is fixed at 256 x 256 and row-major;
  5. tile pixels are packed u4;
  6. bank palettes are emitted as RGB565 u16;
  7. palette declarations use explicit { index, palette };
  8. structural diagnostics are produced early in walker/materialization and therefore participate in validation.

Final Model

1. Payload Shape

The payload is not a concatenation of artifact-local binaries. It is one canonical bank raster:

  1. packed u4 pixel indices for the full sheet;
  2. one 64 * 16 * 2 palette block.

2. Artifact and Tile Identity

  • artifacts are normalized by ascending declared index;
  • tile_id matches the normalized artifact index;
  • placement is row-major in the fixed sheet;
  • v1 capacities depend on tile_size:
    • 8 -> 1024
    • 16 -> 256
    • 32 -> 64

3. Palette Contract

  • palette identity is semantic, not positional;
  • ordering is ascending numeric index, never raw list order;
  • any tile may be rendered with any bank palette at runtime;
  • palette selection is a draw-time concern, not an embedded per-tile payload field.

4. Metadata Contract

AssetEntry.metadata keeps runtime-required fields readable at the root while preserving segmented subtrees:

  • output.metadata -> metadata
  • output.codec_configuration -> metadata.codec
  • output.pipeline -> metadata.pipeline

For tile banks, that means root readability for values such as:

  • tile_size
  • width
  • height
  • palette_count

5. Validation Boundary

Tile-bank structural issues belong in the walker/materialization path, not in a late pack-only surprise phase.

Blocking conditions include:

  • duplicate artifact indices;
  • gaps in normalized artifact indices;
  • fixed-sheet overflow;
  • missing palettes;
  • palette count above 64;
  • malformed palette declarations;
  • missing required metadata;
  • normalization failure.

Fragile tile indices are warnings in the first wave, not blockers by themselves.

Examples

Example: Why palette index must be explicit

If palette identity depends on array position, a harmless editorial reorder can silently change runtime meaning.

Using { index, palette } makes semantic identity reviewable and stable.

Example: Why validation must see tile-bank structure early

If duplicate artifact indices are discovered only during final byte emission, the wizard reaches Packing too late. The correct behavior is for validation to surface the blocker before emission begins, and for pack execution to rerun that same gate on a fresh execution snapshot.

Common Pitfalls and Anti-Patterns

  • Treating artifact declaration order as semantic tile identity.
  • Packing per-artifact fragments instead of one canonical sheet.
  • Embedding palette choice per tile in the packed payload.
  • Flattening all metadata into one ambiguous map.
  • Discovering tile-bank blockers only during late byte emission.

References