Variable Glyph Bank Palette Serialization
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
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
This commit is contained in:
parent
fa089c5cd0
commit
ad2ae00f39
@ -1,4 +1,4 @@
|
||||
{"type":"meta","next_id":{"DSC":39,"AGD":42,"DEC":39,"PLN":92,"LSN":54,"CLSN":1}}
|
||||
{"type":"meta","next_id":{"DSC":39,"AGD":42,"DEC":39,"PLN":92,"LSN":55,"CLSN":1}}
|
||||
{"type":"discussion","id":"DSC-0038","status":"done","ticket":"studio-packer-rgba8888-asset-pipeline","title":"Studio and Packer RGBA8888 Asset Pipeline Alignment","created_at":"2026-05-23","updated_at":"2026-07-14","tags":["studio","packer","assets","glyph-bank","palette","rgba8888","runtime-alignment"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0053","file":"discussion/lessons/DSC-0038-studio-packer-rgba8888-asset-pipeline/LSN-0053-rgba8888-is-the-canonical-studio-packer-palette-contract.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14"}]}
|
||||
{"type":"discussion","id":"DSC-0037","status":"done","ticket":"pbs-autocomplete-parameter-names","title":"PBS autocomplete parameter names for stdlib and method calls","created_at":"2026-05-08","updated_at":"2026-05-14","tags":["compiler-pbs","studio","lsp","autocomplete","signature-help","stdlib"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0052","file":"discussion/lessons/DSC-0037-pbs-autocomplete-parameter-names/LSN-0052-canonical-callable-parameter-names-through-pbs-editor-assistance.md","status":"done","created_at":"2026-05-14","updated_at":"2026-05-14"}]}
|
||||
{"type":"discussion","id":"DSC-0036","status":"open","ticket":"pbs-symbol-documentation-and-hover-markdown","title":"Modelo de documentacao de simbolos em PBS e consumo markdown no hover","created_at":"2026-05-08","updated_at":"2026-05-08","tags":["compiler","compiler-pbs","studio","lsp","vscode","editor","hover","documentation","markdown"],"agendas":[{"id":"AGD-0039","file":"AGD-0039-pbs-symbol-documentation-and-hover-markdown.md","status":"open","created_at":"2026-05-08","updated_at":"2026-05-08"}],"decisions":[],"plans":[],"lessons":[]}
|
||||
@ -18,7 +18,7 @@
|
||||
{"type":"discussion","id":"DSC-0002","status":"done","ticket":"palette-management-in-studio","title":"Palette Management in Studio","created_at":"2026-03-26","updated_at":"2026-04-23","tags":["studio","legacy-import","palette-management","tile-bank","packer-boundary"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0042","file":"discussion/lessons/DSC-0002-palette-management-in-studio/LSN-0042-schema-driven-palette-authoring-and-local-metadata-events.md","status":"done","created_at":"2026-04-23","updated_at":"2026-04-23"}]}
|
||||
{"type":"discussion","id":"DSC-0003","status":"done","ticket":"packer-docs-import","title":"Import docs/packer into discussion-framework artifacts","created_at":"2026-03-26","updated_at":"2026-03-26","tags":["packer","migration","discussion-framework","docs-import"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0009","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0009-mental-model-packer-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0010","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0010-asset-identity-and-runtime-contract-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0011","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0011-foundations-workspace-runtime-and-build-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0012","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0012-runtime-ownership-and-studio-boundary-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0013","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0013-metadata-convergence-and-runtime-sink-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0014","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0014-pack-wizard-summary-validation-and-pack-execution-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0015","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0015-tile-bank-packing-contract-legacy.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"},{"id":"LSN-0017","file":"discussion/lessons/DSC-0003-packer-docs-import/LSN-0017-packer-docs-import-pattern.md","status":"done","created_at":"2026-03-26","updated_at":"2026-03-26"}]}
|
||||
{"type":"discussion","id":"DSC-0004","status":"abandoned","ticket":"tilemap-and-metatile-runtime-binary-layout","title":"Tilemap and Metatile Runtime Binary Layout","created_at":"2026-03-26","updated_at":"2026-04-24","tags":["packer","legacy-import","tilemap","metatile","runtime-layout"],"agendas":[{"id":"AGD-0004","file":"AGD-0004-tilemap-and-metatile-runtime-binary-layout.md","status":"abandoned","created_at":"2026-03-26","updated_at":"2026-04-24","_override_reason":"Explicit user request on 2026-04-24 to abandon AGD-0004 because the agenda is no longer valid."}],"decisions":[],"plans":[],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0005","status":"open","ticket":"variable-tile-bank-palette-serialization","title":"Variable Glyph Bank Palette Serialization","created_at":"2026-03-26","updated_at":"2026-07-14","tags":["packer","legacy-import","glyph-bank","palette-serialization","rgba8888","runtime-alignment"],"agendas":[{"id":"AGD-0005","file":"AGD-0005-variable-tile-bank-palette-serialization.md","status":"accepted","created_at":"2026-03-26","updated_at":"2026-07-14"}],"decisions":[{"id":"DEC-0038","file":"DEC-0038-variable-glyph-bank-palette-serialization.md","status":"accepted","created_at":"2026-07-14","updated_at":"2026-07-14","ref_agenda":"AGD-0005"}],"plans":[{"id":"PLN-0087","file":"PLN-0087-variable-glyph-palette-spec-propagation.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0038"]},{"id":"PLN-0088","file":"PLN-0088-variable-glyph-palette-metadata-and-count-model.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0038"]},{"id":"PLN-0089","file":"PLN-0089-variable-glyph-palette-payload-emission-and-size-accounting.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0038"]},{"id":"PLN-0090","file":"PLN-0090-studio-and-packer-projections-for-variable-glyph-palettes.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0038"]},{"id":"PLN-0091","file":"PLN-0091-variable-glyph-palette-tests-fixtures-and-final-validation.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14","ref_decisions":["DEC-0038"]}],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0005","status":"done","ticket":"variable-tile-bank-palette-serialization","title":"Variable Glyph Bank Palette Serialization","created_at":"2026-03-26","updated_at":"2026-07-14","tags":["packer","legacy-import","glyph-bank","palette-serialization","rgba8888","runtime-alignment"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0054","file":"discussion/lessons/DSC-0005-variable-glyph-bank-palette-serialization/LSN-0054-runtime-owned-variable-glyph-palette-counts.md","status":"done","created_at":"2026-07-14","updated_at":"2026-07-14"}]}
|
||||
{"type":"discussion","id":"DSC-0006","status":"done","ticket":"pbs-game-facing-asset-refs-and-call-result-discard","title":"PBS Game-Facing Asset References and Ignored Call Result Lowering","created_at":"2026-03-27","updated_at":"2026-03-30","tags":["compiler","pbs","ergonomics","lowering","runtime","asset-identity","expression-statements"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0024","file":"discussion/lessons/DSC-0006-pbs-game-facing-asset-refs-and-call-result-discard/LSN-0024-addressable-surface-host-metadata-and-ignored-value-discipline.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30"}]}
|
||||
{"type":"discussion","id":"DSC-0007","status":"done","ticket":"pbs-learn-to-discussion-lessons-migration","title":"Migrate PBS Learn Documents into Discussion Lessons","created_at":"2026-03-27","updated_at":"2026-03-27","tags":["compiler","pbs","migration","discussion-framework","lessons","learn-prune"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0018","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0018-pbs-ast-and-parser-contract-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0019","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0019-pbs-name-resolution-and-linking-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0020","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0020-pbs-runtime-values-identity-memory-boundaries-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0021","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0021-pbs-diagnostics-and-conformance-governance-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0022","file":"discussion/lessons/DSC-0007-pbs-learn-to-discussion-lessons-migration/LSN-0022-pbs-globals-lifecycle-and-published-entrypoint-legacy.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"}]}
|
||||
{"type":"discussion","id":"DSC-0008","status":"done","ticket":"pbs-low-level-asset-manager-surface","title":"PBS Low-Level Asset Manager Surface for Runtime AssetManager","created_at":"2026-03-27","updated_at":"2026-03-27","tags":["compiler","pbs","runtime","asset-manager","host-abi","stdlib","asset"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0023","file":"discussion/lessons/DSC-0008-pbs-low-level-asset-manager-surface/LSN-0023-lowassets-runtime-aligned-sdk-surface.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"}]}
|
||||
|
||||
@ -0,0 +1,126 @@
|
||||
---
|
||||
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`.
|
||||
@ -1,185 +0,0 @@
|
||||
---
|
||||
id: AGD-0005
|
||||
ticket: variable-tile-bank-palette-serialization
|
||||
title: Variable Glyph Bank Palette Serialization
|
||||
status: accepted
|
||||
created: 2026-03-26
|
||||
resolved: 2026-07-14
|
||||
decision: DEC-0038
|
||||
tags:
|
||||
- packer
|
||||
- legacy-import
|
||||
- glyph-bank
|
||||
- palette-serialization
|
||||
- rgba8888
|
||||
- runtime-alignment
|
||||
---
|
||||
|
||||
## Pain
|
||||
|
||||
Domain owner: `packer`, with runtime-facing impact through `assets.pa`.
|
||||
|
||||
The current `GLYPH/indexed_v1` glyph-bank contract serializes a fixed block of
|
||||
`64` palettes even when an asset authors far fewer palettes.
|
||||
|
||||
After `DSC-0038`, each palette entry is RGBA8888, so the fixed palette block is
|
||||
now `64 * 16 * 4 = 4096` bytes. That keeps decoding simple, but it wastes
|
||||
cartridge space and leaves a deliberate mismatch between authored palette count
|
||||
and serialized palette count.
|
||||
|
||||
## Context
|
||||
|
||||
Legacy source: `docs/packer/agendas/Variable Tile Bank Palette Serialization Agenda.md`
|
||||
|
||||
Cross-domain dependency:
|
||||
|
||||
- runtime
|
||||
|
||||
Runtime follow-up:
|
||||
|
||||
- `../runtime/discussion/workflow/decisions/DEC-0041-variable-glyph-bank-palette-protocol.md`
|
||||
is accepted and normative for the runtime side.
|
||||
- Runtime `DSC-0046` keeps `GLYPH/indexed_v1`, adopts variable glyph-bank
|
||||
palette serialization, and treats this as an incompatible v1 correction.
|
||||
- Runtime plans `PLN-0167` through `PLN-0172` are done and publish the
|
||||
downstream handoff.
|
||||
|
||||
Current runtime-owned `GLYPH/indexed_v1` contract:
|
||||
|
||||
- pixels are serialized as packed `u4`;
|
||||
- palettes are serialized as RGBA8888 values in runtime `R`, `G`, `B`, `A`
|
||||
byte order;
|
||||
- `palette_count` is the number of serialized and resident palettes;
|
||||
- `palette_count` must be in `1..=64`;
|
||||
- payload size includes exactly `palette_count * 16 * 4` palette bytes;
|
||||
- palette index `0` is ordinary;
|
||||
- each palette has 16 usable colors;
|
||||
- transparency is represented by alpha, not by a reserved index or magenta
|
||||
color-key;
|
||||
- resident runtime memory materializes exactly `palette_count` palettes;
|
||||
- `palette_id` is a direct palette identity inside the loaded glyph bank and is
|
||||
valid only when `palette_id < palette_count`;
|
||||
- sparse-to-dense palette remapping is not part of v1;
|
||||
- missing palettes must fail explicitly in scene/sprite/composer use, not
|
||||
silently resolve to a default color.
|
||||
|
||||
Downstream producers must emit:
|
||||
|
||||
- root effective metadata fields `tile_size`, `width`, `height`, and
|
||||
`palette_count`;
|
||||
- `size = ceil(width * height / 2) + palette_count * 16 * 4`;
|
||||
- `decoded_size = width * height + palette_count * 16 * 4`;
|
||||
- exactly `palette_count * 16 * 4` RGBA8888 palette bytes;
|
||||
- no `GLYPH/indexed_v2` payload for this change;
|
||||
- no fixed 64-palette padding unless `palette_count = 64` and the payload
|
||||
directly satisfies the runtime v1 contract;
|
||||
- no effective runtime behavior based on `palette_authored`.
|
||||
|
||||
`DSC-0038` intentionally did not solve variable palette-count serialization.
|
||||
It changed the color encoding from RGB565-era semantics to RGBA8888 and kept
|
||||
the fixed 64-palette model stable for that wave.
|
||||
|
||||
Runtime `DEC-0041` now closes the cross-domain protocol questions that this
|
||||
agenda previously carried as open. The remaining Studio/packer work is
|
||||
downstream alignment with the runtime-owned contract.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- [x] Should variable palette serialization arrive as a new payload version or
|
||||
as an incompatible change to the current one?
|
||||
- Runtime `DEC-0041` resolves this as an incompatible correction to
|
||||
`GLYPH/indexed_v1`, with no v2 format.
|
||||
- [x] If `palette_count` becomes variable, should runtime still materialize a
|
||||
64-slot resident bank, or truly shrink in-memory representation too?
|
||||
- Runtime `DEC-0041` resolves this: resident runtime memory materializes
|
||||
exactly `palette_count` palettes.
|
||||
- [x] Should sparse authored palette indices remain sparse in serialization, or
|
||||
be canonicalized into a dense runtime block?
|
||||
- Runtime `DEC-0041` rejects sparse-to-dense remapping. `palette_id` remains
|
||||
direct identity inside the loaded glyph bank.
|
||||
- [x] Should this repository create the owner agenda/decision for the runtime
|
||||
side, or should a matching runtime `discussion/` artifact be opened before
|
||||
implementation planning?
|
||||
- Runtime `DSC-0046` now owns the protocol through accepted `DEC-0041`.
|
||||
Studio/packer must follow that handoff.
|
||||
- [x] Which domain owns compatibility for existing cartridges: `packer`,
|
||||
`runtime`, or `shipper`?
|
||||
- Runtime `DEC-0041` introduces no compatibility mode. Old payloads with
|
||||
`palette_count = 64` remain valid only when they satisfy the new contract
|
||||
directly.
|
||||
|
||||
## Options
|
||||
|
||||
### Option A - Keep fixed 64-palette serialization in v1
|
||||
- **Approach:** Preserve the current fixed v1 payload with zero-filled unused palette slots.
|
||||
- **Pro:** No runtime change and current specs/tests remain stable.
|
||||
- **Con:** Every glyph bank keeps paying the full 4096-byte palette cost.
|
||||
- **Maintainability:** Medium.
|
||||
|
||||
### Option B - Align packer output with runtime variable palette serialization
|
||||
- **Approach:** Keep the `GLYPH/indexed_v1` format name, serialize only
|
||||
`palette_count` palettes, and make packer metadata, payload sizes, fixtures,
|
||||
and Studio projections follow runtime `DEC-0041`.
|
||||
- **Pro:** Removes fixed padding while the project is still in v1, keeps the
|
||||
public format vocabulary stable, and makes runtime metadata match the payload.
|
||||
- **Con:** Requires coordinated packer/spec/test changes and fixture
|
||||
regeneration because the current producer still emits the old fixed-padding
|
||||
shape.
|
||||
- **Maintainability:** Strong if implemented as an explicit contract update,
|
||||
weak if done as an incidental size tweak. Runtime has already closed the
|
||||
protocol questions.
|
||||
|
||||
### Option C - Keep fixed external metadata but trim trailing palettes
|
||||
- **Approach:** Keep some 64-slot assumptions in metadata or runtime memory, but
|
||||
serialize only a shortened trailing subset of palettes in the payload.
|
||||
- **Pro:** Can reduce cartridge size while limiting some runtime changes.
|
||||
- **Con:** Creates a split-brain contract where serialized count, logical count,
|
||||
and resident count can disagree.
|
||||
- **Maintainability:** Weak. It preserves the ambiguity this agenda is trying
|
||||
to remove.
|
||||
|
||||
## Discussion
|
||||
|
||||
The retained concern is still valid after `DSC-0038`, but runtime `DEC-0041`
|
||||
has now closed the protocol. The problem is no longer an open cross-domain
|
||||
design question; it is a downstream producer-alignment task for Studio/packer.
|
||||
|
||||
The old recommendation favored a versioned follow-up because compatibility and
|
||||
runtime stability were treated as constraints. Runtime `DEC-0041` removes that
|
||||
constraint: the project is still in v1, keeps `GLYPH/indexed_v1`, and does not
|
||||
need compatibility for the old fixed 64-palette payload.
|
||||
|
||||
That makes Option B the required direction for this repository. Runtime already
|
||||
changed the contract directly; Studio/packer must now emit the runtime-owned
|
||||
shape and stop treating `palette_authored` or the old 64-padding model as
|
||||
effective runtime behavior.
|
||||
|
||||
Option C should be avoided because it preserves multiple meanings for palette
|
||||
count. If the payload becomes variable, `palette_count` should mean the number
|
||||
of serialized palettes, not an unrelated fixed resident capacity.
|
||||
|
||||
## Resolution
|
||||
|
||||
Recommended direction: adopt **Option B**.
|
||||
|
||||
Updated recommendation:
|
||||
|
||||
1. keep the format name `GLYPH/indexed_v1`;
|
||||
2. follow runtime `DEC-0041` as the protocol authority;
|
||||
3. remove the fixed 64-palette payload block from packer output;
|
||||
4. make packer `palette_count` describe the serialized and resident RGBA8888
|
||||
palette count;
|
||||
5. emit exactly `palette_count * 16 * 4` palette bytes;
|
||||
6. update `size` and `decoded_size` formulas to use variable `palette_count`;
|
||||
7. do not create a v2 format solely for this change;
|
||||
8. do not preserve compatibility with the old fixed-padding payload;
|
||||
9. do not introduce sparse-to-dense palette remapping metadata;
|
||||
10. treat `palette_authored` as informative only unless a later runtime
|
||||
decision promotes it to effective metadata;
|
||||
11. add downstream fixture coverage for `palette_count = 1`, an intermediate
|
||||
count, and `palette_count = 64`;
|
||||
12. add a negative producer validation case for metadata/payload mismatch.
|
||||
|
||||
Next step suggestion: convert this agenda into a Studio/packer decision that
|
||||
references runtime `DEC-0041` and scopes implementation to specs, packer
|
||||
payload emission, Studio projections if needed, tests, and fixtures.
|
||||
@ -1,208 +0,0 @@
|
||||
---
|
||||
id: DEC-0038
|
||||
ticket: variable-tile-bank-palette-serialization
|
||||
title: Variable Glyph Bank Palette Serialization for Studio and Packer
|
||||
status: accepted
|
||||
created: 2026-07-14
|
||||
accepted: 2026-07-14
|
||||
ref_agenda: AGD-0005
|
||||
plans:
|
||||
- PLN-0087
|
||||
- PLN-0088
|
||||
- PLN-0089
|
||||
- PLN-0090
|
||||
- PLN-0091
|
||||
tags:
|
||||
- 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:
|
||||
|
||||
```text
|
||||
size = ceil(width * height / 2) + palette_count * 16 * 4
|
||||
```
|
||||
|
||||
Packer MUST compute glyph-bank `decoded_size` as:
|
||||
|
||||
```text
|
||||
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`.
|
||||
@ -1,132 +0,0 @@
|
||||
---
|
||||
id: PLN-0087
|
||||
ticket: variable-tile-bank-palette-serialization
|
||||
title: Variable Glyph Palette Spec Propagation
|
||||
status: done
|
||||
created: 2026-07-14
|
||||
completed: 2026-07-14
|
||||
ref_decisions:
|
||||
- DEC-0038
|
||||
tags:
|
||||
- specs
|
||||
- packer
|
||||
- studio
|
||||
- glyph-bank
|
||||
- palette-serialization
|
||||
---
|
||||
|
||||
## Objective
|
||||
|
||||
Propagate `DEC-0038` into the canonical Studio and packer specifications before
|
||||
code changes start.
|
||||
|
||||
## Background
|
||||
|
||||
Runtime `DEC-0041` makes `palette_count` the serialized and resident palette
|
||||
count for `GLYPH/indexed_v1`. Studio/packer `DEC-0038` adopts that runtime
|
||||
contract downstream. Current packer specs still describe a fixed
|
||||
`64 * 16 * 4 = 4096` palette block and `palette_count = 64`.
|
||||
|
||||
## Scope
|
||||
|
||||
### Included
|
||||
|
||||
- Update packer specs for glyph-bank metadata, payload layout, and size formulas.
|
||||
- Update Studio specs only where Studio-facing palette count projection or asset
|
||||
details are documented.
|
||||
- Preserve RGBA8888 channel order, packed `u4` pixels, and `GLYPH/indexed_v1`.
|
||||
|
||||
### Excluded
|
||||
|
||||
- Code changes.
|
||||
- Fixture regeneration.
|
||||
- Runtime spec changes.
|
||||
- Any `GLYPH/indexed_v2` design.
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1 - Update asset declaration metadata rules
|
||||
|
||||
**What:** Define `palette_count` as the effective runtime metadata field.
|
||||
|
||||
**How:** Update glyph-bank declaration language so `palette_count` means the
|
||||
number of serialized and resident RGBA8888 palettes, constrained to `1..=64`.
|
||||
State that `palette_authored`, if present, is informative and not runtime
|
||||
effective.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `docs/specs/packer/3. Asset Declaration and Virtual Asset Contract Specification.md`
|
||||
|
||||
### Step 2 - Update glyph payload layout
|
||||
|
||||
**What:** Replace fixed 4096-byte palette block text.
|
||||
|
||||
**How:** Change the layout to `palette_count * 16 * 4` palette bytes and update
|
||||
formulas to:
|
||||
|
||||
```text
|
||||
size = ceil(width * height / 2) + palette_count * 16 * 4
|
||||
decoded_size = width * height + palette_count * 16 * 4
|
||||
```
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `docs/specs/packer/4. Build Artifacts and Deterministic Packing Specification.md`
|
||||
|
||||
### Step 3 - Preserve v1 boundaries
|
||||
|
||||
**What:** Explicitly prohibit v2, compatibility padding, and remapping.
|
||||
|
||||
**How:** Add rules that this remains `GLYPH/indexed_v1`, old fixed-padding is
|
||||
not a compatibility mode, and v1 has no sparse-to-dense palette remapping.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `docs/specs/packer/4. Build Artifacts and Deterministic Packing Specification.md`
|
||||
|
||||
### Step 4 - Update Studio-facing spec text
|
||||
|
||||
**What:** Align Studio projections if they mention palette count or fixed bank
|
||||
shape.
|
||||
|
||||
**How:** Search the Studio asset workspace spec for palette projection, details,
|
||||
or pack wizard language and update only stale fixed-count wording.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `docs/specs/studio/4. Assets Workspace Specification.md`
|
||||
|
||||
## Test Requirements
|
||||
|
||||
### Unit Tests
|
||||
|
||||
- Not applicable for this spec-only plan.
|
||||
|
||||
### Integration Tests
|
||||
|
||||
- Not applicable for this spec-only plan.
|
||||
|
||||
### Manual Verification
|
||||
|
||||
- Search specs for stale normal-path `palette_count = 64`, `4096`, fixed
|
||||
64-palette block, `GLYPH/indexed_v2`, and remapping language.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [x] Packer specs define `palette_count` as runtime-effective `1..=64`.
|
||||
- [x] Packer specs use variable palette byte and size formulas.
|
||||
- [x] Specs keep `GLYPH/indexed_v1` and reject v2 for this change.
|
||||
- [x] Specs reject fixed-padding compatibility and sparse-to-dense remapping.
|
||||
- [x] Studio specs contain no stale fixed 64-palette projection wording.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Depends on accepted `DEC-0038`.
|
||||
- Should complete before code plans.
|
||||
|
||||
## Risks
|
||||
|
||||
- Leaving stale fixed 4096-byte examples will make implementation review
|
||||
ambiguous.
|
||||
- Over-editing Studio specs could imply UI behavior not required by `DEC-0038`.
|
||||
@ -1,140 +0,0 @@
|
||||
---
|
||||
id: PLN-0088
|
||||
ticket: variable-tile-bank-palette-serialization
|
||||
title: Variable Glyph Palette Metadata and Count Model
|
||||
status: done
|
||||
created: 2026-07-14
|
||||
completed: 2026-07-14
|
||||
ref_decisions:
|
||||
- DEC-0038
|
||||
tags:
|
||||
- packer
|
||||
- metadata
|
||||
- glyph-bank
|
||||
- palette-count
|
||||
---
|
||||
|
||||
## Objective
|
||||
|
||||
Make packer metadata compute and expose runtime-effective glyph-bank
|
||||
`palette_count` from declared palette data instead of hard-coding `64`.
|
||||
|
||||
## Background
|
||||
|
||||
`DEC-0038` requires `palette_count` to describe the number of serialized and
|
||||
resident palettes expected by runtime. Current packer code emits
|
||||
`palette_count = 64` and uses `palette_authored` for the actual authored count.
|
||||
That makes the informative count and effective runtime count diverge.
|
||||
|
||||
## Scope
|
||||
|
||||
### Included
|
||||
|
||||
- Compute effective glyph palette count from declared `output.pipeline.palettes`.
|
||||
- Validate `palette_count` in `1..=64`.
|
||||
- Keep palette identity direct; do not remap sparse authored indices.
|
||||
- Stop using `palette_authored` as a runtime-effective field.
|
||||
|
||||
### Excluded
|
||||
|
||||
- Binary payload byte emission.
|
||||
- Size formula changes.
|
||||
- Studio UI changes except compile-safe DTO/projection adjustments.
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1 - Add a runtime-effective palette count helper
|
||||
|
||||
**What:** Centralize effective glyph palette count calculation.
|
||||
|
||||
**How:** Add or update helper logic so packer derives `palette_count` from
|
||||
declared palette indices. Because v1 has no remapping, the effective count must
|
||||
cover the highest direct palette id: `max(index) + 1`. Reject no palettes,
|
||||
negative indices, duplicate indices, and any effective count above `64`.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerAssetWalker.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/PackerAssetDeclarationParser.java`
|
||||
|
||||
### Step 2 - Replace fixed runtime metadata
|
||||
|
||||
**What:** Stop writing `palette_count = 64` unconditionally.
|
||||
|
||||
**How:** Replace runtime metadata emission so glyph-bank entries publish the
|
||||
computed runtime-effective `palette_count`. Keep `palette_authored` only if it
|
||||
is useful as pipeline/tooling information and never as runtime-effective root
|
||||
metadata.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerRuntimeAssetMaterializer.java`
|
||||
|
||||
### Step 3 - Validate direct palette identity
|
||||
|
||||
**What:** Preserve runtime direct `palette_id` semantics.
|
||||
|
||||
**How:** Ensure packer does not compact or renumber palette indices. If palette
|
||||
indices are sparse, emitted palette slots up to `palette_count - 1` must keep
|
||||
their direct identity, with missing slots represented by deterministic default
|
||||
RGBA8888 palette data only when required to preserve direct ids.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerGlyphBankWalker.java`
|
||||
|
||||
### Step 4 - Update projections that expose metadata
|
||||
|
||||
**What:** Align details/read projections with the effective count.
|
||||
|
||||
**How:** Ensure packer read/details APIs expose `palette_count` consistently
|
||||
where runtime metadata is projected, and do not present `palette_authored` as
|
||||
the field that runtime consumes.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/PackerAssetDetailsService.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/PackerReadMessageMapper.java`
|
||||
|
||||
## Test Requirements
|
||||
|
||||
### Unit Tests
|
||||
|
||||
- Parser/metadata tests for `palette_count = 1`, intermediate count, and `64`.
|
||||
- Rejection tests for zero effective palettes, duplicate indices, negative
|
||||
indices, and count above `64`.
|
||||
- Sparse direct identity tests where palette index `3` implies
|
||||
`palette_count = 4`, without remapping palette `3` to `0`.
|
||||
|
||||
### Integration Tests
|
||||
|
||||
- Workspace read/build test proving asset table metadata reports variable
|
||||
`palette_count`.
|
||||
|
||||
### Manual Verification
|
||||
|
||||
- Search packer code for `palette_count = 64` and `GLYPH_BANK_PALETTE_COUNT`
|
||||
assumptions after the change.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [x] Packer computes runtime-effective `palette_count` from declared palettes.
|
||||
- [x] `palette_count` is validated as `1..=64`.
|
||||
- [x] Sparse palette ids are not remapped.
|
||||
- [x] `palette_authored` is not treated as runtime-effective metadata.
|
||||
- [x] Read/details projections do not expose stale fixed-count assumptions.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Depends on `PLN-0087`.
|
||||
- Must complete before payload emission changes in `PLN-0089`.
|
||||
|
||||
## Risks
|
||||
|
||||
- Sparse palette handling can accidentally become remapping if implemented by
|
||||
sorting and compacting declarations.
|
||||
- Keeping `palette_authored` in tooling may confuse readers unless tests prove
|
||||
runtime-effective metadata uses `palette_count`.
|
||||
@ -1,140 +0,0 @@
|
||||
---
|
||||
id: PLN-0089
|
||||
ticket: variable-tile-bank-palette-serialization
|
||||
title: Variable Glyph Palette Payload Emission and Size Accounting
|
||||
status: done
|
||||
created: 2026-07-14
|
||||
completed: 2026-07-14
|
||||
ref_decisions:
|
||||
- DEC-0038
|
||||
tags:
|
||||
- packer
|
||||
- assets-pa
|
||||
- glyph-bank
|
||||
- payload
|
||||
---
|
||||
|
||||
## Objective
|
||||
|
||||
Change packer `GLYPH/indexed_v1` payload emission from a fixed 64-palette block
|
||||
to exactly `palette_count * 16 * 4` RGBA8888 bytes, with matching size and
|
||||
decoded-size accounting.
|
||||
|
||||
## Background
|
||||
|
||||
`FileSystemPackerWorkspaceService` currently defines fixed palette constants
|
||||
and emits a fixed `GLYPH_BANK_PALETTE_BYTES` block. `DEC-0038` requires packer
|
||||
to emit only the runtime-effective palette count and compute asset table sizes
|
||||
from that count.
|
||||
|
||||
## Scope
|
||||
|
||||
### Included
|
||||
|
||||
- Replace fixed palette byte constants with count-dependent formulas.
|
||||
- Emit exactly `palette_count` palettes in RGBA byte order.
|
||||
- Update asset table `size` and `decoded_size`.
|
||||
- Reject metadata/payload mismatches.
|
||||
|
||||
### Excluded
|
||||
|
||||
- Palette model extraction changes covered by `PLN-0088`.
|
||||
- Studio UI changes.
|
||||
- Runtime code changes.
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1 - Replace fixed palette byte constants
|
||||
|
||||
**What:** Remove normal-path fixed `64 * 16 * 4` size assumptions.
|
||||
|
||||
**How:** Keep maximum constants such as `MAX_PALETTE_COUNT = 64`, but compute
|
||||
payload palette bytes as `palette_count * 16 * 4` at each glyph-bank packing
|
||||
boundary.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerAssetWalker.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerRuntimeAssetMaterializer.java`
|
||||
|
||||
### Step 2 - Emit variable palette bytes
|
||||
|
||||
**What:** Write only runtime-effective palettes.
|
||||
|
||||
**How:** Update palette byte generation to allocate
|
||||
`palette_count * 16 * 4` bytes and fill direct palette ids from `0` through
|
||||
`palette_count - 1`. Each color remains RGBA8888 in `R`, `G`, `B`, `A` order.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java`
|
||||
|
||||
### Step 3 - Update size and decoded-size formulas
|
||||
|
||||
**What:** Align asset table sizes with runtime `DEC-0041`.
|
||||
|
||||
**How:** Compute:
|
||||
|
||||
```text
|
||||
size = ceil(width * height / 2) + palette_count * 16 * 4
|
||||
decoded_size = width * height + palette_count * 16 * 4
|
||||
```
|
||||
|
||||
Use these formulas for asset table entries, materializer expectations, and
|
||||
workspace build outputs.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerRuntimeAssetMaterializer.java`
|
||||
|
||||
### Step 4 - Reject metadata/payload mismatches
|
||||
|
||||
**What:** Prevent stale fixed-padding artifacts.
|
||||
|
||||
**How:** Add validation that emitted palette byte length, root metadata
|
||||
`palette_count`, `size`, and `decoded_size` agree. Do not allow a fixed
|
||||
64-palette block when `palette_count < 64`.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/PackerRuntimeAssetMaterializer.java`
|
||||
|
||||
## Test Requirements
|
||||
|
||||
### Unit Tests
|
||||
|
||||
- Assert emitted palette bytes for `palette_count = 1`, an intermediate count,
|
||||
and `64`.
|
||||
- Assert `size` and `decoded_size` formulas for variable counts.
|
||||
- Assert RGBA byte order is unchanged.
|
||||
|
||||
### Integration Tests
|
||||
|
||||
- Build a workspace and inspect `assets.pa` asset table and payload length for
|
||||
variable palette counts.
|
||||
|
||||
### Manual Verification
|
||||
|
||||
- Search for fixed normal-path `4096`, `64 * 16 * 4`, and
|
||||
`GLYPH_BANK_PALETTE_BYTES` residue.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [x] Glyph payloads emit exactly `palette_count * 16 * 4` palette bytes.
|
||||
- [x] Asset table `size` and `decoded_size` use variable formulas.
|
||||
- [x] RGBA byte order is unchanged.
|
||||
- [x] Fixed 64-palette padding is emitted only when `palette_count = 64`.
|
||||
- [x] Metadata/payload mismatch is rejected or impossible by construction.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Depends on `PLN-0088`.
|
||||
|
||||
## Risks
|
||||
|
||||
- Updating metadata without payload length will corrupt runtime slicing.
|
||||
- Updating payload length without decoded-size metadata will fail runtime asset
|
||||
validation.
|
||||
@ -1,147 +0,0 @@
|
||||
---
|
||||
id: PLN-0090
|
||||
ticket: variable-tile-bank-palette-serialization
|
||||
title: Studio and Packer Projections for Variable Glyph Palettes
|
||||
status: done
|
||||
created: 2026-07-14
|
||||
completed: 2026-07-14
|
||||
ref_decisions:
|
||||
- DEC-0038
|
||||
tags:
|
||||
- studio
|
||||
- packer
|
||||
- api
|
||||
- projections
|
||||
- glyph-bank
|
||||
---
|
||||
|
||||
## Objective
|
||||
|
||||
Align Studio-facing and packer-facing projections so variable glyph
|
||||
`palette_count` is visible and not confused with `palette_authored`.
|
||||
|
||||
## Background
|
||||
|
||||
`DEC-0038` says 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.
|
||||
|
||||
## Scope
|
||||
|
||||
### Included
|
||||
|
||||
- Update packer read/detail DTO projections where runtime metadata is surfaced.
|
||||
- Update Studio asset details, palette overhauling, schema, or pack wizard code
|
||||
if it reads fixed counts or authored counts as runtime-effective.
|
||||
- Keep `rgba8888` color projection unchanged.
|
||||
|
||||
### Excluded
|
||||
|
||||
- Binary payload emission.
|
||||
- General palette UI redesign.
|
||||
- `originalArgb8888` UI fallback cleanup unrelated to variable `palette_count`.
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1 - Audit projection boundaries
|
||||
|
||||
**What:** Find all Studio/packer paths that expose glyph palette metadata.
|
||||
|
||||
**How:** Search for `palette_count`, `palette_authored`,
|
||||
`GLYPH_BANK_PALETTE_COUNT`, fixed `64`, and related asset details projections.
|
||||
Classify each match as runtime-effective metadata, tooling-only metadata, UI
|
||||
fallback, or unrelated.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/PackerAssetDetailsService.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/PackerReadMessageMapper.java`
|
||||
- `prometeu-studio/src/main/java/p/studio/workspaces/assets/**`
|
||||
|
||||
### Step 2 - Update packer details/read surfaces
|
||||
|
||||
**What:** Expose runtime-effective `palette_count`.
|
||||
|
||||
**How:** Ensure details/read projections show the `palette_count` that will be
|
||||
written to the runtime asset table. Preserve `palette_authored` only as
|
||||
explicitly tooling-only information if it remains useful.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/PackerAssetDetailsService.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/PackerReadMessageMapper.java`
|
||||
|
||||
### Step 3 - Update Studio consumers
|
||||
|
||||
**What:** Prevent Studio from using authored count as runtime count.
|
||||
|
||||
**How:** Adjust Studio asset details and pack wizard code so any displayed or
|
||||
validated runtime count comes from effective `palette_count`. Keep palette
|
||||
color rendering based on `rgba8888`.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-studio/src/main/java/p/studio/workspaces/assets/details/**`
|
||||
- `prometeu-studio/src/test/java/p/studio/workspaces/assets/details/**`
|
||||
|
||||
### Step 4 - Preserve scene palette id shape
|
||||
|
||||
**What:** Avoid accidental scene payload changes.
|
||||
|
||||
**How:** Confirm scene projections still carry `palette_id` unchanged and only
|
||||
runtime/packer validation changes count semantics.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-studio/src/main/java/p/studio/workspaces/assets/**`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/FileSystemPackerWorkspaceService.java`
|
||||
|
||||
## Test Requirements
|
||||
|
||||
### Unit Tests
|
||||
|
||||
- Packer details/read tests for variable `palette_count`.
|
||||
- Studio asset details tests proving runtime count and authored/tooling count
|
||||
are not conflated.
|
||||
|
||||
### Integration Tests
|
||||
|
||||
- Workspace read/build flow where a glyph bank with an intermediate
|
||||
`palette_count` is projected through packer/Studio surfaces.
|
||||
|
||||
### Manual Verification
|
||||
|
||||
- Search Studio and packer projection code for stale assumptions that
|
||||
`palette_authored` is runtime-effective.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [x] Packer read/details projections expose effective `palette_count`.
|
||||
- [x] Studio consumers do not use `palette_authored` as runtime-effective count.
|
||||
- [x] `rgba8888` color projection remains unchanged.
|
||||
- [x] Scene `palette_id` payload shape is unchanged.
|
||||
- [x] Tests cover variable count projection.
|
||||
|
||||
## Execution Notes
|
||||
|
||||
- Packer runtime output projection is the `assets.pa` asset table generated by
|
||||
`FileSystemPackerWorkspaceService`; `PLN-0088` and `PLN-0089` now project the
|
||||
runtime-effective `palette_count` there.
|
||||
- `PackerAssetDetailsService` and `PackerReadMessageMapper` project palette
|
||||
color data through `pipelinePalettes` and do not expose
|
||||
`palette_authored` as runtime-effective metadata.
|
||||
- Studio asset details mapping forwards packer details without deriving a
|
||||
runtime count from `palette_authored`.
|
||||
- No DTO field was added because doing so would create a new Studio/packer API
|
||||
surface not required by `DEC-0038`.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Depends on `PLN-0088`.
|
||||
- Can run in parallel with `PLN-0089` after metadata semantics are stable.
|
||||
|
||||
## Risks
|
||||
|
||||
- UI code may still need ARGB helper fields for presentation. This plan must not
|
||||
turn that into a runtime metadata decision.
|
||||
- Overbroad projection edits could accidentally change scene contracts.
|
||||
@ -1,167 +0,0 @@
|
||||
---
|
||||
id: PLN-0091
|
||||
ticket: variable-tile-bank-palette-serialization
|
||||
title: Variable Glyph Palette Tests, Fixtures, and Final Validation
|
||||
status: done
|
||||
created: 2026-07-14
|
||||
completed: 2026-07-14
|
||||
ref_decisions:
|
||||
- DEC-0038
|
||||
tags:
|
||||
- tests
|
||||
- fixtures
|
||||
- validation
|
||||
- glyph-bank
|
||||
- palette-serialization
|
||||
---
|
||||
|
||||
## Objective
|
||||
|
||||
Update tests and fixtures to prove Studio/packer emit runtime-conforming
|
||||
variable glyph palette payloads and contain no stale fixed-padding assumptions.
|
||||
|
||||
## Background
|
||||
|
||||
`DEC-0038` requires downstream fixture coverage for `palette_count = 1`, an
|
||||
intermediate count, and `palette_count = 64`, plus producer validation for
|
||||
metadata/payload mismatch. Earlier tests still assert `palette_count = 64`,
|
||||
4096-byte palette blocks, and fixed glyph payload sizes.
|
||||
|
||||
## Scope
|
||||
|
||||
### Included
|
||||
|
||||
- Update packer unit tests and integration-style workspace tests.
|
||||
- Update packer fixture `asset.json` files and expected runtime payload checks.
|
||||
- Update Studio tests only where Studio projections or UI logic expose
|
||||
effective palette count.
|
||||
- Run focused and broad validation.
|
||||
|
||||
### Excluded
|
||||
|
||||
- Runtime repository tests.
|
||||
- New feature design.
|
||||
- Palette remapping behavior.
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1 - Update packer parser and metadata tests
|
||||
|
||||
**What:** Prove effective `palette_count` validation.
|
||||
|
||||
**How:** Add tests for `palette_count = 1`, intermediate counts, `64`,
|
||||
duplicate/sparse direct identity behavior, and rejection above `64`.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/PackerAssetDeclarationParserTest.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/repositories/PackerGlyphBankWalkerTest.java`
|
||||
|
||||
### Step 2 - Update payload and asset table tests
|
||||
|
||||
**What:** Prove variable payload lengths and size formulas.
|
||||
|
||||
**How:** Replace fixed 4096-byte expectations with
|
||||
`palette_count * 16 * 4`. Assert `size`, `decoded_size`, payload offsets, and
|
||||
RGBA bytes for several counts.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/FileSystemPackerWorkspaceServiceTest.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/repositories/PackerRuntimeAssetMaterializerTest.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/PackerRuntimePatchServiceTest.java`
|
||||
- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/PackerRuntimeRegistryTest.java`
|
||||
|
||||
### Step 3 - Update fixtures
|
||||
|
||||
**What:** Replace stale fixed-padding fixtures.
|
||||
|
||||
**How:** Regenerate or edit packer test fixtures so at least one glyph bank uses
|
||||
`palette_count = 1`, one uses an intermediate count, and one uses `64`.
|
||||
Fixtures with fixed 64 padding are valid only when metadata says
|
||||
`palette_count = 64`.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-packer/prometeu-packer-v1/src/test/resources/fixtures/**/asset.json`
|
||||
- Related binary or generated expected payload fixtures under packer test
|
||||
resources.
|
||||
|
||||
### Step 4 - Update Studio tests
|
||||
|
||||
**What:** Cover Studio-facing projection changes.
|
||||
|
||||
**How:** Adjust tests only where Studio surfaces effective palette counts or
|
||||
metadata. Keep color rendering assertions focused on `rgba8888`.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `prometeu-studio/src/test/java/p/studio/workspaces/assets/details/**`
|
||||
|
||||
### Step 5 - Run validation and residue scans
|
||||
|
||||
**What:** Prove no normal-path fixed-padding residue remains.
|
||||
|
||||
**How:** Run relevant Gradle tests and search normal specs/code/tests/fixtures
|
||||
for stale `palette_count = 64`, `4096`, fixed `64 * 16 * 4`, `GLYPH/indexed_v2`,
|
||||
and sparse remapping language. Classify any remaining match as historical,
|
||||
max-bound, or a bug.
|
||||
|
||||
**File(s):**
|
||||
|
||||
- `docs/specs/packer/**`
|
||||
- `docs/specs/studio/**`
|
||||
- `prometeu-packer/**`
|
||||
- `prometeu-studio/**`
|
||||
|
||||
## Test Requirements
|
||||
|
||||
### Unit Tests
|
||||
|
||||
- Packer parser, walker, materializer, details/read, and workspace service tests
|
||||
pass.
|
||||
- Studio asset details tests pass where touched.
|
||||
|
||||
### Integration Tests
|
||||
|
||||
- Packer workspace build/materialization tests pass.
|
||||
- Repository build or narrow Studio/packer build validation passes.
|
||||
|
||||
### Manual Verification
|
||||
|
||||
- Residue scan finds no normal-path fixed-padding contract text or code.
|
||||
- `discussion validate` passes.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [x] Tests cover `palette_count = 1`, an intermediate count, and `64`.
|
||||
- [x] Tests cover variable `size` and `decoded_size`.
|
||||
- [x] Tests cover emitted palette byte length and RGBA order.
|
||||
- [x] Tests cover metadata/payload mismatch rejection or producer validation.
|
||||
- [x] Fixtures no longer rely on fixed 64-palette padding unless count is `64`.
|
||||
- [x] Validation commands pass.
|
||||
- [x] Residue scan results are clean or explicitly classified.
|
||||
|
||||
## Execution Notes
|
||||
|
||||
- Added packer workspace coverage for `palette_count = 1` and intermediate
|
||||
`palette_count = 7`.
|
||||
- Existing fixture and build paths continue to cover `palette_count = 64` where
|
||||
a max-count payload is intended.
|
||||
- Added parser coverage rejecting palette declaration index `64`, preserving
|
||||
the v1 maximum effective count of `64` through direct ids `0..63`.
|
||||
- `:prometeu-packer:prometeu-packer-v1:test` passed.
|
||||
- `./gradlew build` passed.
|
||||
- Residue scan found only intentional normative statements rejecting
|
||||
`convertedRgb565`, `GLYPH/indexed_v2`, fixed-padding compatibility, and
|
||||
sparse-to-dense remapping.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Depends on `PLN-0087`, `PLN-0088`, `PLN-0089`, and `PLN-0090`.
|
||||
|
||||
## Risks
|
||||
|
||||
- Generated project fixtures may require regeneration rather than manual edits.
|
||||
- Broad residue scans may include historical discussions; scope final checks to
|
||||
active specs, code, tests, and fixtures.
|
||||
Loading…
x
Reference in New Issue
Block a user