Reuses the lightbox already built for the character gallery. Clicking
any location still triggers the visit as before, but now also probes
for that location's art and, if it exists, pops it up full-size with
a caption — no modal for locations that don't have art yet, the visit
still happens either way.
Also added a standing "about this place" blurb per location (map.ts's
new LOCATION_INFO), shown under the art. This is distinct from
LOCATION_VISITS' randomized per-visit outcome text in engine.ts, which
still changes every time — the blurb is a fixed description of the
place itself, not what just happened there.
Verified via headless browser: clicking Turning Torso's marker pops
the lightbox with its real art, label, and blurb, no console errors.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
All map markers now show real art in their tooltip preview instead
of falling back to text-only. Fixed two filename mismatches against
what map.ts expects (id-based, e.g. "universitet.png" not the
Swedish definite form "universitetet.png"). Kept the stronger of two
Ribersborg takes — the one with Turning Torso on the skyline ties it
back to the game's central landmark, and the ducks facing camera
reads eerier than facing away.
Verified via headless browser: all 9 markers present, thumbnails
load without error, tooltip renders image + label together.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Map markers now show a tiny thumbnail preview in their tooltip when
art exists for that location (same missing-asset-is-fine fallback
as character portraits — onerror just removes the broken img).
- Two new locations, both free-roam from the start: Möllevångstorget
and Malmö universitet (the latter ties into the researcher
character's arc). VISITABLE_LOCATION_IDS picks them up automatically
since it's derived from the data, not a separate list.
- Sällskapet gets a second mode: "Fullständigt arkiv" shows every
character's real portrait and bio regardless of story progress
(bypassing the usedEventIds lock), and clicking any known portrait
opens a lightbox at full size instead of the cropped card thumbnail.
- All 9 character portraits are now in and wired (fixed two more
filename mismatches along the way: anneli-karin and the rest use
hyphens, not underscores, matching what was actually generated).
- More content: 2 new location-visit variants each for the two new
areas, 6 new Standard events (including a found 1930s photograph
that seems to show Lindqvist in a room nobody recognizes), 4 new
Kaos events tied to the new locations and existing ones.
- Caught and fixed a bug in my own new content before commit: an
event's requires.completedEventId pointed at an upgrade id, which
can never appear in usedEventIds — switched to a minRitual check
that actually gates on the right precondition.
Verified: 15/15 tests, clean typecheck and build, and a real
headless-browser pass — all 9 map markers present, full-archive mode
correctly bypassing locks, and the lightbox opening at full size with
a caption.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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>
Purple downward-chevron mark matching the site's eldritch-purple accent, in the same rounded-square favicon style used across the other self-hosted projects.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
node_modules/.git/dist were being sent on every build with no
.dockerignore at all — same class of fix as goonk's recent deploy-speed
pass. Verified by building with the new file in place (adventure and
new spot-checked with a full container run + health check; the rest
share the same multi-stage Dockerfile pattern).
Balance: an optimal-play simulation showed the game finishing in
under 3 minutes, mostly because torso_beacon + grand_ritual_prep
alone pushed ritualRate to 2.5 — enough to clear the last 50 ritual
points in 20 seconds. Softened those boosts (0.5→0.15, 2→0.35),
raised deepen_ritual's cost curve so it's a real endgame sink instead
of a one-off top-up, and added two new late-game upgrades (sunken
choir, nine filled chairs) between grand_ritual_prep and the win.
Re-simulated: a greedy optimal-play bot now takes ~5 minutes instead
of ~3 and surfaces ~40 distinct events instead of ~30 out of a much
larger pool — real (non-bot) play should run considerably longer.
Content: added 8 new high-dread late-game standard events (gated up
to minDread 400, since nothing previously escalated past 75) and 7
new kaos events, plus one more choice event.
Kaos events no longer get marked as permanently used — they're
chaos-relief flavor, not narrative progression, and a ~24-entry pool
(now 30) was depleting for good over a long game. Standard/chain
events remain single-use.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The overlay's radial gradient was much darker/broader than the intro
scrim, crushing the win/loss artwork (the inverted Torso, the ritual
circle) that the intro screen showed off fine. Dropped the opacity
stops so the same restrained look applies everywhere.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- The log view only re-rendered when state.log.length changed, but the
log is capped at 40 entries — so once a run had logged 40+ things
(easy in a normal session), every entry after that point, including
choice-event outcomes, upgrade purchases, and location visits,
stopped appearing even though the underlying state updated. Fixed
by tracking a monotonic logSeq counter that increments on every
push regardless of the cap, and rendering off that instead of
array length. Consolidated the repeated unshift+cap logic into one
pushLog() helper so future call sites can't reintroduce the bug.
- Added a pause button (and "PAUSAD" indicator) that freezes the tick
loop without touching game state, so a hectic run can be paused to
think without it counting as a save-scummy state mutation. Manual
actions (buying upgrades, visiting locations) still work while
paused, since that's usually the point of pausing.
- The "Aktiva områden" sidebar only ever listed the 3 story-gated
core areas, while the map has 7 clickable locations — making it
look like 4 of the map pins didn't really exist. Split the panel
into "Ritualens kärnplatser" (the 3 gated ones, unlock status shown
as before) and "Övriga platser" (the 4 always-open flavor
locations), so the sidebar and map agree.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Covers the choice events, NPC chains, location text variety, ambient
visual reactivity, intro screen, win/loss art, and the abandon option
added across the last few changes. Also fixes a handful of spelling
and word-choice mistakes found in a sweep of the event text
("blinkmat"→"blinkat", a "summera"/summon false-friend, a stray
English "return" in "Returndatumet", and one word that didn't fit).
Intro and win/loss screens now use a constrained gradient scrim
around the text instead of a flat overlay covering the whole image,
so the artwork stays visible instead of being crushed to black.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Covers the choice events, NPC chains, location text variety, ambient
visual reactivity, intro screen, win/loss art, and the abandon option
added across the last few changes. Also fixes a handful of spelling
and word-choice mistakes found in a sweep of the event text
("blinkmat"→"blinkat", a "summera"/summon false-friend, a stray
English "return" in "Returndatumet", and one word that didn't fit).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Adds a full-screen intro/title screen (new 'intro' game phase) with
a moody Malmö/Turning Torso background and a "Börja ritualen"
button; the game no longer starts ticking until the player begins.
- Win and loss overlays now show matching generated artwork behind
the existing text, instead of a flat scrim.
- New "Avbryt" header button lets the player abandon a run mid-game
(with a confirm prompt) via a new 'abandoned' phase, reusing the
existing overlay/restart flow.
- Source images converted from PNG (~2.1MB each) to WebP (~120KB
each) and placed under public/img/ so Vite serves them as-is.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- #app's filter (hue-rotate/saturate) now tracks dread continuously,
and a fixed vignette bleeds red as hemlighet drops below 40 — no
new assets, just CSS driven by existing state.
- A kaos log entry now triggers a brief screen-glitch shake.
- Location visits pick from 3 flavor-text variants per site instead
of a single fixed line, so repeat visits don't repeat verbatim.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Events can now depend on a previously-set flag and a completed event
id, letting a choice made early in the game (e.g. whether Lindqvist's
whisper was heeded) shape which follow-up events surface later. Adds
two 3-step chains as a first example of persistent NPC arcs.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Standard/kaos events can now present 2 options instead of a fixed
effect, pausing new event triggers until the player answers. Adds
4 choice events as a first batch; resources keep accruing while a
choice is pending.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds an influence currency that scales with follower count and a new
"exert influence" action to trade it for secrecy, uncaps recruiting
with scaling cost, adds a late-game Andakt sink, and makes hemlighet
drain scale with dread/ritual progress so the endgame carries real
risk. Includes a Vitest suite that simulates play to check balance,
which caught the influence-accrual rate being too slow to be useful
early game.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Help modal (? button or keyboard shortcut): how-to-play in Swedish,
flavor text, full changelog sourced from src/data/version.ts
- src/data/version.ts: versioned changelog entries, in-universe Malmö voice
- Map zone clicks: each location on the Leaflet map is now clickable.
Unlocked cult areas give resources + log entries. Locked locations show
lore hints. 30s cooldown per location so it's a decision, not a spam button.
- Dockerfile + nginx.conf + docker-compose.yml (port 5684)
- Gitea CI workflow (identical to 2048 — derives image from repo path, needs
TKNTKN secret, pushes :latest and :sha tags)
- README.md with mechanics summary and docker instructions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 20+ new events drawing from Anders Fager, Kult, and Call of Cthulhu:
ICA cashiers who never blink, SJ trains stopping in non-existent tunnels,
Kult lictors as city officials, death servants finishing lectures, Deep Ones,
investigators dreaming about us, stars being right over Lund Observatory
- Rewrite upgrade descriptions to match the register: mundane detail,
matter-of-fact horror, no melodrama
- Add a new mid-game upgrade (Paktens Förnyelse) to smooth the progression
- Fix recruit button: was destroying DOM every 30fps tick, killing mousedown→click
events; now only rebuilds when availability/affordability actually changes
- Fix double andakt deduction in recruit effect
- Fix map growing over log (proper flex constraints)
- Add localStorage save/load with versioned key (SAVE_VERSION bump invalidates
old saves); autosaves every 10s and on upgrade purchase, clears on restart
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
recruit_neighbor was gated behind !first_meeting so it vanished after
the first upgrade. Now a single repeatable recruit with scaling cost.
Log scrolls to top on new entries so most recent is always visible.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Idle cult management game set in Malmö, Sweden. Manage Troende,
Andakt, Dread, Hemlighet and Kaos while completing the Grand Ritual
before investigators shut you down. Lovecraftian flavour, Henderson-
tier chaos events, OSM/Leaflet map with dread spread markers across
Rosengård, Värnhemstorget, Turning Torso and Øresundsbron.
Vanilla TypeScript + Vite, no framework.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>