feat(SCOPONE-0010): redesign main menu layout

This commit is contained in:
Giancarmine Salucci
2026-04-10 11:41:11 +02:00
parent c107489b0a
commit a4e2891c87
3 changed files with 418 additions and 127 deletions

View File

@@ -1,10 +1,10 @@
# Findings
> Last Updated: 2026-04-09T20:59:51.000Z
> Last Updated: 2026-04-10T09:39:37.000Z
## Summary
Initializer refresh for SCOPONE-0010. The cache was invalid because `docs/FINDINGS.md` no longer matched its recorded hash, and the architecture document no longer matched the live source layout after settings, preferences, and benchmark changes. The observations below reflect the current repository state.
Initializer refresh for SCOPONE-0010. The cache was invalid because `docs/FINDINGS.md` no longer matched its recorded hash and still contained an outdated note about a `SettingsScene` placeholder in `main.ts`. The observations below reflect the current repository state; `docs/ARCHITECTURE.md` and `docs/CODE_STYLE.md` were revalidated unchanged against the live source.
## Codebase Observations
@@ -12,7 +12,7 @@ Initializer refresh for SCOPONE-0010. The cache was invalid because `docs/FINDIN
- The project is structurally split between framework-free gameplay modules in `src/game/` and Phaser scene code in `src/scenes/`.
- `src/scenes/GameScene.ts` and `src/game/ai.ts` remain the two largest concentrations of application logic.
- A dedicated audio preference path now exists: `src/game/preferences.ts`, `src/scenes/MenuScene.ts`, and `src/scenes/SettingsScene.ts`.
- `main.ts` still contains a local `SettingsScene` placeholder class, while `MenuScene.ensureSettingsSceneAvailable()` swaps in the concrete imported scene before navigation.
- `main.ts` now imports and registers `SettingsScene` directly in the Phaser scene list; the earlier placeholder-scene workaround is no longer present.
- The AI transport layer is a stable three-file path: `ai-worker-protocol.ts`, `ai-worker-client.ts`, and `ai.worker.ts`.
- The AI exposes three difficulty levels: `beginner`, `advanced`, and `master`.
- `advanced` and `master` both use `CardTracker` to reason about unseen cards without directly reading hidden hands.
@@ -20,6 +20,7 @@ Initializer refresh for SCOPONE-0010. The cache was invalid because `docs/FINDIN
- `GameScene` consumes AI progress callbacks to update an on-screen think bar while a worker request is running.
- `GameScene` now enforces `AI_MIN_THINK_MS = 1000` and `MOVE_OUTCOME_STATUS_MS = 2000` through timer-backed scene logic.
- `AIWorkerClient` fails over pending work to in-thread `chooseMove()` if worker creation, posting, or deserialization fails.
- `MenuScene` now includes a responsive layout path for compact viewports, driven by calculated panel bounds and camera zoom instead of a fixed desktop-only composition.
- The AI benchmark harness is now in source under `src/game/ai-benchmark.ts` and `src/game/ai-benchmark-fixtures.ts`, and `package.json` exposes it as `npm run benchmark:ai-quality`.
- The current benchmark contract is iteration 5: 13 fixed fixtures, 6 critical concepts, and 48 self-play matches.
- The Android wrapper targets SDK 36 with `minSdkVersion` 24 and applies immersive mode from the native activity.
@@ -31,7 +32,7 @@ Initializer refresh for SCOPONE-0010. The cache was invalid because `docs/FINDIN
- `GameScene.ts` still centralizes layout, turn flow, HUD updates, effects, audio, status messaging, and AI orchestration in one scene class.
- `ai.ts` still combines heuristic tiers, inference helpers, determinization, move ordering, and alpha-beta evaluation in one module.
- The current settings flow works, but the dual registration pattern for `SettingsScene` in `main.ts` plus dynamic replacement in `MenuScene` is fragile and worth simplifying later.
- `MenuScene.ts` now carries substantial responsive layout and decorative rendering logic in the same scene that handles navigation and difficulty selection.
- Worker transport is isolated cleanly, but progress rendering and fallback behavior remain coupled to scene-level UI concerns.
- A 3.2 to 4.35 second master search window may still be noticeable on slower mobile devices even with yielding and the minimum-think pacing already in place.
- There is no dedicated automated rules test suite beyond type-checking and the AI benchmark harness.
@@ -66,7 +67,8 @@ Initializer refresh for SCOPONE-0010. The cache was invalid because `docs/FINDIN
### Scene / UI implementation snapshot
- `BootScene` loads atlas assets and presents a simple loading bar.
- `MenuScene` now exposes both difficulty selection and a dedicated entry point into `SettingsScene`.
- `main.ts` registers `BootScene`, `MenuScene`, `GameScene`, and `SettingsScene` directly in the Phaser game config.
- `MenuScene` now exposes both difficulty selection and a dedicated entry point into `SettingsScene`, with a separate compact-layout branch for smaller viewports.
- `SettingsScene` persists music and effects toggles immediately through `saveAudioPreferences()`.
- `GameScene` reads normalized audio preferences from scene data or persisted storage before match start.
- `GameScene` tracks played and captured cards in `CardTracker` as the round evolves.
@@ -140,4 +142,11 @@ Initializer refresh for SCOPONE-0010. The cache was invalid because `docs/FINDIN
- `src/scenes/SettingsScene.ts` exists as a real scene and persists music and effects toggles independently through `saveAudioPreferences()`.
- `src/scenes/GameScene.ts` already contains the previously planned pacing and status work: `AI_MIN_THINK_MS = 1000`, `MOVE_OUTCOME_STATUS_MS = 2000`, timer-backed `setStatus(...)`, and `handleSceneShutdown()` timer cleanup are all present in source and should be treated as current behavior, not future work.
- `src/game/ai-benchmark.ts` now enforces an iteration 5 contract with simulated timing, cross-seed aggregation, dual-loss reporting, and a regression watchlist intersection. Older findings that described iteration 4 targets or wall-clock-only timing are stale.
- `main.ts` still registers a local `SettingsScene` stub while `MenuScene` dynamically installs the concrete scene implementation before use. This works today but is an architectural wrinkle worth remembering in later planning.
- `src/main.ts` now imports and registers `SettingsScene` directly; the earlier placeholder-scene note is no longer accurate.
### SCOPONE-0010: Phaser scene-manager and resize notes (2026-04-10)
- Source: Context7 `/websites/phaser_io_api-documentation`, queries `Phaser 3.87 ScenePlugin add remove get duplicate key behavior and Scale Manager resize event for responsive UI layout in scenes` and `Phaser 3.87 SceneManager add scene duplicate key error getScene get key existing scene unique key documentation`.
- `SceneManager.add(key, ...)` requires a unique scene key; replacing a scene under the same key should remove the existing scene first rather than attempting a duplicate add.
- `SceneManager.remove(key)` clears the scene key from the cache and destroys that scene's systems, so the current `MenuScene.ensureSettingsSceneAvailable()` pattern is intentionally destructive when it replaces the placeholder scene.
- Phaser's resize path dispatches resize events from the Scale Manager / renderer when the display changes size, which is the framework-supported hook for responsive scene relayout if this iteration introduces viewport-aware menu composition.