fix(SCOPONE-0008): refresh lag fix docs
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# Architecture
|
# Architecture
|
||||||
|
|
||||||
> Last Updated: 2026-04-02T18:12:18.000Z
|
> Last Updated: 2026-04-02T19:05:00.000Z
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
@@ -27,7 +27,10 @@ scopone-phaser/
|
|||||||
| | |- types.ts
|
| | |- types.ts
|
||||||
| | |- engine.ts
|
| | |- engine.ts
|
||||||
| | |- card-tracker.ts
|
| | |- card-tracker.ts
|
||||||
| | `- ai.ts
|
| | |- ai.ts
|
||||||
|
| | |- ai-worker-protocol.ts
|
||||||
|
| | |- ai-worker-client.ts
|
||||||
|
| | `- ai.worker.ts
|
||||||
| `- scenes/
|
| `- scenes/
|
||||||
| |- BootScene.ts
|
| |- BootScene.ts
|
||||||
| |- MenuScene.ts
|
| |- MenuScene.ts
|
||||||
@@ -64,8 +67,9 @@ Observed architectural patterns in the current codebase:
|
|||||||
| Scene-based flow | `BootScene -> MenuScene -> GameScene` via Phaser scene registration |
|
| Scene-based flow | `BootScene -> MenuScene -> GameScene` via Phaser scene registration |
|
||||||
| Functional core / imperative shell | `src/game/` stays free of Phaser imports, while `src/scenes/` owns rendering and input |
|
| Functional core / imperative shell | `src/game/` stays free of Phaser imports, while `src/scenes/` owns rendering and input |
|
||||||
| Clone-before-mutate state transitions | `applyMove()` clones `GameState` before applying move effects |
|
| Clone-before-mutate state transitions | `applyMove()` clones `GameState` before applying move effects |
|
||||||
|
| Worker offload with fallback | `AIWorkerClient` runs heavy AI inside `ai.worker.ts` and falls back to in-thread `chooseMove()` if worker startup or messaging fails |
|
||||||
| Determinization search | Master AI samples hidden hands before alpha-beta evaluation |
|
| Determinization search | Master AI samples hidden hands before alpha-beta evaluation |
|
||||||
| Callback-driven progress reporting | `chooseMove()` reports `AIDecisionProgress` to `GameScene` for the think bar |
|
| Message-based progress reporting | Worker and main thread exchange typed request/result/progress messages through `ai-worker-protocol.ts` |
|
||||||
|
|
||||||
## Key Components
|
## Key Components
|
||||||
|
|
||||||
@@ -94,7 +98,7 @@ Observed architectural patterns in the current codebase:
|
|||||||
- Computes unseen cards from `played + myHand + table`.
|
- Computes unseen cards from `played + myHand + table`.
|
||||||
- Supplies probability helpers used by the AI for value-based inference.
|
- Supplies probability helpers used by the AI for value-based inference.
|
||||||
|
|
||||||
### `src/game/ai.ts` (1210 lines)
|
### `src/game/ai.ts`
|
||||||
|
|
||||||
- Exposes `chooseMove()` as an async entry point.
|
- Exposes `chooseMove()` as an async entry point.
|
||||||
- Implements three difficulty levels:
|
- Implements three difficulty levels:
|
||||||
@@ -103,22 +107,38 @@ Observed architectural patterns in the current codebase:
|
|||||||
- `master`: determinization plus alpha-beta search with dynamic time budgets, batching, and progress callbacks.
|
- `master`: determinization plus alpha-beta search with dynamic time budgets, batching, and progress callbacks.
|
||||||
- Uses `yieldToBrowser()` between master-search batches so Phaser can repaint the think bar.
|
- Uses `yieldToBrowser()` between master-search batches so Phaser can repaint the think bar.
|
||||||
|
|
||||||
### `src/scenes/BootScene.ts` (47 lines)
|
### `src/game/ai-worker-protocol.ts`
|
||||||
|
|
||||||
|
- Defines the typed message contract between the main thread and the worker.
|
||||||
|
- Serializes requests around `GameState`, `Difficulty`, `PlayerIndex`, tracker snapshots, progress, results, and worker-safe errors.
|
||||||
|
|
||||||
|
### `src/game/ai-worker-client.ts`
|
||||||
|
|
||||||
|
- Wraps the worker lifecycle behind the same `chooseMove()` API the scene needs.
|
||||||
|
- Creates module workers with `new Worker(new URL('./ai.worker.ts', import.meta.url), { type: 'module' })`.
|
||||||
|
- Streams progress callbacks back into `GameScene` and degrades to direct `chooseMove()` execution when workers are unavailable.
|
||||||
|
|
||||||
|
### `src/game/ai.worker.ts`
|
||||||
|
|
||||||
|
- Rehydrates `CardTracker` from a snapshot, delegates move selection to `chooseMove()`, and posts progress/result/error messages back to the scene thread.
|
||||||
|
- Keeps the expensive `master` search off the main rendering thread when worker support is available.
|
||||||
|
|
||||||
|
### `src/scenes/BootScene.ts`
|
||||||
|
|
||||||
- Loads the card atlas and card-back texture.
|
- Loads the card atlas and card-back texture.
|
||||||
- Shows a simple progress bar and transitions into the menu.
|
- Shows a simple progress bar and transitions into the menu.
|
||||||
|
|
||||||
### `src/scenes/MenuScene.ts` (103 lines)
|
### `src/scenes/MenuScene.ts`
|
||||||
|
|
||||||
- Renders the title screen and rules summary.
|
- Renders the title screen and rules summary.
|
||||||
- Lets the player choose `beginner`, `advanced`, or `master` difficulty.
|
- Lets the player choose `beginner`, `advanced`, or `master` difficulty.
|
||||||
- Starts `GameScene` with the selected difficulty in scene data.
|
- Starts `GameScene` with the selected difficulty in scene data.
|
||||||
|
|
||||||
### `src/scenes/GameScene.ts` (1446 lines)
|
### `src/scenes/GameScene.ts`
|
||||||
|
|
||||||
- Owns the match loop, HUD, think bar, card interaction, animation, FX, audio, and round transitions.
|
- Owns the match loop, HUD, think bar, card interaction, animation, FX, audio, and round transitions.
|
||||||
- Uses `CardTracker` to record played and captured cards after each move.
|
- Uses `CardTracker` to record played and captured cards after each move.
|
||||||
- Bridges async AI progress into a visible top-of-screen think bar.
|
- Instantiates `AIWorkerClient`, bridges async AI progress into a visible top-of-screen think bar, and disposes worker resources on scene shutdown.
|
||||||
- Handles end-of-round overlays and full-match restart flow.
|
- Handles end-of-round overlays and full-match restart flow.
|
||||||
|
|
||||||
### `android/app/src/main/java/com/phaser/scopa/MainActivity.java`
|
### `android/app/src/main/java/com/phaser/scopa/MainActivity.java`
|
||||||
@@ -166,6 +186,10 @@ main.ts
|
|||||||
-> GameScene
|
-> GameScene
|
||||||
-> engine.ts
|
-> engine.ts
|
||||||
-> ai.ts
|
-> ai.ts
|
||||||
|
-> ai-worker-client.ts
|
||||||
|
-> ai-worker-protocol.ts
|
||||||
|
-> ai.worker.ts
|
||||||
|
-> ai.ts
|
||||||
-> card-tracker.ts
|
-> card-tracker.ts
|
||||||
-> types.ts
|
-> types.ts
|
||||||
```
|
```
|
||||||
@@ -184,10 +208,12 @@ Dependencies are one-directional at the application level:
|
|||||||
4. `GameScene.create()` initializes a new `CardTracker`, creates the initial `GameState`, and animates the opening deal.
|
4. `GameScene.create()` initializes a new `CardTracker`, creates the initial `GameState`, and animates the opening deal.
|
||||||
5. On each turn:
|
5. On each turn:
|
||||||
- Human turns use click-driven selection and capture highlighting.
|
- Human turns use click-driven selection and capture highlighting.
|
||||||
- AI turns call `chooseMove(state, playerIdx, difficulty, tracker, onProgress)`.
|
- AI turns call `AIWorkerClient.chooseMove(state, playerIdx, difficulty, tracker, onProgress)`.
|
||||||
6. `chooseMove()` either returns immediately for heuristic tiers or performs batched master search while reporting `AIDecisionProgress`.
|
6. `AIWorkerClient` posts a typed request into `ai.worker.ts`; if worker setup fails, it falls back to in-thread `chooseMove()`.
|
||||||
7. `GameScene.executeMove()` applies the move, updates the tracker, animates the result, refreshes the HUD, and advances the round.
|
7. `chooseMove()` either returns immediately for heuristic tiers or performs batched master search while reporting `AIDecisionProgress`.
|
||||||
8. When all hands are empty, `engine.ts` finalizes scoring and `GameScene` displays the round summary or final match screen.
|
8. Worker progress messages drive `GameScene.updateThinkBar()` until a result is posted back.
|
||||||
|
9. `GameScene.executeMove()` applies the move, updates the tracker, animates the result, refreshes the HUD, and advances the round.
|
||||||
|
10. When all hands are empty, `engine.ts` finalizes scoring and `GameScene` displays the round summary or final match screen.
|
||||||
|
|
||||||
## Build System
|
## Build System
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
# Findings
|
# Findings
|
||||||
|
|
||||||
> Last Updated: 2026-04-02T18:12:18.000Z
|
> Last Updated: 2026-04-02T19:05:00.000Z
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
Initializer refresh for the current Scopone Scientifico codebase. The existing findings were stale relative to the latest AI and tracker implementation, so the observations below reflect the current source tree.
|
Initializer refresh for the current Scopone Scientifico codebase. The existing findings were stale relative to the current worker-backed AI execution path, so the observations below reflect the live source tree.
|
||||||
|
|
||||||
## Codebase Observations
|
## Codebase Observations
|
||||||
|
|
||||||
- Primary gameplay code lives in 8 TypeScript source files under `src/`; the Android wrapper adds 3 Java files.
|
- Primary gameplay code lives in 8 TypeScript source files under `src/`; the Android wrapper adds 3 Java files.
|
||||||
- The largest modules are `src/scenes/GameScene.ts` (1446 lines) and `src/game/ai.ts` (1210 lines).
|
- The gameplay runtime now includes three AI transport files in addition to the rules engine: `ai-worker-protocol.ts`, `ai-worker-client.ts`, and `ai.worker.ts`.
|
||||||
|
- The largest concentration of logic still sits in `src/scenes/GameScene.ts` and `src/game/ai.ts`.
|
||||||
- `src/game/` remains framework-independent and contains the rules engine, score calculation, card tracker, and AI logic.
|
- `src/game/` remains framework-independent and contains the rules engine, score calculation, card tracker, and AI logic.
|
||||||
- The AI now has three distinct difficulty levels: `beginner`, `advanced`, and `master`.
|
- The AI now has three distinct difficulty levels: `beginner`, `advanced`, and `master`.
|
||||||
- The `advanced` and `master` tiers use `CardTracker` to reason about unseen cards instead of reading hidden hands directly.
|
- The `advanced` and `master` tiers use `CardTracker` to reason about unseen cards instead of reading hidden hands directly.
|
||||||
- The `master` tier performs determinization plus alpha-beta search and reports progress back to the scene.
|
- The `master` tier performs determinization plus alpha-beta search and reports progress back through `AIDecisionProgress`.
|
||||||
- `GameScene` displays AI progress through a top think bar and updates it from the `AIDecisionProgress` callback.
|
- `GameScene` displays AI progress through a top think bar and updates it from worker-forwarded progress messages.
|
||||||
|
- `AIWorkerClient` degrades cleanly to in-thread `chooseMove()` execution when workers are unavailable or fail.
|
||||||
- Audio remains fully procedural via Web Audio; no audio asset pipeline is present.
|
- Audio remains fully procedural via Web Audio; no audio asset pipeline is present.
|
||||||
- No ESLint or Prettier config is present.
|
- No ESLint or Prettier config is present.
|
||||||
- The only repository-wide verification command supplied is `npx tsc --noEmit`.
|
- The only repository-wide verification command supplied is `npx tsc --noEmit`.
|
||||||
@@ -23,6 +25,7 @@ Initializer refresh for the current Scopone Scientifico codebase. The existing f
|
|||||||
|
|
||||||
- `GameScene.ts` still centralizes scene layout, input, effects, audio, HUD, and round transitions in one file, which raises maintenance cost.
|
- `GameScene.ts` still centralizes scene layout, input, effects, audio, HUD, and round transitions in one file, which raises maintenance cost.
|
||||||
- `ai.ts` mixes heuristic tiers, inference helpers, determinization, and alpha-beta evaluation in one module.
|
- `ai.ts` mixes heuristic tiers, inference helpers, determinization, and alpha-beta evaluation in one module.
|
||||||
|
- Worker message types and fallback behavior are separated cleanly, but the UI still knows about AI progress presentation details directly.
|
||||||
- The `master` profile allows up to 9800 ms of search budget, which may be expensive on slower devices even with batch yielding.
|
- The `master` profile allows up to 9800 ms of search budget, which may be expensive on slower devices even with batch yielding.
|
||||||
- There is still no dedicated automated test suite for rules or AI behavior beyond type-checking.
|
- There is still no dedicated automated test suite for rules or AI behavior beyond type-checking.
|
||||||
- Formatting rules are enforced socially rather than by a linter/formatter toolchain.
|
- Formatting rules are enforced socially rather than by a linter/formatter toolchain.
|
||||||
@@ -43,6 +46,14 @@ Initializer refresh for the current Scopone Scientifico codebase. The existing f
|
|||||||
- `master` orders legal moves with a quick evaluator, samples hidden hands, then scores moves with alpha-beta search under a deadline.
|
- `master` orders legal moves with a quick evaluator, samples hidden hands, then scores moves with alpha-beta search under a deadline.
|
||||||
- `masterMove()` yields back to the browser between batches so Phaser can repaint the progress UI.
|
- `masterMove()` yields back to the browser between batches so Phaser can repaint the progress UI.
|
||||||
|
|
||||||
|
### Worker execution snapshot
|
||||||
|
|
||||||
|
- `GameScene` creates a fresh `AIWorkerClient` on scene creation and disposes it on shutdown.
|
||||||
|
- `AIWorkerClient` serializes a tracker snapshot instead of sending a live `CardTracker` instance across the worker boundary.
|
||||||
|
- `ai.worker.ts` reconstructs tracker state with `CardTracker.fromSnapshot()` before calling `chooseMove()`.
|
||||||
|
- Progress, results, and serialized worker errors all travel through `ai-worker-protocol.ts`.
|
||||||
|
- If worker initialization, posting, or message deserialization fails, pending requests are rerun with the in-thread AI path.
|
||||||
|
|
||||||
### Scene / UI implementation snapshot
|
### Scene / UI implementation snapshot
|
||||||
|
|
||||||
- `MenuScene` exposes difficulty selection before match start.
|
- `MenuScene` exposes difficulty selection before match start.
|
||||||
|
|||||||
Reference in New Issue
Block a user