221 lines
9.8 KiB
Markdown
221 lines
9.8 KiB
Markdown
---
|
|
id: AGD-0049
|
|
ticket: runtime-owned-variable-glyph-bank-palette-protocol
|
|
title: Runtime-Owned Variable Glyph Bank Palette Protocol
|
|
status: accepted
|
|
created: 2026-07-14
|
|
resolved: 2026-07-14
|
|
decision:
|
|
tags:
|
|
- runtime
|
|
- gfx
|
|
- assets
|
|
- glyph-bank
|
|
- palette-serialization
|
|
- protocol
|
|
---
|
|
|
|
## Contexto
|
|
|
|
A agenda `../studio/discussion/workflow/agendas/AGD-0005-variable-tile-bank-palette-serialization.md`
|
|
levantou o desperdicio do payload atual de `GLYPH/indexed_v1`: todo glyph bank
|
|
carrega `64 * 16 * 4 = 4096` bytes de paletas RGBA8888, mesmo quando o asset
|
|
usa poucas paletas.
|
|
|
|
Esse problema toca o `packer`, mas a decisao do protocolo pertence ao
|
|
`runtime`. A especificacao final deve ser definida aqui, no contrato runtime,
|
|
e o `packer` deve seguir a spec quando ela estiver pronta. A agenda de `studio`
|
|
serve como entrada factual e motivacao, nao como autoridade normativa sobre o
|
|
payload, a memoria residente ou a semantica de `palette_id`.
|
|
|
|
Estado atual no runtime:
|
|
|
|
- `docs/specs/runtime/15-asset-management.md` documenta `palette_count = 64`;
|
|
- `docs/specs/runtime/04-gfx-peripheral.md` documenta `palette_id` em `0..63`;
|
|
- `crates/console/prometeu-hal/src/glyph_bank.rs` materializa paletas como
|
|
`[[Color; 16]; 64]`;
|
|
- `crates/console/prometeu-drivers/src/asset.rs` rejeita metadata cujo
|
|
`palette_count` nao seja `64`;
|
|
- o decode de glyph bank le um bloco fixo de `64 * 16 * 4` bytes em
|
|
`assets.pa`;
|
|
- testes de asset e VM ainda calculam payload e decoded size com o bloco fixo.
|
|
|
|
Decisoes anteriores relevantes:
|
|
|
|
- `DSC-0022` estabeleceu `GlyphBank` como nome canonico do artefato grafico;
|
|
- `DSC-0037` estabeleceu RGBA8888 como contrato runtime, com alpha como dado de
|
|
cor e sem indice magico reservado.
|
|
|
|
## Problema
|
|
|
|
O runtime precisa decidir se `GLYPH/indexed_v1` continua sendo um contrato de
|
|
64 paletas fixas ou se passa a aceitar uma quantidade variavel de paletas
|
|
serializadas.
|
|
|
|
Essa decisao nao e apenas uma otimizacao de tamanho de cartucho. Ela muda:
|
|
|
|
- o significado de `palette_count`;
|
|
- a validacao de `palette_id`;
|
|
- a formula de `size` e `decoded_size`;
|
|
- a representacao residente de `GlyphBank`;
|
|
- o comportamento quando uma cena referencia uma paleta nao carregada;
|
|
- a fronteira entre contrato de asset, HAL, composer, testes e tooling.
|
|
|
|
## Pontos Criticos
|
|
|
|
- Autoridade: o runtime decide o protocolo publicado; o `packer` segue.
|
|
- Compatibilidade: o projeto ainda esta em v1, entao nao ha obrigacao
|
|
presumida de preservar o padding fixo antigo.
|
|
- Identidade: `palette_id` pode continuar sendo uma identidade direta ou pode
|
|
virar indice em uma tabela compactada, mas nao pode ter dois significados.
|
|
- Materializacao: economizar bytes no payload nao implica automaticamente
|
|
economizar memoria residente, mas manter uma tabela fixa pode preservar
|
|
semantica simples para renderizacao e cenas.
|
|
- Falhas: se `palette_id` apontar para uma paleta ausente, o runtime precisa
|
|
definir se isso falha no load, na composicao, ou se resolve para cor default.
|
|
- Propagacao: qualquer decisao precisa mover specs, decode, HAL, fixtures e
|
|
testes juntos, como ocorreu na migracao RGBA8888.
|
|
|
|
## Opcoes
|
|
|
|
### Opcao A - Manter 64 paletas fixas no protocolo runtime
|
|
|
|
- **Abordagem:** Preservar `palette_count = 64`, bloco fixo de 4096 bytes e
|
|
tabela residente fixa.
|
|
- **Pro:** Mantem decode, composicao e limites de `palette_id` simples.
|
|
- **Contra:** O runtime continua publicando um custo obrigatorio de payload que
|
|
nao representa a maioria dos assets.
|
|
- **Manutencao:** Boa para estabilidade local, fraca para alinhamento entre
|
|
metadata autoral e payload real.
|
|
|
|
### Opcao B - Payload variavel, memoria residente fixa de 64 slots
|
|
|
|
- **Abordagem:** Fazer `palette_count` representar o numero de paletas
|
|
serializadas, mas expandir para uma tabela residente fixa de 64 paletas no
|
|
load. Paletas nao serializadas ficam em valor default, e `palette_id` continua
|
|
sendo identidade direta `0..63`.
|
|
- **Pro:** Reduz payload mantendo o contrato de composicao e cena simples.
|
|
- **Contra:** Requer decidir se referencias a paletas nao serializadas sao
|
|
invalidas no load, invalidas na composicao ou simplesmente resolvem para a
|
|
paleta default.
|
|
- **Manutencao:** Boa se a spec declarar que `palette_count` mede somente o
|
|
prefixo serializado e que o runtime ainda materializa capacidade fixa.
|
|
|
|
### Opcao C - Payload variavel e memoria residente variavel
|
|
|
|
- **Abordagem:** Fazer `palette_count` controlar tanto o payload quanto a
|
|
quantidade residente de paletas. `palette_id >= palette_count` passa a ser
|
|
invalido para aquele glyph bank.
|
|
- **Pro:** O contrato fica mais fiel ao asset carregado e reduz memoria
|
|
residente por banco.
|
|
- **Contra:** A composicao precisa carregar limite por banco e transformar
|
|
validacao de `palette_id` em regra dependente do asset.
|
|
- **Manutencao:** Forte se o runtime quiser que o banco carregado seja a unica
|
|
fonte de verdade; mais invasiva no HAL/composer.
|
|
|
|
### Opcao D - Paletas compactadas com remapeamento de identidade
|
|
|
|
- **Abordagem:** Serializar somente paletas usadas em uma tabela densa e
|
|
introduzir um mapa entre identidade autoral/esparsa e indice residente.
|
|
- **Pro:** Pode minimizar payload mesmo quando indices autorais sao esparsos.
|
|
- **Contra:** Introduz um segundo contrato de identidade e exige metadata extra
|
|
ou reescrita de cenas/assets dependentes.
|
|
- **Manutencao:** Fraca para v1 unless haja uma necessidade clara de preservar
|
|
indices esparsos sem preencher lacunas.
|
|
|
|
## Sugestao / Recomendacao
|
|
|
|
Adotar a **Opcao C**.
|
|
|
|
`palette_count` deve ser o contrato real do glyph bank carregado: se o payload
|
|
serializa `N` paletas, o runtime materializa `N` paletas e `palette_id >= N`
|
|
e invalido para aquele banco.
|
|
|
|
A **Opcao B** fica descartada porque manter memoria residente fixa preservaria
|
|
uma segunda nocao de capacidade que nao corresponde ao asset carregado. A
|
|
**Opcao D** tambem fica descartada porque introduzir remapeamento de identidade
|
|
transformaria um protocolo simples em uma camada adicional de metadata.
|
|
|
|
## Perguntas em Aberto
|
|
|
|
- [x] `palette_count` deve definir tambem a quantidade residente de paletas, ou
|
|
apenas o prefixo serializado no payload?
|
|
- Resolucao: define tambem a quantidade residente.
|
|
- [x] `palette_id` deve ser validado contra `palette_count` por glyph bank ou
|
|
continuar limitado globalmente a `0..63`?
|
|
- Resolucao: validar contra `palette_count` por glyph bank, mantendo um
|
|
limite maximo global separado.
|
|
- [x] Quando uma cena referencia uma paleta ausente, o erro deve ocorrer no
|
|
load do glyph bank, no load/decode da scene, ou na composicao?
|
|
- Resolucao: o glyph bank carrega se o proprio payload e valido. A referencia
|
|
ausente falha quando uma scene/sprite tenta usar `palette_id >=
|
|
palette_count` contra o banco real; o runtime deve tratar isso como erro
|
|
explicito, nao como fallback silencioso para transparente/default.
|
|
- [x] O limite maximo de paletas por glyph bank continua sendo `64` em v1?
|
|
- Resolucao: sim. A variabilidade deve reduzir `N`, nao abrir uma
|
|
quantidade ilimitada de paletas em v1.
|
|
- [x] `decoded_size` deve contar apenas paletas materializadas ou manter alguma
|
|
nocao de capacidade residente?
|
|
- Resolucao: contar apenas paletas materializadas:
|
|
`width * height + palette_count * 16 * 4`.
|
|
- [x] A mudanca deve manter o nome `GLYPH/indexed_v1` como correcao
|
|
incompativel de v1, ou o runtime exige uma nova versao de payload?
|
|
- Resolucao: manter `GLYPH/indexed_v1` como correcao incompativel, sem
|
|
compatibilidade com o padding fixo antigo.
|
|
|
|
## Criterio para Encerrar
|
|
|
|
A agenda pode virar decisao quando o runtime escolher:
|
|
|
|
- o significado normativo de `palette_count`;
|
|
- a relacao entre payload serializado e memoria residente;
|
|
- a regra de validade de `palette_id`;
|
|
- o ponto de falha para paletas referenciadas mas ausentes;
|
|
- a estrategia de versao para `GLYPH/indexed_v1`;
|
|
- a lista de specs, crates e testes que precisam ser propagados no plano.
|
|
|
|
## Discussion
|
|
|
|
Entrada do usuario em 2026-07-14: o runtime deve decidir o protocolo com base
|
|
no que for melhor para o runtime; o `packer` deve seguir a spec quando pronta.
|
|
|
|
Entrada do usuario em 2026-07-14: preferencia pela Opcao C, se possivel.
|
|
|
|
Analise atual: a Opcao C e viavel, mas transforma `palette_id` em validacao
|
|
dependente do glyph bank carregado. O codigo atual ja centraliza parte desse
|
|
risco em `GlyphBank::resolve_color`, que hoje retorna transparente quando a
|
|
paleta nao existe. Para a Opcao C virar contrato robusto, a decisao nao deve
|
|
depender de fallback silencioso: precisa escolher um ponto explicito de falha
|
|
para `palette_id >= palette_count`.
|
|
|
|
Entrada do usuario em 2026-07-14: aceitar a recomendacao e seguir com a Opcao
|
|
C.
|
|
|
|
## Resolution
|
|
|
|
Fechar a agenda em favor da **Opcao C - Payload variavel e memoria residente
|
|
variavel**.
|
|
|
|
Contrato a levar para decisao:
|
|
|
|
- o runtime e a autoridade do protocolo `GLYPH/indexed_v1`;
|
|
- o `packer` deve seguir a spec runtime quando ela estiver publicada;
|
|
- `palette_count` significa o numero de paletas RGBA8888 serializadas e
|
|
materializadas no glyph bank carregado;
|
|
- `palette_count` deve estar no intervalo `1..=64`;
|
|
- cada paleta continua tendo 16 cores RGBA8888;
|
|
- `palette_id` e uma identidade direta dentro do glyph bank carregado, valida
|
|
somente quando `palette_id < palette_count`;
|
|
- o runtime nao deve remapear paletas esparsas para outra identidade;
|
|
- `decoded_size` deve contar apenas as paletas materializadas:
|
|
`width * height + palette_count * 16 * 4`;
|
|
- a mudanca permanece em `GLYPH/indexed_v1` como correcao incompativel de v1;
|
|
- payloads antigos com padding fixo e `palette_count = 64` so continuam
|
|
validos se tambem satisfizerem o novo contrato por coincidencia, nao por uma
|
|
regra de compatibilidade separada;
|
|
- referencias a paletas ausentes devem falhar explicitamente quando
|
|
scene/sprite/composer tentarem usar `palette_id >= palette_count` contra o
|
|
banco real;
|
|
- o plano posterior deve propagar specs, `GlyphBank`, decode de assets,
|
|
validacao de scene/sprite/composer, fixtures e testes.
|