9.1 KiB
| id | ticket | title | status | created | resolved | decision | tags | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| AGD-0031 | studio-frame-composer-syscall-and-sprite-alignment | Studio Alignment with Runtime FrameComposer Syscalls and Sprite Composition | in_progress | 2026-04-18 | 2026-04-18 | DEC-0027 |
|
Pain
The sibling runtime has already moved the public frame-orchestration ABI to composer.*.
This repository still exposes the old model through @sdk:gfx and Gfx.set_sprite, which means:
- the Studio-side compiler and stdlib still teach a legacy public contract;
- PBS examples and tests still lower sprite composition through the wrong owner;
- specs still describe a source surface that no longer matches the runtime's canonical syscall boundary;
- any new Studio work risks reinforcing a dual contract between
gfx.*primitives andcomposer.*frame orchestration.
The user explicitly scoped this discussion to:
- ABI/syscall alignment with the current
../runtime; FrameComposerconvergence for sprite composition;- Studio-side propagation across
compiler,pbs, andstdlib; @sdk:composerfor the sprite-composition path;- removal of the legacy
Gfx.set_spriteentrypoint; - no scene-bank implementation work in this ticket.
Context
Domain owner: studio
Primary affected subdomains:
compiler/pbsstudio
Expected propagation targets if this discussion closes:
docs/specs/compiler-languages/pbsdocs/specs/compiler- PBS stdlib resources under
prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/resources/stdlib - compiler/frontend/backend conformance tests
- Studio-adjacent examples and fixtures that still import
@sdk:gfxfor sprite composition
Observed current state on 2026-04-18:
../runtimelessonDSC-0026locksFrameComposeras the canonical frame owner above the render backend.../runtimelessonDSC-0027locks the public VM-facing syscall ABI tocomposer.bind_scene,composer.unbind_scene,composer.set_camera, andcomposer.emit_sprite, and removes the legacy publicgfx.set_spritepath.../runtimelessonDSC-0028keeps immediate/debug primitives such asgfx.draw_textoutside canonical game composition as a deferred overlay path.- this repository still ships
@sdk:gfxwithLowGfx.set_sprite(...)andGfx.set_sprite(...); - this repository does not yet expose a reserved
@sdk:composermodule; - docs and tests still use
@sdk:gfxas the visible source surface for sprite composition.
This creates architectural drift:
- runtime public ownership says
composer.*for frame composition; - Studio-side language and stdlib surfaces still say
gfx.*for part of that same behavior.
The drift is specifically about syscall and sprite-composer alignment.
Out of scope for this agenda:
composer.bind_scene,composer.unbind_scene, andcomposer.set_camerarollout in Studio;- scene-bank authoring workflows;
- scene asset import/editor design;
- scene bank build/materialization contracts beyond what is minimally needed to name ABI boundaries;
- broader scene workspace/product decisions already separated into other discussions.
Open Questions
- Studio should expose a new reserved module
@sdk:composeras the canonical public source surface for sprite composition. @sdk:gfxshould remain limited to primitive/overlay/back-end-adjacent operations once sprite composition moves out.- PBS should export
@sdk:composerusing the same source-level shape already used by@sdk:gfx: low-level host owner plus public service facade. - Mutating composer operations should remain raw
intstatus returns in v1 for now. - Tests, fixtures, examples, and callsites should all migrate in this wave if possible; no compatibility path should be preserved.
- No temporary compatibility alias is acceptable;
Gfx.set_spriteshould be removed completely.
Options
Option A - Introduce @sdk:composer now for sprite emission only in this wave
- Approach: Add a dedicated reserved stdlib module that exposes the sprite-composition path through
composer.emit_sprite; migrate sprite composition calls, host metadata, docs, and tests to that module; keep@sdk:gfxfor primitives/overlay-style operations only; defer Studio-sidebind_scene,unbind_scene, andset_camera. - Pro: Matches the runtime's canonical service boundary, preserves the split between frame composition and render primitives, and avoids teaching the retired
gfx.set_spritecontract. - Con: Introduces a partial first wave of the
composerdomain, so docs must be explicit that other composer operations are intentionally deferred rather than absent by accident. - Maintainability: Strong, because the public source surface mirrors the actual runtime ABI and ownership model.
Option B - Keep @sdk:gfx as the user-facing module and only retarget its internals to composer.*
- Approach: Preserve the visible
Gfx.set_spriteAPI in Studio while changing lowering metadata underneath to hitcomposer.emit_sprite. - Pro: Smaller immediate source churn in examples and tests.
- Con: Encodes the wrong owner in the public teaching surface, preserves the exact dual-contract problem the runtime discussion just removed, and makes later cleanup harder.
- Maintainability: Weak, because it keeps historical naming instead of canonical service ownership.
Option C - Add @sdk:composer but retain temporary Gfx.set_sprite compatibility in parallel
- Approach: Introduce the new canonical module while leaving
Gfx.set_spriteas an alias or transitional wrapper for one or more waves. - Pro: Softens migration pressure for existing examples and downstream users.
- Con: Creates two public ways to express the same operation, invites drift in specs/tests/docs, and conflicts with the runtime lesson that legacy public fallbacks should be removed when they preserve the wrong model.
- Maintainability: Medium at best in the short term, poor in the long term if the alias survives longer than intended.
Discussion
The runtime side has already made two architectural facts explicit:
- frame orchestration belongs to
FrameComposer, not toGfx; - the public syscall namespace must reflect that ownership.
That means this repository is no longer choosing between equivalent naming styles.
It is choosing whether Studio will:
- align its source-facing contracts with the canonical runtime boundary; or
- preserve a legacy public façade that the runtime has already declared misleading.
The user's scope also matters.
This ticket is not asking for scene-bank product work, and it also is not asking for Studio-side scene binding or camera rollout. So the migration target should stay narrow:
- syscall/domain alignment;
@sdk:composersurface alignment for sprite emission;- compiler/PBS/stdlib propagation;
- tests and examples updated to stop asserting the retired path.
- removal of the old
Gfx.set_spritepath.
The remaining design work is therefore smaller and more concrete:
- define the Studio-side shape of
@sdk:composerfor sprite emission; - propagate
composer.emit_spritethrough stdlib, specs, compiler, and tests; - keep the deferred composer calls explicitly out of this ticket so the repository does not accidentally mix sprite convergence with unfinished scene-facing rollout.
The agenda questions are now resolved with explicit user direction:
@sdk:composershould follow the same editorial pattern already used by@sdk:gfx, meaning a low-level host owner plus a public service facade.composer.emit_spriteshould continue returning a rawintstatus in this wave.- Migration should be broad and immediate across tests, fixtures, and examples where feasible.
Gfx.set_spriteshould be removed entirely, with no compatibility alias or dual-path surface.- Specs should document only what this wave actually implements, while leaving room for
bind_scene,unbind_scene, andset_camerato be added later using the same pattern.
Resolution
Recommended direction:
- adopt Option A as the working direction for this discussion;
- open a Studio-side canonical
@sdk:composersurface aligned to the runtime ABI for sprite emission in this wave; - retire
Gfx.set_spritefrom normative Studio-facing contracts instead of preserving a compatibility façade; - defer
composer.bind_scene,composer.unbind_scene, andcomposer.set_camerato a later ticket; - keep scene-bank authoring/editor work explicitly out of this ticket;
- keep
@sdk:gfxfocused on primitive and overlay-style operations.
Recommended next step:
- treat the sprite-only
@sdk:composerwave as the accepted scope of this agenda; - write a decision that locks:
@sdk:composeras the canonical Studio-side sprite-composition module;- the
LowComposer+Composershape matching the established@sdk:gfxpattern; - raw
intstatus returns for this wave; - complete removal of
Gfx.set_spritewith no compatibility path; - broad propagation across specs, stdlib, compiler, tests, fixtures, and examples;
- deferred addition of
bind_scene,unbind_scene, andset_camerain later work.