All checks were successful
JaCoCo Coverage #### Project Overview
No changes detected, that affect the code coverage.
* Line Coverage: 61.08% (17147/28073)
* Branch Coverage: 51.93% (6599/12707)
* Lines of Code: 28073
* Cyclomatic Complexity: 11234
#### Quality Gates Summary
Output truncated.
Test / Build skipped: 15, passed: 583
Intrepid/Prometeu/Studio/pipeline/head This commit looks good
127 lines
5.3 KiB
Markdown
127 lines
5.3 KiB
Markdown
---
|
|
id: LSN-0054
|
|
ticket: variable-tile-bank-palette-serialization
|
|
title: Runtime-Owned Variable Glyph Palette Counts
|
|
created: 2026-07-14
|
|
tags:
|
|
- packer
|
|
- studio
|
|
- glyph-bank
|
|
- palette-serialization
|
|
- rgba8888
|
|
- runtime-alignment
|
|
---
|
|
|
|
# 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_count` could 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:
|
|
|
|
1. `palette_count` is the effective serialized and resident palette count.
|
|
2. `palette_count` must be in the inclusive range `1..=64`.
|
|
3. Palette bytes are exactly `palette_count * 16 * 4`.
|
|
4. `size = ceil(width * height / 2) + palette_count * 16 * 4`.
|
|
5. `decoded_size = width * height + palette_count * 16 * 4`.
|
|
6. Palette bytes remain RGBA8888 in `R`, `G`, `B`, `A` order.
|
|
7. `GLYPH/indexed_v1` remains the format name. This change does not introduce
|
|
`GLYPH/indexed_v2`.
|
|
8. There is no compatibility mode for the old fixed 64-palette padding.
|
|
9. Palette IDs remain direct. There is no sparse-to-dense remapping metadata in
|
|
v1.
|
|
10. `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:
|
|
|
|
```text
|
|
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.
|
|
`64` is the upper bound, not the default emitted count.
|
|
- Do not use `palette_authored` as a runtime-effective field. It may describe a
|
|
tool view, but runtime loads `palette_count`.
|
|
- Do not preserve fixed 4096-byte palette padding for banks with fewer than 64
|
|
effective palettes.
|
|
- Do not create `GLYPH/indexed_v2` to 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_count` defines 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`.
|