prometeu-studio/docs/packer/agendas/Tile Bank Packing Materialization Agenda.md
2026-03-24 13:42:55 +00:00

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_table são derivados;
  • quais metadados convergem para AssetEntry.metadata;
  • e quais invariantes devem falhar o build.

Problem

O repositório já tem base suficiente para:

  1. descobrir arquivos relevantes de tile bank;
  2. validar metadados mínimos como tile_size;
  3. construir snapshots runtime-backed;
  4. definir assets.pa como 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_size e metadata são derivados para a entrada runtime;
  • quais dados ficam em AssetEntry.metadata versus 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:

Contexto atual de código:

  • PackerAssetWalker já reconhece OutputFormatCatalog.TILES_INDEXED_V1;
  • PackerTileBankWalker já 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 bank dentro de assets.pa.

Consumer baseline now confirmed in ../runtime:

  • TILES now uses codec = NONE as the runtime-facing v1 baseline;
  • serialized tile pixels are packed u4 palette indices in payload order;
  • the runtime expands those packed indices into one u8 logical index per pixel in memory after decode;
  • tile-bank palettes are serialized as RGB565 u16 values in little-endian order;
  • runtime-facing v1 uses 64 palettes per tile bank;
  • the runtime loader currently requires the following metadata fields for tile banks:
    • tile_size
    • width
    • height
    • palette_count
  • for v1, palette_count must be 64;
  • for v1, the serialized tile-bank payload is:
    1. packed indexed pixels for the full sheet, using ceil(width * height / 2) bytes;
    2. one palette block of 64 * 16 * 2 = 2048 bytes;
  • for v1, the runtime-side size expectations are:
    • size = ceil(width * height / 2) + 2048
    • decoded_size = (width * height) + 2048
  • for the producer-side contract discussed here, tile_id = 0 remains valid and must not be reserved away by the packer.

Relevant confirmed runtime references:

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.metadata sem 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[].metadata nã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;
  • 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:
    1. plano de pixels packed u4;
    2. bloco de paletas 64 * 16 * u16;
  • palettes must always be materialized to RGB565 during pack emission;
  • size deve representar o tamanho emitido no payload region;
  • decoded_size deve 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_id
  • asset_name
  • bank_type = TILES
  • offset
  • size
  • decoded_size
  • codec
  • metadata

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 = TILES
  • codec = NONE
  • metadata mínima obrigatória:
    • tile_size
    • width
    • height
    • palette_count = 64
  • width and height are bank-sheet helpers, not per-artifact dimensions
  • with the current v1 target, the emitted bank sheet is fixed at 256 x 256

Metadata Recommendation

AssetEntry.metadata deve receber apenas os campos runtime-consumable e format-relevant.

Direção inicial recomendada:

  • metadados declarativos como tile_size entram no sink runtime;
  • metadados derivados necessários para leitura correta do runtime entram no sink runtime, pelo menos:
    • width
    • height
    • palette_count;
  • AssetEntry.metadata should aggregate normalized maps derived from:
    • asset.json.output.metadata
    • asset.json.output.codec_configuration
    • asset.json.output.pipeline;
  • bank palettes are declared in asset.json.output.pipeline.palettes using explicit { index, palette } entries and emitted in ascending numeric index order;
  • 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:

  1. não existir conjunto suficiente de artifacts selecionados para materialização válida;
  2. o metadata declarativo obrigatório do formato estiver ausente ou inválido;
  3. a normalização dos artifacts para o payload canônico falhar;
  4. houver colisão ou ambiguidade ao convergir metadata runtime-facing;
  5. o packer não conseguir derivar de forma determinística os campos exigidos para a entry runtime.

Additional first-wave diagnostic expectations:

  • bank without declared palettes in asset.json.output.pipeline.palettes must emit a diagnostic;
  • tile banks whose declared palette list exceeds 64 must fail;
  • tiles that use fragile indices, meaning indices not represented safely across the full declared bank palette set, should emit a WARNING;
  • that fragile-index warning is advisory in the first wave and should 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 PackerRuntimeMaterializationConfig estiver em PACKING, esses probes relevantes devem carregar bytes opcionais preenchidos para congelar o input do pack.
  • palette declarations in asset.json.output.pipeline.palettes carry explicit semantic identity through index;
  • palette order is ascending numeric index, never raw array position;
  • palette ids are the normalized declared index values 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

  1. Given the fixed 256 x 256 bank target, what is the canonical tile placement rule inside that sheet for tile_size = 8, 16, and 32?
  2. Which normalization diagnostics should be blocking versus warning specifically for:
    • artifact index gaps or duplicates
    • sheet capacity overflow
    • palette list overflow beyond 64
    • banks without declared palettes
    • fragile tile indices across the declared bank palette set?

Expected Follow-up

  1. Converter esta agenda em uma decision de docs/packer para materialização de tile bank.
  2. Propagar o contrato resultante para:
    • docs/packer/specs/4. Build Artifacts and Deterministic Packing Specification.md
    • specs runtime relevantes em ../runtime
  3. Planejar PR de implementação do materializador de tile bank em prometeu-packer-v1.
  4. Adicionar testes de conformance do formato: artifacts -> payload -> asset_table entry -> runtime-read assumptions.