From 1182d3ae1f67b665037d1d1242600e2253de6ce1 Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Mon, 27 Apr 2026 06:47:18 +0100 Subject: [PATCH] Studio scene pack contract for runtime SCENE binary payload --- discussion/index.ndjson | 3 +- ...udio-scene-pack-runtime-binary-contract.md | 242 ++++++++++++++++++ 2 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 discussion/workflow/agendas/AGD-0032-studio-scene-pack-runtime-binary-contract.md diff --git a/discussion/index.ndjson b/discussion/index.ndjson index 715457cd..a82f42f5 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -1,4 +1,5 @@ -{"type":"meta","next_id":{"DSC":30,"AGD":32,"DEC":29,"PLN":59,"LSN":46,"CLSN":1}} +{"type":"meta","next_id":{"DSC":31,"AGD":33,"DEC":29,"PLN":59,"LSN":46,"CLSN":1}} +{"type":"discussion","id":"DSC-0030","status":"accepted","ticket":"studio-scene-pack-runtime-binary-contract","title":"Studio scene pack contract for runtime SCENE binary payload","created_at":"2026-04-24","updated_at":"2026-04-27","tags":["studio","packer","runtime","scene","asset-pack","binary-format","tiled"],"agendas":[{"id":"AGD-0032","file":"AGD-0032-studio-scene-pack-runtime-binary-contract.md","status":"accepted","created_at":"2026-04-24","updated_at":"2026-04-27"}],"decisions":[],"plans":[],"lessons":[]} {"type":"discussion","id":"DSC-0029","status":"done","ticket":"studio-frame-composer-syscall-and-sprite-alignment","title":"Studio Alignment with Runtime FrameComposer Syscalls and Sprite Composition","created_at":"2026-04-18","updated_at":"2026-04-18","tags":["studio","compiler","pbs","stdlib","runtime-alignment","abi","syscall","frame-composer","sprites"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0041","file":"discussion/lessons/DSC-0029-studio-frame-composer-syscall-and-sprite-alignment/LSN-0041-composer-must-own-public-sprite-composition.md","status":"done","created_at":"2026-04-18","updated_at":"2026-04-18"}]} {"type":"discussion","id":"DSC-0028","status":"done","ticket":"studio-tiled-parser-assets-scene-asset-type","title":"Tiled Parser and Scene Asset-Type Ownership in Assets Workspace","created_at":"2026-04-15","updated_at":"2026-04-23","tags":["studio","assets","scene","tiled","parser","asset-type"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0045","file":"discussion/lessons/DSC-0028-studio-tiled-parser-assets-scene-asset-type/LSN-0045-asset-owned-scene-bank-and-tiled-xml-workflow.md","status":"done","created_at":"2026-04-23","updated_at":"2026-04-23"}]} {"type":"discussion","id":"DSC-0027","status":"abandoned","ticket":"studio-scene-workspace","title":"Scene Workspace for SCENE Authoring","created_at":"2026-04-14","updated_at":"2026-04-15","tags":["studio","workspace","scene","tilemap","asset","runtime-alignment"],"agendas":[{"id":"AGD-0029","file":"AGD-0029-studio-scene-workspace.md","status":"abandoned","created_at":"2026-04-14","updated_at":"2026-04-15","_override_reason":"Explicit user request on 2026-04-15 to abandon the accepted agenda and its downstream work."}],"decisions":[{"id":"DEC-0026","file":"DEC-0026-studio-scene-workspace.md","status":"abandoned","created_at":"2026-04-14","updated_at":"2026-04-15","ref_agenda":"AGD-0029","_override_reason":"Explicit user request on 2026-04-15 to abandon the accepted decision and stop using it as normative guidance."}],"plans":[{"id":"PLN-0049","file":"PLN-0049-scene-workspace-spec-and-boundary-propagation.md","status":"abandoned","created_at":"2026-04-14","updated_at":"2026-04-15","ref_decisions":["DEC-0026"],"_override_reason":"Explicit user request on 2026-04-15 to abandon all plans derived from DEC-0026."},{"id":"PLN-0050","file":"PLN-0050-scene-workspace-shell-and-project-state-foundations.md","status":"abandoned","created_at":"2026-04-14","updated_at":"2026-04-15","ref_decisions":["DEC-0026"],"_override_reason":"Explicit user request on 2026-04-15 to abandon all plans derived from DEC-0026."},{"id":"PLN-0051","file":"PLN-0051-scene-artifact-and-assets-handoff-contract.md","status":"abandoned","created_at":"2026-04-14","updated_at":"2026-04-15","ref_decisions":["DEC-0026"],"_override_reason":"Explicit user request on 2026-04-15 to abandon all plans derived from DEC-0026."},{"id":"PLN-0052","file":"PLN-0052-scene-workspace-wave-1-tilemap-editor.md","status":"abandoned","created_at":"2026-04-14","updated_at":"2026-04-15","ref_decisions":["DEC-0026"],"_override_reason":"Explicit user request on 2026-04-15 to abandon all plans derived from DEC-0026."}],"lessons":[]} diff --git a/discussion/workflow/agendas/AGD-0032-studio-scene-pack-runtime-binary-contract.md b/discussion/workflow/agendas/AGD-0032-studio-scene-pack-runtime-binary-contract.md new file mode 100644 index 00000000..be27b0a8 --- /dev/null +++ b/discussion/workflow/agendas/AGD-0032-studio-scene-pack-runtime-binary-contract.md @@ -0,0 +1,242 @@ +--- +id: AGD-0032 +ticket: studio-scene-pack-runtime-binary-contract +title: Studio scene pack contract for runtime SCENE binary payload +status: accepted +created: 2026-04-24 +resolved: 2026-04-27 +decision: +tags: [studio, packer, runtime, scene, asset-pack, binary-format, tiled] +--- + +## Pain + +O runtime ja possui um payload binario `SCENE` versionado e com decoder real, mas o Studio/paker ainda para em `TMX`/`TSX` e nao fecha a publicacao desse asset para `assets.pa`. + +Isso deixa um gap claro entre: + +- authoring/editorial workflow no dominio `studio`; +- materializacao e packing no dominio `packer`; +- contrato efetivamente consumido no dominio `runtime`. + +Dominio owner desta agenda: `studio`. +Boundary explicito: `studio -> packer -> runtime`. + +## Context + +- O runtime define `SCENE` v1 com magic `SCNE`, version `1`, `4` layers fixas, metadata vazio no header do asset table e payload binario por layer. +- O decoder de `SCENE` ja valida: + version; + layer count; + tile size; + parallax factor; + `width * height == tile_count`; + `decoded_size`; + ausencia de trailing bytes. +- O runtime tambem ja instala `SceneBank` em scene slots, mas a dependencia de glyph por layer agora eh `glyph_asset_id`, nao mais `glyph_bank_id`. +- O runtime resolve `glyph_asset_id -> glyph slot` internamente durante `bind_scene` e `render_frame`, mantendo a alocacao de slot como concern operacional de runtime. +- O Studio hoje trata `Scene Bank` como asset owner de authoring/validation, com `scene-bank.studio.json`, `TMX` por layer e `TSX` gerado por glyph bank especializado em tileset. +- A decision consolidada em `DSC-0028` fechou o modelo wave 1 de authoring em `TMX`/`TSX`, mas deixou explicitamente o scene packing runtime como concern posterior. +- O packer atual reconhece `SCENE_BANK` como familia e `SCENE/tilemap_v1` como output format, mas ainda nao faz walk/materialization de scene e falha deliberadamente no pack execution para familias fora de `GLYPH_BANK`. + +Findings tecnicos relevantes desta agenda: + +1. O formato binario ja existe no runtime e nao esta “a decidir”. +2. O packer atual nao produz payload `SCENE`. +3. O maior buraco contratual hoje nao eh o layout binario em si, mas a traducao editorial de `TMX`/`TSX` para os campos exigidos pelo runtime. +4. O campo mais sensivel continua sendo a dependencia de glyph por layer, mas o runtime atual passou a usar `glyph_asset_id` no `SCENE` e resolver `asset_id -> slot` internamente. +5. Isso remove do Studio/paker a necessidade de conhecer previamente o glyph slot operacional do runtime para serializar a scene. + +## Open Questions + +- [x] Quem deve ser o owner da compilacao `TMX`/`TSX -> SCENE`: `prometeu-packer` embutido no Studio, uma camada editorial do Studio, ou outro componente? + Resposta atual da discussao: + o `Asset Workspace` gera e usa `TMX`/`TSX` apenas como support/editorial surfaces; + esses formatos nao devem ser empurrados para o `prometeu-packer`; + o `prometeu-packer` deve receber um protocolo proprio de requisicao; + o `Scene Bank` no Studio deve validar e extrair, no passo de `Accept`, os dados necessarios dos artefatos editoriais para esse request. +- [x] Qual deve ser o contrato canonico da dependencia de glyph por layer? + Resposta validada contra o runtime atual: + o payload `SCENE` deve carregar `glyph_asset_id`; + a resolucao `asset_id -> slot` pertence ao runtime; + Studio e packer nao precisam serializar slot de glyph no contrato da scene. +- [x] O `Scene Bank` deve persistir `glyph_asset_id` explicitamente no metadata/request do Studio ou derivar isso sempre a partir do asset referenciado na layer? + Resposta atual da discussao: + `glyph_asset_id` eh derivado do tileset/glyph asset selecionado no form da layer, mantendo uma unica fonte da verdade. +- [x] Onde devem viver os `parallax_factor` por layer, que o runtime exige mas o metadata atual do Studio nao modela? + Resposta atual da discussao: + `parallax_factor` deve ser adicionado ao form da layer no Studio. +- [x] De onde vem o `palette_id` por layer/tile no request atual? + Resposta atual da discussao: + `palette_id` ainda nao existe no workflow atual e deve ser adicionado ao form da layer no Studio, ou em surface editorial equivalente no mesmo nivel. +- [x] Como o workflow editorial indica se uma layer entra ou nao na publicacao? + Resposta atual da discussao: + o checkbox existente no form da layer indica se a layer esta ativa/sera usada. +- [x] Qual eh a regra oficial de traducao de tiles do Tiled para records do payload runtime: + `gid` base; + flip flags; + `glyph_id`; + `palette_id`? + Resposta atual da discussao: + cada tile eh mapeado pelo `TSX`, e o `TSX` aponta para o glyph asset; + `flip` e `palette_id` por tile podem vir como properties no `TMX`, por serem dados do tile especifico; + `glyph_id` ja existe como property no `TSX`. +- [x] O wave 1 continua estritamente limitado a um `TSX` por `TMX`/layer tambem no scene pack runtime, ou precisamos abrir espaco para multi-tileset antes de fechar o contrato? + Resposta atual da discussao: + sim, wave 1 continua com exatamente `1 TSX` por `TMX`/layer. +- [x] A aceitacao no Studio deve ser gate obrigatorio para publicar `SCENE` em pack, ou apenas um estado editorial recomendado? + Resposta atual da discussao: + o criterio continua sendo o usual do workflow: nenhum diagnostic error bloqueante. +- [x] O `SCENE/tilemap_v1` no manifest representa o payload binario runtime final, ou ainda esta sendo usado ambiguamente para o estado editorial baseado em `TMX`? + Resposta atual da discussao: + vamos manter `SCENE/tilemap_v1` por enquanto; + o runtime nao exige mudanca desse nome neste momento. +- [x] Qual deve ser o shape exato do request `studio -> packer`? + Resposta atual da discussao: + o request deve ser construido backwards a partir dos dados do payload binario `SCENE`, como um data class o mais proximo possivel do binario final. + Shape atual assentado na agenda: + ```text + ScenePackRequest + - version: int + - layers: [ScenePackLayerRequest; 4] + + ScenePackLayerRequest + - active: bool + - glyph_asset_id: int + - tile_size: int + - parallax_factor_x: float + - parallax_factor_y: float + - width: int + - height: int + - tiles: List + + ScenePackTileRequest + - active: bool + - glyph_id: int + - palette_id: int + - flip_x: bool + - flip_y: bool + ``` + Observacoes do shape assentado: + `request -> SCENE` deve ser quase isomorfico; + `tile_count` pode ser derivado de `width * height`; + campos reservados do binario nao precisam existir no request. + +## Options + +### Option A - Studio Accepts Tiled and Emits a Packer-Owned Scene Request + +- **Approach:** manter o Studio como owner de authoring, validation e acceptance de `TMX`/`TSX`, e fazer o `Scene Bank` aceito extrair um request proprio e estavel para o `prometeu-packer`; o packer compila esse request para o payload binario `SCENE` sem conhecer `TMX`/`TSX`. +- **Pro:** preserva `TMX`/`TSX` como concern editorial do Studio e evita contaminar o packer com detalhes de tooling externo. +- **Con:** exige fechar um boundary formal novo entre Studio e packer, incluindo o schema desse request. +- **Maintainability:** boa, desde que o contrato editorial/runtime fique explicito e versionado. + +### Option B - Add a Studio-Owned Intermediate Scene Representation First + +- **Approach:** antes de empacotar, introduzir um modelo normalizado intermediario no Studio ou em shared tooling, e so depois converter esse modelo para o payload binario runtime. +- **Pro:** pode simplificar validacao e testes sem depender diretamente de parsing de `TMX` no packer. +- **Con:** reabre o risco de criar uma segunda surface de scene alem de `TMX`, contrariando a direcao recente de evitar schema paralelo cedo demais. +- **Maintainability:** media; melhora isolamento interno, mas adiciona outra camada contratual para manter. + +### Option C - Make Packer Parse TMX/TSX Directly + +- **Approach:** fazer o `prometeu-packer` ler `TMX`/`TSX` diretamente e produzir o payload runtime a partir dessas surfaces editoriais. +- **Pro:** reduz o numero aparente de etapas entre authoring e pack final. +- **Con:** acopla o packer a uma surface editorial do Studio e ao tooling externo, o que contraria a direcao explicitada nesta discussao. +- **Maintainability:** fraca; qualquer evolucao do authoring/editorial tende a vazar para o contrato operacional do packer. + +## Discussion + +O estado atual sugere que o layout binario do runtime ja esta suficientemente maduro para servir como contrato de destino. A discussao principal nao deveria voltar para “qual eh o formato binario da scene”, e sim para “como o Studio/paker chegam nele de forma disciplinada”. + +Ha uma restricao importante aqui: a decision anterior sobre `Scene Bank` em Assets e `TMX`/`TSX` como surfaces wave 1 continua valida. Portanto esta agenda nao deve reinterpretar `DSC-0028` como se o Studio precisasse ganhar um scene workspace, um editor pesado ou um schema proprietario paralelo por conveniencia. + +Direcao ja explicitada nesta thread: + +- `TMX` e `TSX` ficam confinados ao dominio editorial do Studio; +- o `Asset Workspace` deve conseguir validar e extrair do estado aceito os dados relevantes para pack; +- o `prometeu-packer` nao deve conhecer Tiled nem depender de `TMX`/`TSX`; +- o boundary Studio -> packer deve ser um protocolo proprio, estavel e independente das surfaces editoriais. + +Os pontos mais arriscados no boundary sao: + +1. `glyph_asset_id`: + o runtime agora aceita identidade estavel de asset na scene e resolve `asset_id -> slot` internamente; a discussao ja convergiu que esse valor eh derivado do tileset/glyph asset selecionado no form da layer. +2. `parallax_factor`: + o runtime exige esse campo por layer; a direcao atual eh adiciona-lo ao form da layer, no mesmo nivel editorial de configuracoes como dimensao do mapa. +3. traducao de tiles: + a direcao atual ja convergiu que cada tile eh resolvido pelo `TSX`, com `flip` e `palette_id` podendo vir do `TMX`; o request do packer deve preservar esses campos de forma quase isomorfica ao record runtime. +4. `palette_id`: + a direcao atual eh adiciona-lo ao form da layer, com possibilidade de override por tile via properties editoriais no `TMX`. +5. gate editorial: + o checkbox de layer ativa ja cobre o uso editorial da layer, e o gate atual para publicar continua sendo ausencia de diagnostic error bloqueante. +## Settled So Far + +Os pontos abaixo ficam cravados nesta agenda como direcao atual da discussao: + +1. `TMX` e `TSX` permanecem surfaces editoriais do Studio e nao entram no protocolo operacional do packer. +2. O `Asset Workspace` deve extrair, no passo de `Accept`, um request proprio para o `prometeu-packer`. +3. O payload runtime `SCENE` carrega `glyph_asset_id`, e a resolucao `asset_id -> slot` pertence ao runtime. +4. `glyph_asset_id` eh derivado do tileset/glyph asset selecionado no form da layer. +5. `parallax_factor` deve existir no form da layer. +6. `palette_id` deve existir no form da layer, ou em surface editorial equivalente no mesmo nivel. +7. O checkbox da layer define se ela esta ativa/sera usada. +8. Cada tile eh resolvido via `TSX`; `glyph_id` ja existe como property no `TSX`. +9. `flip` e `palette_id` por tile podem vir como properties no `TMX`. +10. Wave 1 continua com exatamente `1 TSX` por `TMX`/layer. +11. O gate atual para publicar continua sendo ausencia de diagnostic error bloqueante. +12. O request `studio -> packer` deve ser derivado backwards do payload binario e `request -> SCENE` deve ser o mais direto possivel. +13. O shape atual assentado do request e: + `ScenePackRequest(version, layers[4])`; + `ScenePackLayerRequest(active, glyph_asset_id, tile_size, parallax_factor_x, parallax_factor_y, width, height, tiles)`; + `ScenePackTileRequest(active, glyph_id, palette_id, flip_x, flip_y)`. +14. O manifest permanece com `SCENE/tilemap_v1` por enquanto. + +## Recommendation + +Seguir com a `Option A`. + +Direcao recomendada: + +1. manter `TMX`/`TSX` como surfaces editoriais wave 1 no dominio `studio`; +2. fechar uma decision nova para o boundary `studio/packer/runtime` do `Scene Bank`; +3. fazer o `Asset Workspace` aceitar e extrair do estado editorial um request proprio para o packer; +4. fazer o `prometeu-packer` ser owner apenas da compilacao desse request para o payload binario `SCENE`; +5. explicitar na decision: + modelagem da dependencia `glyph_asset_id`; + modelagem de `parallax_factor`; + modelagem de `palette_id`; + semantica da layer ativa no request; + gate baseado em diagnostics bloqueantes; + formato do request `studio -> packer`, derivado backwards do payload binario; + semantica oficial de `SCENE/tilemap_v1`. + +Essa direcao reaproveita o que ja existe, mantem o packer livre das ferramentas editoriais do Studio e concentra a publicacao runtime no subsistema que ja monta `assets.pa`. + +## Next Step Suggestion + +Converter esta agenda em uma decision focada no contrato de compilacao/publicacao de `Scene Bank`, cobrindo: + +1. ownership por dominio; +2. formato do request `studio -> packer`, backwards a partir do payload binario; +3. mapping editorial -> request -> runtime, com `request -> SCENE` o mais direto possivel; +4. modelagem e validacao de `glyph_asset_id` por layer; +5. gating de diagnostics para pack; +6. propagation targets em `prometeu-packer`, `prometeu-studio` e specs relevantes. + +## Resolution + +Agenda aceita. + +Direcao consolidada: + +1. `TMX`/`TSX` permanecem estritamente editoriais no dominio `studio`. +2. O `Scene Bank` aceito deve extrair um request proprio e estavel para o `prometeu-packer`. +3. O request `studio -> packer` deve ser derivado backwards do payload binario `SCENE` e `request -> SCENE` deve ser o mais direto possivel. +4. O contrato runtime de dependencia de glyph por layer usa `glyph_asset_id`, com resolucao `asset_id -> slot` pertencendo ao runtime. +5. O workflow editorial do Studio deve prover `glyph_asset_id` derivado do tileset selecionado, `parallax_factor`, `palette_id`, estado ativo da layer e a traducao por tile a partir de `TSX`/`TMX`. +6. Wave 1 permanece com exatamente `1 TSX` por `TMX`/layer. +7. O gate para publicacao continua sendo ausencia de diagnostic error bloqueante. +8. O manifest permanece com `SCENE/tilemap_v1` por enquanto. + +Proximo passo sugerido: converter esta agenda em uma `decision` normativa para o boundary `studio -> packer -> runtime`.