2.8 KiB
| id | ticket | title | created | tags | |||||
|---|---|---|---|---|---|---|---|---|---|
| LSN-0054 | hub-suspended-game-kill-affordance | Manual Hub Kill Must Share Game Termination Cleanup | 2026-07-05 |
|
Context
After a Game returns to Home, the Game can remain resident and suspended so it can be resumed later. That state needs a visible, direct way to terminate the resident Game without launching another cartridge just to force replacement.
The Hub kill affordance solved the UX gap, but the durable engineering lesson is the cleanup boundary: manual kill must not become a second, partial termination path.
Key Decisions
Hub Suspended Game Kill Affordance
What: Hub renders a red bottom-right control when a Game is resident and suspended. The control shows only the Game title. Clicking it immediately terminates the resident Game and keeps the user in Hub.
Why: The user can distinguish "resume this Game" from "discard this resident Game" without starting a different cartridge. Reusing the canonical termination path prevents a repeat of stale scene/glyph/asset state bugs.
Trade-offs: V1 has no confirmation step. The destructive nature is carried by placement, color, and the fact that the target Game is already out of foreground.
Patterns and Algorithms
Manual Hub kill and destructive Game replacement should call the same resident Game termination helper. That helper is responsible for the whole runtime surface:
- close the Game task;
- stop the process;
- remove the VM session;
- clear resident Game state and task-scoped lifecycle delivery;
- restore Shell/Hub render ownership;
- clear lifecycle audio pause state;
- unbind the Game2D composer scene;
- shut down cartridge-scoped asset manager state and physical banks;
- emit explicit Hub/POS observability for manual kill.
The Hub itself should emit a high-level action such as KillResidentGame; it
should not know how to clean runtime subsystems.
Pitfalls
- A UI-only kill that removes a task but leaves assets or composer binding alive can still fail later when another Game renders.
- A cleanup-only helper without an end-to-end Hub click test can miss the interaction between hitbox, foreground ownership, render owner, and no-resume.
- Hard-coded click coordinates in tests make the UI contract harder to maintain; expose the layout hitbox when tests need to exercise it.
Takeaways
- Visible system controls should produce system actions, not direct subsystem mutation from UI code.
- Manual kill and Game replacement are variants of the same resident Game termination contract.
- Cleanup tests should prove both logical state removal and visible-frame behavior: the control appears before kill and disappears after kill.
- "No resume after kill" is as important as "task closed" because resumability is the user-facing state.