5.3 KiB
| id | ticket | title | created | tags | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| LSN-0054 | variable-tile-bank-palette-serialization | Runtime-Owned Variable Glyph Palette Counts | 2026-07-14 |
|
Runtime-Owned Variable Glyph Palette Counts
Original Problem
The first RGBA8888 alignment wave made Studio and packer emit palette colors in
the runtime channel order, but it deliberately kept the old fixed glyph-bank
palette payload shape. Every GLYPH/indexed_v1 payload still reserved room for
64 palettes, so the emitted palette block was always 64 * 16 * 4 = 4096
bytes even when the bank used one or a few palettes.
That fixed shape left two problems:
- packer output was larger than the runtime needed;
palette_countcould not be trusted as the effective runtime resident count, because the payload still looked like a 64-palette bank.
Runtime later accepted the variable-palette protocol for
GLYPH/indexed_v1. Studio and packer had to follow that runtime-owned wire
contract instead of keeping a stale producer-side convention.
Consolidated Decision
Runtime owns the GLYPH/indexed_v1 protocol. Studio and packer are downstream
producers of runtime-conforming assets.pa payloads.
The accepted rule is:
palette_countis the effective serialized and resident palette count.palette_countmust be in the inclusive range1..=64.- Palette bytes are exactly
palette_count * 16 * 4. size = ceil(width * height / 2) + palette_count * 16 * 4.decoded_size = width * height + palette_count * 16 * 4.- Palette bytes remain RGBA8888 in
R,G,B,Aorder. GLYPH/indexed_v1remains the format name. This change does not introduceGLYPH/indexed_v2.- There is no compatibility mode for the old fixed 64-palette padding.
- Palette IDs remain direct. There is no sparse-to-dense remapping metadata in v1.
palette_authored, when present, is informative tooling metadata only.
Implementation Result
The packer specs now define palette_count as runtime-effective metadata for
glyph banks and describe the variable palette payload in the build-artifact
contract. Studio-facing asset workspace docs now keep palette_count distinct
from any authored or tooling-only palette count.
The packer metadata model derives and validates effective palette count instead
of hard-coding 64. Sparse direct palette IDs are preserved by materializing
intermediate palette slots up to the highest referenced ID; those slots are not
a remapping table.
Payload emission now writes exactly the effective number of palette slots. Size and decoded-size accounting use the same formula as the runtime contract, so metadata, asset-table entries, and payload lengths agree.
Tests and fixtures cover palette_count = 1, intermediate counts, 64, sparse
direct identity, invalid counts above 64, RGBA8888 byte order, and payload
size accounting. Final validation passed with:
discussion validate;./gradlew :prometeu-packer:prometeu-packer-v1:test;./gradlew build.
Practical Examples
A 256 by 256 glyph bank with one palette has:
pixel bytes = ceil(256 * 256 / 2) = 32768
palette bytes = 1 * 16 * 4 = 64
size = 32768 + 64 = 32832
decoded_size = 256 * 256 + 64 = 65600
A bank that references palette ID 6 has an effective palette_count of at
least 7. Palette slots 0 through 6 exist in the serialized palette block.
If some lower slots were not authored directly, they are deterministic
placeholders; palette 6 is not remapped to palette 0.
Common Pitfalls and Anti-patterns
- Do not infer runtime payload length from the maximum allowed palette count.
64is the upper bound, not the default emitted count. - Do not use
palette_authoredas a runtime-effective field. It may describe a tool view, but runtime loadspalette_count. - Do not preserve fixed 4096-byte palette padding for banks with fewer than 64 effective palettes.
- Do not create
GLYPH/indexed_v2to carry this change. The accepted runtime protocol keeps the v1 format name. - Do not introduce sparse-to-dense palette remapping metadata. Existing scene, sprite, packer, and runtime references use direct palette identity.
- Do not combine RGBA8888 channel-order work with palette-count semantics.
RGBA8888 defines each color value;
palette_countdefines how many palettes are serialized and resident.
References
- Runtime decision:
../runtime/discussion/workflow/decisions/DEC-0041-variable-glyph-bank-palette-protocol.md. - Studio/packer decision:
discussion/workflow/decisions/DEC-0038-variable-glyph-bank-palette-serialization.md. PLN-0087: Variable glyph palette spec propagation.PLN-0088: Variable glyph palette metadata and count model.PLN-0089: Variable glyph palette payload emission and size accounting.PLN-0090: Studio and packer projections for variable glyph palettes.PLN-0091: Variable glyph palette tests, fixtures, and final validation.- Prior lesson:
discussion/lessons/DSC-0038-studio-packer-rgba8888-asset-pipeline/LSN-0053-rgba8888-is-the-canonical-studio-packer-palette-contract.md. 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.