prometeu-runtime/discussion/lessons/DSC-0046-runtime-owned-variable-glyph-bank-palette-protocol/LSN-0055-runtime-owned-asset-protocols-must-align-payload-residency-and-lookup.md
bQUARKz 7cced0709b
Some checks failed
Intrepid/Prometeu/Runtime/pipeline/head There was a failure building this commit
Intrepid/Prometeu/Runtime/pipeline/pr-master There was a failure building this commit
housekeep DSC-0046 variable glyph palette protocol
2026-07-14 16:08:17 +01:00

4.3 KiB

id ticket title created tags decision
LSN-0055 runtime-owned-variable-glyph-bank-palette-protocol Runtime-Owned Asset Protocols Must Align Payload, Residency, and Lookup 2026-07-14
runtime
assets
glyph-bank
palette-serialization
protocol
DEC-0041

Context

The runtime changed the GLYPH/indexed_v1 glyph-bank palette contract from a fixed 64-palette payload and resident table to variable palette serialization and variable resident palette storage.

The initiating pressure came from packer/studio: fixed RGBA8888 palette padding made small glyph banks pay for 64 * 16 * 4 palette bytes even when they used far fewer palettes. The important architectural point was that the runtime, not the packer, had to decide the protocol. The packer can only emit payloads that conform to the runtime contract once the runtime spec is published.

Key Decisions

Variable Glyph Bank Palette Protocol

What: palette_count became the number of serialized palettes and the number of resident palettes in the loaded GlyphBank. The valid range is 1..=64. palette_id remains a direct palette identity and is valid only when palette_id < palette_count for the referenced resident bank.

Why: Keeping serialized count variable while retaining a fixed 64-slot resident table would preserve two meanings for palette capacity. The runtime would save payload bytes but still carry a split contract between payload shape, resident shape, and lookup validity. Making all three agree gives the runtime one source of truth.

Trade-offs: Palette validity is now bank-dependent. Scene and sprite composition must check the referenced loaded bank instead of relying on a global 0..63 rule. This adds validation work, but it prevents invalid references from silently becoming transparent or default colors.

Patterns and Algorithms

Let the runtime own runtime-facing asset protocols. Tooling can discover pain, but the runtime spec must define effective metadata, payload shape, resident shape, and failure semantics.

Make count fields material. A count such as palette_count should not describe only what the producer authored or only what the payload happens to include. If runtime lookup depends on it, the count must also define resident state and validation boundaries.

Keep identity direct unless a real remapping problem exists. Sparse-to-dense palette remapping was rejected because it would add a second identity layer across scenes, sprites, packer output, and runtime lookup. V1 keeps palette id N as palette slot N in the resident bank.

Separate transparent color from invalid lookup. RGBA alpha is valid color data. An invalid palette reference must be observable as invalid; it must not be collapsed into Color::TRANSPARENT.

Use residue scans after protocol migrations. Search for fixed byte formulas, old constants, fixture helpers, and spec phrases. Legitimate hits should be renamed as maximum-bound concepts, not left as accidental active contracts.

Pitfalls

Partially variable specs are worse than fixed specs. The asset spec already had variable size formulas in some places but still required palette_count = 64 elsewhere. That contradiction made it unclear which rule was canonical.

Resident data structures can preserve obsolete protocol assumptions after the payload changes. A fixed array in GlyphBank would have kept the old model alive even if decode accepted variable payloads.

Fallback rendering hides contract errors. Returning transparent for an invalid palette id makes bad assets and bad scene references look like intentional alpha, which is exactly the wrong failure mode for a runtime protocol.

Fixture generators are part of the contract surface. Stress cartridges and test payload builders must express whether they are using a variable count or the v1 maximum; otherwise they reintroduce fixed-padding assumptions.

Takeaways

  • Runtime-facing asset protocols should align payload size, resident memory, and lookup validity.
  • palette_count is effective runtime metadata, not producer commentary.
  • Direct identity is simpler than remapping until a concrete remapping need exists.
  • Invalid palette references should fail explicitly; transparent remains a valid RGBA color, not an error substitute.
  • Protocol migrations need spec edits, code changes, fixture updates, and residue scans in the same workflow.