prometeu-studio/discussion/workflow/decisions/DEC-0038-variable-glyph-bank-palette-serialization.md

7.1 KiB

id ticket title status created accepted ref_agenda plans tags
DEC-0038 variable-tile-bank-palette-serialization Variable Glyph Bank Palette Serialization for Studio and Packer accepted 2026-07-14 2026-07-14 AGD-0005
PLN-0087
PLN-0088
PLN-0089
PLN-0090
PLN-0091
packer
studio
glyph-bank
palette-serialization
rgba8888
runtime-alignment

Status

Accepted. Drafted from accepted agenda AGD-0005 and accepted on 2026-07-14.

Context

This decision belongs to the packer domain, with Studio-facing projection and fixture impact. Runtime protocol ownership remains in ../runtime.

Studio/packer already aligned glyph-bank colors with RGBA8888 through DSC-0038. That work kept the GLYPH/indexed_v1 format name and changed the palette color encoding from RGB565-era data to RGBA8888 in runtime channel order. It deliberately preserved the fixed 64-palette payload model for that wave.

Runtime DEC-0041 now changes the authoritative GLYPH/indexed_v1 contract:

  • palette_count is the number of serialized and resident palettes;
  • palette_count MUST be in 1..=64;
  • payloads contain exactly palette_count * 16 * 4 RGBA8888 palette bytes;
  • size = ceil(width * height / 2) + palette_count * 16 * 4;
  • decoded_size = width * height + palette_count * 16 * 4;
  • resident runtime memory materializes exactly palette_count palettes;
  • palette_id is direct identity within the loaded glyph bank and is valid only when palette_id < palette_count;
  • v1 has no sparse-to-dense palette remapping metadata;
  • this remains GLYPH/indexed_v1, not a new v2 payload.

Studio/packer must now follow that runtime-owned contract as downstream producers of runtime-conforming assets.pa payloads.

Decision

Studio and packer SHALL adopt variable glyph-bank palette serialization for GLYPH/indexed_v1, following runtime DEC-0041 as the protocol authority.

Packer MUST stop emitting a fixed 64-palette block for glyph banks unless the effective palette_count is actually 64.

Packer MUST emit exactly palette_count * 16 * 4 palette bytes for each GLYPH/indexed_v1 glyph-bank payload.

Packer MUST compute glyph-bank size as:

size = ceil(width * height / 2) + palette_count * 16 * 4

Packer MUST compute glyph-bank decoded_size as:

decoded_size = width * height + palette_count * 16 * 4

Packer MUST publish root effective metadata fields required by runtime:

  • tile_size
  • width
  • height
  • palette_count

For GLYPH/indexed_v1, palette_count MUST describe the number of serialized RGBA8888 palettes and the number of resident palettes expected by runtime. palette_count MUST be in the inclusive range 1..=64.

Packer and Studio MUST NOT introduce GLYPH/indexed_v2 for this change.

Packer and Studio MUST NOT preserve compatibility with the old fixed-padding payload shape as a special mode.

Packer and Studio MUST NOT introduce sparse-to-dense palette remapping metadata for v1.

palette_authored, when present in tooling or pipeline metadata, is informative only. It MUST NOT be treated as effective runtime metadata unless a later runtime decision promotes it.

Palette bytes SHALL remain RGBA8888 in runtime R, G, B, A byte order. Palette index 0 and color index 0 remain ordinary indices. Transparency remains represented by the alpha channel of the resolved RGBA8888 color.

Rationale

Runtime owns the GLYPH/indexed_v1 wire contract. Once runtime DEC-0041 accepted variable palette serialization, keeping packer output fixed at 64 palettes would make Studio/packer produce stale runtime payloads.

Making palette_count the effective serialized and resident count removes the old mismatch between authored palette count and payload shape. The packer no longer needs to pad every glyph bank to 4096 palette bytes unless the bank really uses all 64 palettes.

Keeping the existing format name is correct because the project is still in v1 and runtime explicitly accepted this as an incompatible v1 correction. A v2 name would add migration surface without protecting any required compatibility contract.

Rejecting sparse-to-dense remapping keeps palette_id direct. Scene, sprite, packer output, and runtime lookup all refer to the same palette identity inside the loaded glyph bank.

Implications

Specs

Packer specs MUST be updated so GLYPH/indexed_v1 no longer describes a fixed 64 * 16 * 4 = 4096 palette block as the normal payload shape.

Packer specs MUST define palette_count as the effective serialized palette count for glyph banks, constrained to 1..=64.

Studio specs MUST be updated only where Studio-facing projections, asset details, pack wizard behavior, or fixtures expose the old fixed-padding model.

Code

Packer payload emission MUST write only palette_count palettes.

Packer payload validation/materialization helpers MUST compute size and decoded size from variable palette_count.

Packer metadata projection and Studio-facing read/detail APIs MUST expose the runtime-effective palette_count correctly.

Studio code MUST NOT treat palette_authored as the runtime-effective count.

Tests and Fixtures

Tests MUST cover:

  • palette_count = 1;
  • an intermediate palette_count;
  • palette_count = 64;
  • size and decoded-size formulas for variable counts;
  • emitted RGBA8888 palette byte count;
  • metadata/payload mismatch rejection or producer validation.

Fixtures that encode the old fixed-padding assumption MUST be regenerated or updated unless they intentionally use palette_count = 64 and satisfy the new runtime contract directly.

Non-goals

This decision does not change RGBA8888 channel order.

This decision does not change the packed u4 indexed pixel plane.

This decision does not change scene palette_id payload shape.

This decision does not introduce v2, compatibility branches, or palette identity remapping.

Propagation Targets

  • Specs:
    • docs/specs/packer/3. Asset Declaration and Virtual Asset Contract Specification.md
    • docs/specs/packer/4. Build Artifacts and Deterministic Packing Specification.md
    • docs/specs/studio/4. Assets Workspace Specification.md, if Studio-facing palette count projection is documented there.
  • Code:
    • packer glyph-bank payload emission;
    • packer asset walking/materialization;
    • packer read/detail projections;
    • Studio asset details or pack wizard surfaces if they expose palette counts.
  • Tests:
    • packer parser, walker, materializer, workspace service, and fixture tests;
    • Studio tests if Studio projections or UI logic expose palette counts.
  • Docs:
    • downstream implementation plans derived from this decision.

References

  • Agenda: AGD-0005
  • Runtime decision: ../runtime/discussion/workflow/decisions/DEC-0041-variable-glyph-bank-palette-protocol.md
  • Runtime handoff: ../runtime/discussion/workflow/plans/PLN-0172-runtime-spec-handoff-to-packer-and-studio.md
  • Prior Studio/packer RGBA8888 lesson: discussion/lessons/DSC-0038-studio-packer-rgba8888-asset-pipeline/LSN-0053-rgba8888-is-the-canonical-studio-packer-palette-contract.md

Revision Log

  • 2026-07-14: Initial accepted decision from AGD-0005, aligned with runtime DEC-0041.