274 lines
13 KiB
Markdown
274 lines
13 KiB
Markdown
---
|
|
id: AGD-0041
|
|
ticket: studio-packer-rgba8888-asset-pipeline
|
|
title: Agenda - Studio and Packer RGBA8888 Asset Pipeline Alignment
|
|
status: accepted
|
|
created: 2026-05-23
|
|
resolved: 2026-05-23
|
|
decision: DEC-0037
|
|
tags:
|
|
- studio
|
|
- packer
|
|
- assets
|
|
- glyph-bank
|
|
- palette
|
|
- rgba8888
|
|
- runtime-alignment
|
|
---
|
|
|
|
## Pain
|
|
|
|
Domain owner: `studio`, with direct subdomain ownership in `packer` and
|
|
cross-domain dependency on `runtime`.
|
|
|
|
The runtime RGBA8888 migration changes the color contract underneath the Studio
|
|
asset pipeline. Runtime `DEC-0029` says RGBA8888 is the single canonical logical
|
|
color and physical framebuffer format, and that asset packages must encode
|
|
palettes as RGBA8888 without preserving RGB565 compatibility.
|
|
|
|
Studio still carries RGB565 in the packer-facing asset pipeline:
|
|
|
|
- `docs/specs/packer/4. Build Artifacts and Deterministic Packing Specification.md`
|
|
defines `GLYPH/indexed_v1` palette payloads as `64 * 16 * 2` bytes of
|
|
little-endian `RGB565` values.
|
|
- `PackerPaletteV1` stores both `originalArgb8888` and `convertedRgb565`.
|
|
- `PackerGlyphBankWalker` drops partial alpha, treats alpha 0 and magenta as
|
|
transparent index `0`, stores only RGB identity for palette lookup, and
|
|
converts palette colors to RGB565.
|
|
- `PackerAssetDetailsService`, `PackerReadMessageMapper`, test fixtures, and
|
|
project `asset.json` files expose `convertedRgb565` as normal pipeline data.
|
|
|
|
The problem is not only changing one serializer. The Studio/packer side must
|
|
decide how authoring metadata, palette UI/data, emitted `assets.pa`, tests, and
|
|
existing project fixtures align with runtime RGBA channel order and meaningful
|
|
alpha.
|
|
|
|
## Context
|
|
|
|
Runtime discussion context:
|
|
|
|
- `../runtime/discussion/workflow/agendas/AGD-0037-rgba8888-framebuffer-and-pixel-format-direction.md`
|
|
was consulted as the originating discussion.
|
|
- `../runtime/discussion/workflow/decisions/DEC-0029-rgba8888-runtime-pixel-format-contract.md`
|
|
is accepted and normative for runtime.
|
|
- Runtime plans already split execution across specs, HAL/ABI, renderer,
|
|
asset palettes/tooling, host presentation, and validation.
|
|
|
|
Relevant runtime invariants for this Studio discussion:
|
|
|
|
- raw color values use RGBA channel order;
|
|
- asset package palettes must be RGBA8888;
|
|
- old RGB565 palette assets are not compatible runtime input;
|
|
- indexed tile/sprite payloads may remain indexed/paletized;
|
|
- transparency is represented by alpha in the resolved palette entry, not by
|
|
reserving palette index `0` as a special transparent index;
|
|
- RGB565 helpers may exist only as temporary migration utilities, not the
|
|
normal runtime path.
|
|
|
|
Relevant Studio/packer state:
|
|
|
|
- `assets.pa` is the authoritative runtime-facing artifact owned by the packer.
|
|
- `output.pipeline` is tooling-only by default, but current glyph palette data
|
|
lives there and is used by packer details/read flows.
|
|
- `GLYPH/indexed_v1` currently emits a fixed 256x256 packed `u4` pixel plane
|
|
plus a fixed 64-palette RGB565 block.
|
|
- `DSC-0005` is still open around variable tile-bank palette serialization.
|
|
That discussion optimizes fixed-vs-variable palette count. RGBA8888 changes
|
|
the color encoding and transparency semantics first, so it should supersede
|
|
or reframe any RGB565 assumptions before variable palette work continues.
|
|
- Studio scene publication currently carries `palette_id` in scene pack
|
|
requests. Scene payload shape is mostly unaffected by color format, but scene
|
|
previews, palette defaults, validation, and any editor-visible palette data
|
|
must remain consistent with the glyph-bank contract.
|
|
|
|
## Open Questions
|
|
|
|
- [x] Should Studio keep the runtime-facing format name `GLYPH/indexed_v1` and
|
|
make it an incompatible v1 contract update, or should packer emit a new
|
|
explicit format/version such as `GLYPH/indexed_rgba8888_v1`?
|
|
- Keep `GLYPH/indexed_v1`. The structural change is in palette encoding; the
|
|
remaining glyph payload model stays stable.
|
|
- [x] What is the canonical authoring-side palette field name: keep
|
|
`originalArgb8888`, rename to `rgba8888`, or store structured channel data?
|
|
- Use `rgba8888` unless the decision stage finds a concrete tooling reason to
|
|
choose a more explicit variant.
|
|
- [x] How should Java `BufferedImage` ARGB input be converted to runtime RGBA
|
|
raw values without confusing storage order, JSON numeric representation, or
|
|
signed `int` display in tooling?
|
|
- Convert ARGB input to RGBA output directly at the packer boundary.
|
|
- [x] Does palette index `0` remain an ordinary palette slot immediately, as
|
|
runtime `DEC-0029` requires, or does Studio need a temporary migration step to
|
|
rewrite existing transparent-index assets into alpha-bearing palette entries?
|
|
- Palette index `0` becomes an ordinary palette slot. Glyph palettes therefore
|
|
have 16 usable colors, not 15 plus a reserved transparent index.
|
|
- [x] Should magenta color-key support disappear from Studio authoring now, or
|
|
survive only as an explicit import/conversion helper outside the normal pack
|
|
path?
|
|
- Magenta color-key support should disappear completely.
|
|
- [x] Should partial alpha in PNG tiles become first-class palette data, or
|
|
should the packer still reject/diagnose partial alpha until renderer behavior
|
|
is fully proven?
|
|
- Partial alpha becomes valid palette data now. Existing validations and
|
|
warnings that flatten or reject partial alpha should be removed.
|
|
- [x] Which existing fixtures and sample projects should be regenerated versus
|
|
deleted because they encode RGB565-specific expectations?
|
|
- `main` and `fragments` will be regenerated manually later; they should not
|
|
block the Studio/packer decision.
|
|
- [x] How should this agenda relate to `DSC-0005`: close it as superseded,
|
|
revise it after RGBA8888, or keep it open as a later palette-count
|
|
optimization?
|
|
- `DSC-0005` remains a later step. RGBA8888 should not absorb variable
|
|
palette-count serialization.
|
|
|
|
## Options
|
|
|
|
### Option A - Minimal serializer swap inside current names
|
|
|
|
- **Approach:** Keep current public names and `GLYPH/indexed_v1`, replace the
|
|
palette block with fixed `64 * 16 * 4` RGBA8888 entries, remove
|
|
`convertedRgb565`, and update tests/specs in place.
|
|
- **Pro:** Smallest naming churn and likely the fastest path to unblock runtime
|
|
asset decode.
|
|
- **Con:** The `v1` label would silently change binary meaning, which is risky
|
|
for fixtures, docs, and any stale build output.
|
|
- **Maintainability:** Medium. Fast, but it relies on the repository accepting a
|
|
coordinated breaking change with no compatibility ambiguity.
|
|
|
|
### Option B - Explicit RGBA8888 glyph payload format
|
|
|
|
- **Approach:** Add an explicit runtime-facing glyph format/version for the
|
|
RGBA8888 palette payload, retire RGB565 output from the normal pack path, and
|
|
update asset declarations, specs, materialization, tests, fixtures, and sample
|
|
projects to the new format.
|
|
- **Pro:** Makes the breaking contract visible in file format names, tests, and
|
|
diagnostics while still obeying the runtime decision not to support RGB565 as
|
|
compatible input.
|
|
- **Con:** More code and fixture churn; requires clear migration handling for
|
|
stale project declarations and generated build artifacts.
|
|
- **Maintainability:** Strong. The format boundary becomes explicit and easier
|
|
to audit.
|
|
|
|
### Option C - Broaden the wave into full palette model redesign
|
|
|
|
- **Approach:** Use the RGBA8888 migration to redesign palette count, sparse vs
|
|
dense indices, material palettes, import/export, alpha authoring UI, and scene
|
|
palette defaults in one decision.
|
|
- **Pro:** Could produce a cleaner long-term asset model and resolve `DSC-0005`
|
|
at the same time.
|
|
- **Con:** Mixes a mandatory runtime alignment with optional model improvements,
|
|
increasing risk and delaying the renderer/asset migration.
|
|
- **Maintainability:** Weak for this wave. Better reserved for follow-up after
|
|
the RGBA8888 contract is stable.
|
|
|
|
## Discussion
|
|
|
|
The discussion converged toward an in-place `GLYPH/indexed_v1` structural
|
|
update rather than a new format name. This keeps the glyph-bank identity stable:
|
|
indexed pixels, fixed emitted sheet shape, scene `palette_id` references, and
|
|
the broad runtime glyph-bank model remain the same. The incompatible change is
|
|
the palette block and palette metadata moving from RGB565-derived values to raw
|
|
RGBA8888.
|
|
|
|
The authoring/read projection should expose `rgba8888` as the canonical palette
|
|
field. Java image inputs may still arrive as ARGB through `BufferedImage`, but
|
|
that is an input representation only. The packer boundary converts ARGB to
|
|
runtime RGBA and the rest of the pipeline should speak RGBA8888.
|
|
|
|
Palette index `0` is no longer special. It becomes a normal usable palette
|
|
entry, which gives glyph palettes 16 usable colors. Transparency comes from the
|
|
alpha byte in the RGBA8888 palette value. As a consequence, the old magenta
|
|
color-key behavior should be removed completely, not retained as a normal
|
|
authoring shortcut or hidden compatibility rule.
|
|
|
|
Partial alpha is valid data in this model. The packer should preserve it in the
|
|
palette instead of warning, flattening, or rejecting it. Existing validations
|
|
around partial alpha and the 15-color limit are therefore stale and should be
|
|
rewritten around the new 16-entry RGBA palette contract.
|
|
|
|
Existing sample projects and fixtures that still carry RGB565 assumptions are
|
|
not part of the discussion blocker. `main` and `fragments` will be regenerated
|
|
later. `DSC-0005` remains a separate future discussion for palette-count
|
|
serialization and should not be folded into this RGBA8888 wave.
|
|
|
|
## Tradeoffs
|
|
|
|
### Compatibility vs explicit break
|
|
|
|
Runtime `DEC-0029` already rejects RGB565 compatibility for this migration.
|
|
Studio therefore should not preserve RGB565 input as a normal path. The open
|
|
tradeoff is whether the packer should make the break visible through a new
|
|
format/version or simply mutate the existing v1 meaning.
|
|
|
|
### Authoring convenience vs runtime truth
|
|
|
|
Java image tooling naturally reads pixels as ARGB ints. Runtime wants raw RGBA
|
|
channel order. Studio can keep ARGB only as an import-side implementation detail,
|
|
but packer output, public metadata, and tests need one unambiguous RGBA8888
|
|
representation.
|
|
|
|
### Indexed art identity vs alpha semantics
|
|
|
|
The indexed/palette model can remain. What changes is that every palette entry,
|
|
including index `0`, should be a real RGBA color. Transparent pixels should be
|
|
encoded by alpha, not by a hardwired index rule or magenta color key.
|
|
|
|
### Scope control vs complete cleanup
|
|
|
|
It is tempting to combine RGBA8888 with variable palette serialization from
|
|
`DSC-0005`. That should be resisted unless the decision explicitly expands
|
|
scope. RGBA8888 changes bytes per palette entry and transparency semantics;
|
|
palette count optimization is a separate axis.
|
|
|
|
## Recommendation
|
|
|
|
Adopt a refined Option A.
|
|
|
|
The Studio/packer decision should keep `GLYPH/indexed_v1` as the runtime-facing
|
|
format name, but redefine its palette block and palette metadata around
|
|
RGBA8888. This is an intentional structural break in the palette contract, not
|
|
a new glyph-bank format.
|
|
|
|
The recommended shape for the decision is:
|
|
|
|
1. emit palette entries as raw RGBA8888 values in runtime RGBA channel order;
|
|
2. replace `convertedRgb565` with canonical `rgba8888` data in authoring and
|
|
read/detail projections;
|
|
3. treat Java/PNG ARGB as an input decoding detail and convert deliberately at
|
|
the packer boundary;
|
|
4. make palette index `0` ordinary, yielding 16 usable palette entries;
|
|
5. represent transparency and partial transparency only through RGBA alpha;
|
|
6. remove magenta color-key behavior completely;
|
|
7. remove partial-alpha flattening/rejection and preserve partial alpha as
|
|
valid palette data;
|
|
8. preserve fixed 64-palette serialization for this wave unless a decision
|
|
explicitly revises `DSC-0005`;
|
|
9. regenerate or rewrite RGB565 fixtures instead of supporting stale RGB565
|
|
assets at runtime.
|
|
|
|
## Next Step
|
|
|
|
The agenda is ready to move to decision if the refined recommendation is
|
|
accepted.
|
|
|
|
The next artifact should be a Studio/packer decision that references runtime
|
|
`DEC-0029`, leaves `DSC-0005` for a later palette-count step, and defines
|
|
propagation targets for:
|
|
|
|
- `docs/specs/packer`;
|
|
- `docs/specs/studio`;
|
|
- `prometeu-packer` models, walkers, serializers, services, fixtures, and
|
|
tests;
|
|
- sample project assets;
|
|
- any Studio asset workspace UI/read projections that expose palette data.
|
|
|
|
## Resolution
|
|
|
|
Accepted on 2026-05-23.
|
|
|
|
The discussion is closed in favor of decision `DEC-0037`. The accepted
|
|
direction keeps `GLYPH/indexed_v1`, moves its palette contract to RGBA8888,
|
|
uses `rgba8888` as the canonical palette field, makes palette index `0`
|
|
ordinary, removes magenta color-key behavior completely, accepts partial alpha
|
|
as valid palette data, and leaves `DSC-0005` for a later palette-count
|
|
serialization step.
|