13 KiB
Tile Bank Packing Materialization Agenda
Status: Open
Domain Owner: docs/packer
Cross-Domain Impact: ../runtime, docs/studio
Purpose
Convergir a discussão sobre como um asset tile bank deve ser materializado durante o packing para produzir payload runtime-facing válido dentro de assets.pa.
Esta agenda não trata do workflow operacional do Pack Wizard.
Ela trata do contrato técnico de materialização do formato TILES/indexed_v1:
- quais arquivos entram no pack;
- como eles viram payload binário final;
- quais campos do
asset_tablesão derivados; - quais metadados convergem para
AssetEntry.metadata; - e quais invariantes devem falhar o build.
Problem
O repositório já tem base suficiente para:
- descobrir arquivos relevantes de
tile bank; - validar metadados mínimos como
tile_size; - construir snapshots runtime-backed;
- definir
assets.pacomo artefato autoritativo do runtime.
Mas ainda não existe decisão formal sobre a materialização final de tile bank no pack.
Hoje falta fechar, pelo menos:
- qual é o payload binário efetivamente emitido para um
tile bank; - como múltiplos artifacts selecionados são agregados no payload final;
- como
bank_type,codec,size,decoded_sizeemetadatasão derivados para a entrada runtime; - quais dados ficam em
AssetEntry.metadataversus quais permanecem detalhe interno de pipeline; - quais condições tornam o pack inválido para esse formato.
Sem isso, o packWorkspace(...) pode até ganhar semântica operacional correta, mas ainda ficará sem contrato suficiente para produzir assets.pa conformat para tile bank.
Context
O contrato upstream já impõe limites claros:
assets.paé o artefato runtime-facing autoritativo:../specs/1. Domain and Artifact Boundary Specification.mdasset_tableé determinística porasset_id, offsets são relativos ao payload region e metadata converge para um sink único:../specs/4. Build Artifacts and Deterministic Packing Specification.md- o runtime espera
assets.paautocontido comasset_tableepreloadválidos:../../../runtime/docs/runtime/specs/13-cartridge.md - o runtime consome
AssetEntry { asset_id, asset_name, bank_type, offset, size, decoded_size, codec, metadata }:../../../runtime/docs/runtime/specs/15-asset-management.md
Contexto atual de código:
PackerAssetWalkerjá reconheceOutputFormatCatalog.TILES_INDEXED_V1;PackerTileBankWalkerjá produz probes/metadata family-relevant;- o snapshot atual já consegue expor arquivos candidatos e metadata de walk;
- ainda não existe materialização final de payload de
tile bankdentro deassets.pa.
Consumer baseline now confirmed in ../runtime:
TILESnow usescodec = NONEas the runtime-facing v1 baseline;- serialized tile pixels are packed
u4palette indices in payload order; - the runtime expands those packed indices into one
u8logical index per pixel in memory after decode; - tile-bank palettes are serialized as
RGB565u16values in little-endian order; - runtime-facing v1 uses
64palettes per tile bank; - the runtime loader currently requires the following metadata fields for tile banks:
tile_sizewidthheightpalette_count
- for v1,
palette_countmust be64; - for v1, the serialized tile-bank payload is:
- packed indexed pixels for the full sheet, using
ceil(width * height / 2)bytes; - one palette block of
64 * 16 * 2 = 2048bytes;
- packed indexed pixels for the full sheet, using
- for v1, the runtime-side size expectations are:
size = ceil(width * height / 2) + 2048decoded_size = (width * height) + 2048
- for the producer-side contract discussed here,
tile_id = 0remains valid and must not be reserved away by the packer.
Relevant confirmed runtime references:
../../../runtime/docs/runtime/specs/15-asset-management.md../../../runtime/docs/runtime/specs/04-gfx-peripheral.md../../../runtime/crates/console/prometeu-drivers/src/asset.rs../../../runtime/crates/console/prometeu-hal/src/tile_bank.rs- tilemap empty-cell semantics remain under active runtime discussion and must not currently force the packer to reserve
tile_id = 0:../../../runtime/docs/runtime/agendas/023-tilemap-empty-cell-vs-tile-id-zero.md
Isso significa que o problema agora não é descoberta de arquivos.
O lado consumidor já está suficientemente claro.
O problema agora é fechar o contrato produtor tile bank -> runtime asset entry + payload bytes no packer sem contradizer esse baseline runtime.
Options
Option A - Concatenate selected tile artifacts as a simple raw stream
Cada artifact selecionado do tile bank vira um segmento binário simples, e o payload final do asset é a concatenação determinística desses segmentos.
metadata carrega apenas o mínimo necessário para o runtime interpretar o asset.
Option B - Emit one canonical tile-bank payload plus normalized runtime metadata
Os artifacts selecionados são primeiro normalizados para um modelo canônico de tile bank, e então o packer emite:
- um único payload binário canônico para o asset;
- um conjunto fechado de campos runtime-facing em
AssetEntry.metadata.
Qualquer detalhe interno adicional de pipeline fica fora do contrato runtime principal ou vai apenas para tooling metadata.
Option C - Preserve rich per-artifact structure directly in runtime metadata
O packer mantém estrutura mais rica de artifacts individuais no próprio AssetEntry.metadata, expondo para o runtime detalhes mais próximos da pipeline de build.
Tradeoffs
- Option A é a implementação mais simples, mas corre risco de deixar semântica demais implícita no consumidor.
- Option A também pode dificultar compatibilidade futura se a concatenação simples não codificar claramente limites, forma lógica ou derivação de
decoded_size. - Option B exige fechar um modelo canônico do
tile bank, mas produz o contrato mais limpo entre packer e runtime. - Option B também respeita melhor a regra já vigente de convergência para
AssetEntry.metadatasem transformar metadata runtime em espelho da pipeline. - Option C pode parecer flexível no curto prazo, mas mistura detalhe de pipeline com contrato runtime e aumenta acoplamento.
- Option C tensiona diretamente o guardrail já documentado de que
asset_table[].metadatanão deve virar depósito arbitrário de estrutura interna.
Recommendation
Adotar Option B.
O primeiro formato de packing a ser fechado deve ter payload canônico e metadata runtime-facing normalizada.
Payload Recommendation
O tile bank deve produzir um payload binário único por asset incluído no build.
Regras recomendadas:
- o payload é derivado apenas dos artifacts selecionados que realmente entram no build atual;
- a ordem de agregação dos artifacts deve ser determinística by
artifacts[*].index; - for v1,
1 artifact = 1 tile; - for the current target, the canonical tile-bank sheet is always
256 x 256; - tile placement inside that fixed sheet is row-major;
tile_idis the linear row-major slot and therefore matches the normalizedartifacts[*].index;- resulting capacity is therefore:
tile_size = 8->32 x 32 = 1024tilestile_size = 16->16 x 16 = 256tilestile_size = 32->8 x 8 = 64tiles
- o payload final do asset deve ter fronteiras e interpretação definidas pelo próprio contrato do formato, não por convenção incidental de concatenação;
- para
TILES/indexed_v1, o payload v1 já deve assumir:- plano de pixels packed
u4; - bloco de paletas
64 * 16 * u16;
- plano de pixels packed
- palettes must always be materialized to
RGB565during pack emission; sizedeve representar o tamanho emitido no payload region;decoded_sizedeve seguir a convenção runtime já confirmada: tamanho expandido dos indices em memória mais o bloco de paletas runtime-facing.
Runtime Entry Recommendation
Cada tile bank emitido para o runtime deve preencher, no mínimo:
asset_idasset_namebank_type = TILESoffsetsizedecoded_sizecodecmetadata
O contrato de bank_type, codec e decoded_size não deve ser deixado implícito no packer implementation detail.
Baseline now fixed by the runtime consumer:
bank_type = TILEScodec = NONE- metadata mínima obrigatória:
tile_sizewidthheightpalette_count = 64
widthandheightare bank-sheet helpers, not per-artifact dimensions- with the current v1 target, the emitted bank sheet is fixed at
256 x 256 - producer-side metadata normalization must emit what the consumer requires while preserving segmented authoring meaning:
asset.json.output.metadata->AssetEntry.metadataasset.json.output.codec_configuration->AssetEntry.metadata.codecasset.json.output.pipeline->AssetEntry.metadata.pipeline
Metadata Recommendation
AssetEntry.metadata deve receber apenas os campos runtime-consumable e format-relevant.
Direção inicial recomendada:
- metadados declarativos como
tile_sizeentram no sink runtime; - metadados derivados necessários para leitura correta do runtime entram no sink runtime, pelo menos:
widthheightpalette_count;
AssetEntry.metadatashould aggregate normalized maps using this structure:asset.json.output.metadata->metadataasset.json.output.codec_configuration->metadata.codecasset.json.output.pipeline->metadata.pipeline
- bank palettes are declared in
asset.json.output.pipeline.palettesusing explicit{ index, palette }entries and emitted in ascending numericindexorder; - any tile in the bank may be rendered with any palette in the bank;
- palette assignment is therefore not a per-artifact packing contract and remains a runtime draw-time concern;
- the packer must nevertheless validate whether the declared bank palette set safely covers the indices used by packed tiles.
- detalhes de pipeline úteis apenas para inspeção e tooling não devem dominar
AssetEntry.metadata; - quando um detalhe interno for necessário apenas para tooling, ele deve preferir companion tooling data em vez de inflar o contrato runtime.
Failure Recommendation
O build de tile bank deve falhar quando qualquer uma das seguintes condições acontecer:
- não existir conjunto suficiente de artifacts selecionados para materialização válida;
- o metadata declarativo obrigatório do formato estiver ausente ou inválido;
- a normalização dos artifacts para o payload canônico falhar;
- houver colisão ou ambiguidade ao convergir metadata runtime-facing;
- o packer não conseguir derivar de forma determinística os campos exigidos para a entry runtime.
Additional first-wave diagnostic expectations:
- duplicate
artifacts[*].indexisblocking; - gap in normalized
artifacts[*].indexordering isblocking; - sheet-capacity overflow for the fixed
256 x 256target isblocking; - bank without declared palettes in
asset.json.output.pipeline.palettesisblocking; - declared palette list above
64isblocking; - malformed palette declarations are
blocking; - tiles that use fragile indices, meaning indices not represented safely across the full declared bank palette set, emit a
WARNING; - that fragile-index warning is advisory in the first wave and does not block pack by itself unless later promoted by decision.
Packing Boundary Recommendation
O seletor de packing para tile bank deve operar sobre os probes já descobertos pelo walker family-oriented.
Regras:
- o walker continua generalista e orientado à family;
- a seleção do que entra no payload final acontece na policy/materialization layer de packing;
- somente probes do asset registrado, incluído no build, e efetivamente selecionados pelo contrato do formato entram na materialização final;
- quando o
PackerRuntimeMaterializationConfigestiver emPACKING, esses probes relevantes devem carregar bytes opcionais preenchidos para congelar o input do pack. - palette declarations in
asset.json.output.pipeline.palettescarry explicit semantic identity throughindex; - palette order is ascending numeric
index, never raw array position; - palette ids are the normalized declared
indexvalues from that pipeline palette list; - all tiles in the bank may use any palette declared in the bank;
- palette selection is a runtime draw concern, not a tile-payload embedding concern.
Open Questions
- None at this stage for the tile-bank v1 producer contract.
Expected Follow-up
- Converter esta agenda em uma
decisiondedocs/packerpara materialização detile bank. - Propagar o contrato resultante para:
docs/packer/specs/4. Build Artifacts and Deterministic Packing Specification.md- specs runtime relevantes em
../runtime
- Planejar PR de implementação do materializador de
tile bankemprometeu-packer-v1. - Adicionar testes de conformance do formato:
artifacts -> payload -> asset_table entry -> runtime-read assumptions.