prometeu-runtime/discussion/lessons/DSC-0044-hub-suspended-game-kill-affordance/LSN-0054-manual-hub-kill-must-share-game-termination-cleanup.md
bQUARKz de53eb5ad7
All checks were successful
Intrepid/Prometeu/Runtime/pipeline/head This commit looks good
Intrepid/Prometeu/Runtime/pipeline/pr-master This commit looks good
Hub Suspended Game Kill Affordance
2026-07-05 16:27:05 +01:00

73 lines
2.8 KiB
Markdown

---
id: LSN-0054
ticket: hub-suspended-game-kill-affordance
title: Manual Hub Kill Must Share Game Termination Cleanup
created: 2026-07-05
tags: [hub, lifecycle, game, ui, assets]
---
## 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.