From 4227d26101f68fb312ff307a9e9a86bcbd17b517 Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Fri, 24 Apr 2026 14:15:31 +0100 Subject: [PATCH] implements PLN-0042 scene glyph tooling and fixtures --- .../prometeu-drivers/src/frame_composer.rs | 23 +++++++++++++++++++ crates/tools/pbxgen-stress/src/lib.rs | 11 +++++---- discussion/index.ndjson | 2 +- ...ene-glyph-tooling-and-fixture-migration.md | 5 ++-- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/crates/console/prometeu-drivers/src/frame_composer.rs b/crates/console/prometeu-drivers/src/frame_composer.rs index faa1a00c..db4c62e5 100644 --- a/crates/console/prometeu-drivers/src/frame_composer.rs +++ b/crates/console/prometeu-drivers/src/frame_composer.rs @@ -847,4 +847,27 @@ mod tests { assert!(message.contains("SCENE dependency fatal during render_frame")); assert!(message.contains("glyph_asset_id=1")); } + + #[test] + fn render_frame_resolves_glyph_dependency_by_asset_id_not_by_slot_number() { + let banks = Arc::new(MemoryBanks::new()); + banks.install_glyph_bank(7, Arc::new(make_glyph_bank(TileSize::Size8, 2, Color::BLUE))); + banks.install_scene_bank(0, Arc::new(make_scene_with_palette(42, 2, TileSize::Size8))); + + let mut frame_composer = FrameComposer::new( + 16, + 16, + Arc::clone(&banks) as Arc, + make_glyph_slot_index(&[(42, 7)]), + ); + assert!(frame_composer.bind_scene(0)); + + let mut gfx = Gfx::new(16, 16, Arc::clone(&banks) as Arc); + gfx.scene_fade_level = 31; + gfx.hud_fade_level = 31; + frame_composer.render_frame(&mut gfx); + gfx.present(); + + assert_eq!(gfx.front_buffer()[0], Color::BLUE.raw()); + } } diff --git a/crates/tools/pbxgen-stress/src/lib.rs b/crates/tools/pbxgen-stress/src/lib.rs index 7f165b8c..611689f0 100644 --- a/crates/tools/pbxgen-stress/src/lib.rs +++ b/crates/tools/pbxgen-stress/src/lib.rs @@ -4,8 +4,9 @@ use prometeu_bytecode::model::{ BytecodeModule, ConstantPoolEntry, DebugInfo, Export, FunctionMeta, SyscallDecl, }; use prometeu_hal::asset::{ - AssetCodec, AssetEntry, BankType, PreloadEntry, SCENE_DECODED_LAYER_OVERHEAD_BYTES_V1, - SCENE_LAYER_COUNT_V1, SCENE_PAYLOAD_MAGIC_V1, SCENE_PAYLOAD_VERSION_V1, + AssetCodec, AssetEntry, AssetId, BankType, PreloadEntry, + SCENE_DECODED_LAYER_OVERHEAD_BYTES_V1, SCENE_LAYER_COUNT_V1, SCENE_PAYLOAD_MAGIC_V1, + SCENE_PAYLOAD_VERSION_V1, }; use prometeu_hal::cartridge::{ AssetsPackHeader, AssetsPackPrelude, ASSETS_PA_MAGIC, ASSETS_PA_PRELUDE_SIZE, @@ -338,7 +339,7 @@ fn build_scene_bank() -> SceneBank { SceneLayer { active: true, - glyph_bank_id: 0, + glyph_asset_id: 100, tile_size: TileSize::Size8, parallax_factor: match layer_index { 0 => ParallaxFactor { x: 1.0, y: 1.0 }, @@ -381,9 +382,9 @@ fn encode_scene_payload(scene: &SceneBank) -> Vec { for layer in &scene.layers { let layer_flags = if layer.active { 0b0000_0001 } else { 0 }; data.push(layer_flags); - data.push(layer.glyph_bank_id); + data.extend_from_slice(&(layer.glyph_asset_id as AssetId).to_le_bytes()); data.push(layer.tile_size as u8); - data.push(0); + data.extend_from_slice(&0_u16.to_le_bytes()); data.extend_from_slice(&layer.parallax_factor.x.to_le_bytes()); data.extend_from_slice(&layer.parallax_factor.y.to_le_bytes()); data.extend_from_slice(&(layer.tilemap.width as u32).to_le_bytes()); diff --git a/discussion/index.ndjson b/discussion/index.ndjson index 413c30a0..d4f0315e 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -21,7 +21,7 @@ {"type":"discussion","id":"DSC-0026","status":"done","ticket":"render-all-scene-cache-and-camera-integration","title":"Integrate render_all with Scene Cache and Camera","created_at":"2026-04-14","updated_at":"2026-04-18","tags":["gfx","runtime","render","camera","scene"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0031","file":"lessons/DSC-0026-render-all-scene-cache-and-camera-integration/LSN-0031-frame-composition-belongs-above-the-render-backend.md","status":"done","created_at":"2026-04-18","updated_at":"2026-04-18"}]} {"type":"discussion","id":"DSC-0027","status":"done","ticket":"frame-composer-public-syscall-surface","title":"Agenda - FrameComposer Public Syscall Surface","created_at":"2026-04-17","updated_at":"2026-04-18","tags":["gfx","runtime","syscall","abi","frame-composer","scene","camera","sprites"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0032","file":"lessons/DSC-0027-frame-composer-public-syscall-surface/LSN-0032-public-abi-must-follow-the-canonical-service-boundary.md","status":"done","created_at":"2026-04-18","updated_at":"2026-04-18"}]} {"type":"discussion","id":"DSC-0028","status":"done","ticket":"deferred-overlay-and-primitive-composition","title":"Deferred Overlay and Primitive Composition over FrameComposer","created_at":"2026-04-18","updated_at":"2026-04-18","tags":["gfx","runtime","render","frame-composer","overlay","primitives","hud"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0033","file":"lessons/DSC-0028-deferred-overlay-and-primitive-composition/LSN-0033-debug-primitives-should-be-a-final-overlay-not-part-of-game-composition.md","status":"done","created_at":"2026-04-18","updated_at":"2026-04-18"}]} -{"type":"discussion","id":"DSC-0029","status":"open","ticket":"scene-bank-glyph-runtime-binding-leak","title":"Scene Bank Glyph Runtime Binding Leak","created_at":"2026-04-24","updated_at":"2026-04-24","tags":["gfx","runtime","asset","scene","glyph","format","architecture"],"agendas":[{"id":"AGD-0029","file":"AGD-0029-scene-bank-glyph-runtime-binding-leak.md","status":"accepted","created_at":"2026-04-24","updated_at":"2026-04-24"}],"decisions":[{"id":"DEC-0021","file":"DEC-0021-scene-bank-glyph-dependencies-must-bind-by-asset-id.md","status":"in_progress","created_at":"2026-04-24","updated_at":"2026-04-24","ref_agenda":"AGD-0029"}],"plans":[{"id":"PLN-0040","file":"PLN-0040-scene-glyph-dependency-spec-and-wire-layout.md","status":"done","created_at":"2026-04-24","updated_at":"2026-04-24","ref_decisions":["DEC-0021"]},{"id":"PLN-0041","file":"PLN-0041-scene-glyph-runtime-resolution-and-fatal-paths.md","status":"done","created_at":"2026-04-24","updated_at":"2026-04-24","ref_decisions":["DEC-0021"]},{"id":"PLN-0042","file":"PLN-0042-scene-glyph-tooling-and-fixture-migration.md","status":"review","created_at":"2026-04-24","updated_at":"2026-04-24","ref_decisions":["DEC-0021"]}],"lessons":[]} +{"type":"discussion","id":"DSC-0029","status":"open","ticket":"scene-bank-glyph-runtime-binding-leak","title":"Scene Bank Glyph Runtime Binding Leak","created_at":"2026-04-24","updated_at":"2026-04-24","tags":["gfx","runtime","asset","scene","glyph","format","architecture"],"agendas":[{"id":"AGD-0029","file":"AGD-0029-scene-bank-glyph-runtime-binding-leak.md","status":"accepted","created_at":"2026-04-24","updated_at":"2026-04-24"}],"decisions":[{"id":"DEC-0021","file":"DEC-0021-scene-bank-glyph-dependencies-must-bind-by-asset-id.md","status":"in_progress","created_at":"2026-04-24","updated_at":"2026-04-24","ref_agenda":"AGD-0029"}],"plans":[{"id":"PLN-0040","file":"PLN-0040-scene-glyph-dependency-spec-and-wire-layout.md","status":"done","created_at":"2026-04-24","updated_at":"2026-04-24","ref_decisions":["DEC-0021"]},{"id":"PLN-0041","file":"PLN-0041-scene-glyph-runtime-resolution-and-fatal-paths.md","status":"done","created_at":"2026-04-24","updated_at":"2026-04-24","ref_decisions":["DEC-0021"]},{"id":"PLN-0042","file":"PLN-0042-scene-glyph-tooling-and-fixture-migration.md","status":"done","created_at":"2026-04-24","updated_at":"2026-04-24","ref_decisions":["DEC-0021"]}],"lessons":[]} {"type":"discussion","id":"DSC-0014","status":"done","ticket":"perf-vm-allocation-and-copy-pressure","title":"Agenda - [PERF] VM Allocation and Copy Pressure","created_at":"2026-03-27","updated_at":"2026-04-20","tags":[],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0035","file":"lessons/DSC-0014-perf-vm-allocation-and-copy-pressure/LSN-0035-first-materialization-is-not-the-same-as-hot-path-copy-pressure.md","status":"done","created_at":"2026-04-20","updated_at":"2026-04-20"}]} {"type":"discussion","id":"DSC-0015","status":"abandoned","ticket":"perf-cartridge-boot-and-program-ownership","title":"Agenda - [PERF] Cartridge Boot and Program Ownership","created_at":"2026-03-27","updated_at":"2026-04-20","tags":[],"agendas":[{"id":"AGD-0014","file":"workflow/agendas/AGD-0014-perf-cartridge-boot-and-program-ownership.md","status":"abandoned","created_at":"2026-03-27","updated_at":"2026-04-20","_override_reason":"User explicitly chose to close the discussion without decision because FS->memory copy for the program is already acceptable."}],"decisions":[],"plans":[],"lessons":[],"_override_reason":"User explicitly chose to abandon the discussion without creating a decision because FS->memory copy for the program is already acceptable."} {"type":"discussion","id":"DSC-0016","status":"done","ticket":"tilemap-empty-cell-vs-tile-id-zero","title":"Tilemap Empty Cell vs Tile ID Zero","created_at":"2026-03-27","updated_at":"2026-04-09","tags":[],"agendas":[{"id":"AGD-0015","file":"workflow/agendas/AGD-0015-tilemap-empty-cell-vs-tile-id-zero.md","status":"done","created_at":"2026-03-27","updated_at":"2026-04-09"}],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0022","file":"lessons/DSC-0016-tilemap-empty-cell-semantics/LSN-0022-tilemap-empty-cell-convergence.md","status":"done","created_at":"2026-04-09","updated_at":"2026-04-09"}]} diff --git a/discussion/workflow/plans/PLN-0042-scene-glyph-tooling-and-fixture-migration.md b/discussion/workflow/plans/PLN-0042-scene-glyph-tooling-and-fixture-migration.md index 8a844e23..6cf9a71a 100644 --- a/discussion/workflow/plans/PLN-0042-scene-glyph-tooling-and-fixture-migration.md +++ b/discussion/workflow/plans/PLN-0042-scene-glyph-tooling-and-fixture-migration.md @@ -2,9 +2,9 @@ id: PLN-0042 ticket: scene-bank-glyph-runtime-binding-leak title: Scene glyph tooling, fixtures, and test payload migration -status: review +status: done created: 2026-04-24 -completed: +completed: 2026-04-24 tags: [gfx, runtime, asset, scene, glyph, tooling, tests] --- @@ -113,4 +113,3 @@ Introduce tests that deliberately load glyph dependencies into different slots f - Test helper churn may be broad because many fixtures were written around the leaked slot model. - Tool outputs may silently drift if any scene payload writer is missed. - Regression tests can become brittle if they depend on incidental slot ordering instead of declared dependency identity. -