Add offline progress, tab haunting, character gallery, more flavor

Real depth additions, not a reskin of another idle game:

- applyOfflineProgress: the cult continues while the tab is closed or
  backgrounded (rAF throttles hard when hidden, so real time drifts
  well past simulated time). Approximates tick()'s per-second rates
  over the elapsed window, capped at 24h, with a narrative "while you
  were away" log line scaled to how long that was. Can end the game
  in a win or loss if the numbers would have gotten there. Re-checked
  on every tab-visibility return too, not just page load.
- Tab-title haunting: document.title cycles short eerie lines
  ("Han väntar…", "Havet kallar…") while the tab is hidden, restores
  on return.
- New late-game upgrade "Viskningen leder er" — once bought, the cult
  visits map locations on its own occasionally without a click. A
  small loss-of-agency horror beat, not just a QoL toggle.
- Log's newest line now types itself out, with characters
  occasionally swapped for occult symbols (☿☠ψ) at a rate scaled to
  current dread. Older lines stay static and legible — this never
  applies retroactively.
- New "Sällskapet" character gallery: cards for every named recurring
  character, locked to a silhouette + "???" until you've actually met
  them (checked against usedEventIds). Portraits are optional — missing
  art falls back to an initial-letter placeholder, so this works
  incrementally as art gets added. First five real portraits included.
- Real bug fix: several Kaos events referenced characters (Göran,
  Bengt-Åke, the Sydsvenskan journalist) as if already introduced,
  but had no ordering dependency on the Standard event that actually
  introduces them — so a fresh cultist could show up in the log
  already "familiar" before you'd ever met them. Gated with
  requires.completedEventId.
- More flavor text throughout: two new variants per location visit,
  6 new Standard events, 4 new Kaos events.

Evaluated three other ideas from the same source and declined them:
a generic milestone-triggered log (Djupet's log already reacts to
real state, not arbitrary point totals), an investigator combat
minigame (hemlighet draining to zero already does this job, and
tower-defense clicking would fight the game's actual tone), and a
node-sequencing ritual minigame (real scope for a twitch mechanic
that doesn't match the rest of the game's pacing).

Verified: 15/15 tests passing, clean typecheck and production build,
and a real headless-browser pass — offline catch-up after a
simulated 5-hour gap, tab-title cycling and restore, and the
character gallery rendering real portraits alongside locked cards.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Fredrik Johansson
2026-08-01 20:53:26 +02:00
co-authored by Claude Sonnet 5
parent 1eb9c43625
commit aeedf0abb5
14 changed files with 581 additions and 8 deletions
+9
View File
@@ -119,6 +119,15 @@ export const UPGRADES: Upgrade[] = [
available: s => s.upgrades.has('grand_ritual_prep'),
once: false,
},
{
id: 'whisper_guidance',
name: 'Viskningen leder er',
desc: 'Ni behöver inte längre besluta vart ni går. Fötterna vet vägen innan huvudet gör det. Bekvämt. Det är också första gången ingen av er är helt säker på vem som bestämmer längre.',
cost: () => ({ andakt: 600, dread: 80 }),
effect: () => { /* handled by main.ts's tick loop — see WHISPER_INTERVAL_TICKS */ },
available: s => s.upgrades.has('torso_beacon') && !s.upgrades.has('whisper_guidance'),
once: true,
},
];
function ritualDeepenings(s: State): number {