5.0 KiB
| id | ticket | title | status | created | completed | tags | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| PLN-0020 | render-all-scene-cache-and-camera-integration | Plan - Cache Refresh and render_frame Path | accepted | 2026-04-14 |
|
Objective
Connect FrameComposer to SceneViewportResolver, apply cache refreshes inside FrameComposer, and establish render_frame() as the canonical composition path for world + sprites + fades.
Background
DEC-0014 requires that cache refresh policy remain inside FrameComposer and that FrameComposer.render_frame() become the canonical frame entry while Gfx remains only the low-level execution backend.
DEC-0014 also requires the world path to remain tile-size agnostic, with explicit support for 8x8, 16x16, and 32x32 scene-layer tile sizes.
For per-layer camera scaling, this plan treats parallax_factor as the canonical scene-layer field name.
Scope
Included
- apply
CacheRefreshRequests inFrameComposer - connect camera/scene state to resolver updates
- use cache-backed world rendering in the frame path
- keep valid no-scene rendering (
sprites + fades)
Excluded
- HUD integration
- final retirement cleanup of legacy callsites
Execution Steps
Step 1 - Apply resolver refreshes inside FrameComposer
What:
Move cache-refresh orchestration fully into FrameComposer.
How:
- On active-scene frames:
- call resolver update with current camera and scene
- consume returned
CacheRefreshRequests - apply them to
SceneViewportCache
- Keep
Gfxunaware of refresh semantics. - Ensure resolver and refresh math follow the bound layer
tile_sizevalues rather than any fixed16x16default. - Ensure per-layer camera math is expressed through
parallax_factornaming in the resolver/cache path.
File(s):
crates/console/prometeu-drivers/src/frame_composer.rs
Step 2 - Define render_frame() as the canonical frame path
What:
Introduce the new frame service on FrameComposer.
How:
- Add
render_frame()toFrameComposer. - If a scene is active and renderable:
- prepare resolver update
- refresh cache
- call the cache-backed world path in
Gfx
- If no scene is active:
- call the no-scene path for
sprites + fades
- call the no-scene path for
- World rendering must remain valid when the active scene uses
8x8tiles.
File(s):
crates/console/prometeu-drivers/src/frame_composer.rscrates/console/prometeu-drivers/src/gfx.rs
Step 3 - Keep Gfx as backend only
What:
Narrow Gfx to backend-oriented composition responsibilities.
How:
- Ensure
Gfxconsumes prepared state fromFrameComposer. - Do not let
Gfxregain ownership of cache refresh or scene orchestration. - Keep low-level helpers for cache-backed copy paths, sprite drawing, and fades in
Gfx.
File(s):
crates/console/prometeu-drivers/src/gfx.rs
Step 4 - Cover scene and no-scene frame paths
What: Protect the two canonical frame modes.
How:
- Add tests for:
- active-scene world composition
- no-scene
sprites + fades - scene transition through unbind/rebind
- cache refresh behavior staying inside
FrameComposer - active-scene composition with
8x8tile-size layers
File(s):
crates/console/prometeu-drivers/src/frame_composer.rscrates/console/prometeu-drivers/src/gfx.rs
Test Requirements
Unit Tests
render_frame()with no scene produces valid no-scene composition.render_frame()with a scene applies resolver refreshes before composition.- cache refresh requests are applied by
FrameComposer, notGfx. render_frame()with an8x8scene uses resolver/cache math derived from layer tile size rather than a16x16assumption.- Resolver/cache-facing tests use
parallax_factorterminology for per-layer camera scaling.
Integration Tests
- scene bind + camera set + sprite emission +
render_frame()produces the expected composed frame. - scene bind + camera set +
8x8scene +render_frame()produces the expected composed frame.
Manual Verification
- Verify that no-scene frames still render sprites/fades without crashes or hidden clears.
Acceptance Criteria
FrameComposer.render_frame()exists and is the canonical frame path.- Cache refreshes are applied inside
FrameComposer. - World rendering consumes the cache-backed path.
- No-scene
sprites + fadesbehavior remains valid. Gfxremains backend-only for this path.- The world path is explicitly covered for
8x8scenes without16x16-specific assumptions. - Resolver/cache/frame-path terminology is aligned on
parallax_factorfor scene-layer camera scaling.
Dependencies
- Depends on
PLN-0017,PLN-0018, andPLN-0019 - Source decision:
DEC-0014
Risks
- If refresh application leaks into
Gfx, the ownership split fromDEC-0014collapses. - If no-scene behavior is not tested explicitly, scene integration can accidentally make scene binding mandatory.
- If tests cover only
16x16, a latent compositor regression against canonical8x8scenes can ship unnoticed.