| # Game State Machine |
|
|
| Deterministic rules the server enforces per session. Derived from PLAN ยง4 and ยง6.3. |
| The model never decides act transitions โ the server does, from these rules. |
|
|
| ## Session state object |
| ```json |
| { |
| "session_id": "uuid", |
| "turn": 0, |
| "act": 1, |
| "tones_seen_count": {}, // tone id -> times Lily has emitted it (tones_seen = its keys) |
| "lexicon": {}, // tone id -> { guess: str, confidence: "red|amber|teal|green" } |
| "notes_unlocked": [], // note ids, in unlock order |
| "empathy": 0, // rises on caring/personal player questions (see below) |
| "finale_played": false |
| } |
| ``` |
|
|
| - **lexicon_size** = count of lexicon entries with a non-empty `guess`. |
| - A tone is "active" this turn if its `act_active <= act` (see `data/tones.json`). |
| - **Per-act tone cap** (`ACT_TONE_CAP` in `app/game.py`): Lily's reply is trimmed to |
| at most {Act I: 3, Act II: 5, Act III: 7} tones, so early phrases stay short and |
| decodable. The prompt also asks for the matching count per act. |
| - **empathy** rises by 1 on any turn whose message hits a caring cue (`EMPATHY_CUES`) |
| or a personal-question cue (`PERSONAL_CUES`) โ heuristic in `app/game.py`, upgradable |
| to Nemotron (Phase 6). Gates the `empathy` evidence notes. |
|
|
| ## Tone activation tiers (PLAN 6.3; Act I widened for learnability) |
| | Tier | Active from | Tones | Count active | |
| |---|---|---|---| |
| | Act I start | act 1 | โ โ โณ โฟ โญ โฎ โ โ โ โก | 10 | |
| | Transition + Act II | act 2 | + โ โฝ โ โ โฃ โซ โฏ โ | 18 | |
| | Act III | act 3 | + โป โ โ โ โ โ
| 24 | |
|
|
| (In `tones.json`: `act_active` is 1, 2, or 3. `time_now` (โฟ) and `act_stay` (โ) were |
| promoted from Act II to Act I so Lily has enough vocabulary to be coherent early โ |
| she can ground feeling in the present and express intent ("you / stay / now"). The |
| total still reaches 18 by Act II and 24 by Act III, so the later gates are unchanged.) |
|
|
| ## Act transitions |
| Evaluated after each turn. Forward-only; never regress. |
|
|
| **Act I โ Act II** when BOTH: |
| - `lexicon_size >= 5` (at least 5 lexicon entries โ PLAN 4.2), AND |
| - at least `max(5, len(ACT1_TONES) - 3)` Act-I tones have been seen โฅ 2ร (currently |
| 7 of 10). Relaxed from "every Act-I tone twice" so widening Act I vocabulary doesn't |
| stall progression; a couple of rarely-used tones are tolerated. |
|
|
| **Act II โ Act III** when BOTH: |
| - `len(tones_seen) >= 18` (18 of 27 tones seen โ PLAN 4.3), AND |
| - note `N07` (travel fund + passport) is unlocked. |
|
|
| **Finale** โ within Act III, when `len(tones_seen) == 27` AND `N10` unlocked: |
| the server may trigger the ending sequence (`special: "finale"`), set |
| `finale_played = true`. After that, normal input is closed; the ending plays out |
| (PLAN 4.5). |
|
|
| ## Note unlocks (see data/notes.json) โ 15 notes |
| Re-evaluated every turn (`act >= note.act` always required): |
| - **threshold notes** unlock when `lexicon_size >= unlock_value`. |
| - **topic notes** unlock when the turn's `topic_signal == note.unlock_value`. Signals: |
| `music`, `university`, `relationship`, `family`, `travel`. The `family` and `travel` |
| signals also have server-side keyword fallbacks (`FAMILY_CUES`, `TRAVEL_CUES`) when |
| the model misses them. |
| - **empathy notes** unlock when `empathy >= unlock_value` โ the vulnerable backstory |
| (friend's statement, mother's voicemail, wellbeing slip, the reconstructed evening), |
| gated behind the detective showing care. Thresholds: N15=2, N12=3, N13=4, N14=5. |
| - `N10` requires every tone *seen* (`len(tones_seen) == 27`, per PLAN 7.3) โ special-cased. |
|
|
| Each note also carries `found` (investigation provenance, shown on the card), an |
| optional `hint` (`{tone_id, text}` surfaced in the lexicon once that tone is heard โ |
| evidence helps decode the language), and `summary`/`order` (the "Her Story" tab |
| assembles found summaries into a narrative, sequenced by `order`). |
|
|
| ## Atmosphere coupling (Phase 7) |
| Act drives the UI color temperature (Tailwind CSS vars on `body[data-act]`): |
| - Act I โ warm cream / amber. Act II โ gray-amber. Act III โ near-monochrome cold. |
|
|
| Note: ambient background music was **removed** by design โ only the tones make sound. |
| The PLAN 6.5 "music EQ shift per act" no longer applies; color temperature is the |
| remaining act-coupled atmosphere (Phase 7.2). |
|
|