diff --git a/src/engine.ts b/src/engine.ts index a3ab288..f671ac0 100644 --- a/src/engine.ts +++ b/src/engine.ts @@ -213,7 +213,7 @@ export function resolveEventChoice(state: State, choiceIndex: number): State { } interface LocationVisit { - text: string; + texts: string[]; effect: Partial<{ andakt: number; dread: number; kaos: number; ritual: number; hemlighet: number }>; requiresArea?: keyof State['areas']; lockedText: string; @@ -221,40 +221,68 @@ interface LocationVisit { const LOCATION_VISITS: Record = { rosengard: { - text: 'Du sitter i källaren. Lamporna flimrar i takt med ditt hjärta. Eller tvärtom. +andakt', + texts: [ + 'Du sitter i källaren. Lamporna flimrar i takt med ditt hjärta. Eller tvärtom. +andakt', + 'Någon har städat källaren medan ingen var där. Ingen av er erkänner sig skyldig. +andakt', + 'Den varma stolen är varm igen. Ingen har suttit i den. +andakt', + ], effect: { andakt: 15 }, requiresArea: 'rosengard', lockedText: 'En fuktig källarlokal i Rosengård. Du kan se ljuset under dörren. Ni är inte redo än.', }, varnhem: { - text: 'Cirkeln är lite större sedan du var här sist. Du ritade den inte. +dread +ritual', + texts: [ + 'Cirkeln är lite större sedan du var här sist. Du ritade den inte. +dread +ritual', + 'Kritan på asfalten har inte suddats trots regnet i natt. +dread +ritual', + 'Torget är tomt förutom en duva som går i exakt cirkelns mönster. +dread +ritual', + ], effect: { dread: 8, ritual: 2 }, requiresArea: 'varnhem', lockedText: 'Värnhemstorget ser normalt ut. Det är ett dåligt tecken.', }, torso: { - text: 'Byggnaden pekar. Du tittar dit den pekar. Du tittar bort igen. Det hjälper inte. +dread +ritual', + texts: [ + 'Byggnaden pekar. Du tittar dit den pekar. Du tittar bort igen. Det hjälper inte. +dread +ritual', + 'Ett fönster högt uppe är tänt som det aldrig varit förut. Ingen bor där. Ingen har någonsin bott där. +dread +ritual', + 'Torso vrider sig en grad till i vinden som inte finns. +dread +ritual', + ], effect: { dread: 15, ritual: 5 }, requiresArea: 'torso', lockedText: 'Turning Torso vrider sig i vinden. Inte i vinden. I något annat.', }, oresund: { - text: 'Vattnet sjunker lite långsammare just nu. Det vet att du stod här. +dread', + texts: [ + 'Vattnet sjunker lite långsammare just nu. Det vet att du stod här. +dread', + 'En färja passerar utan ljud. Ingen ombord vinkar. Alla ombord tittar rakt på dig. +dread', + 'Bron surrar på en frekvens du känner i tänderna snarare än öronen. +dread', + ], effect: { dread: 5 }, lockedText: 'Öresund. Danskarna på andra sidan verkar inte märka någonting. Det är det mest oroande av allt.', }, ribersborg: { - text: 'Änderna tittar på dig. En av dem nickar. Du nickar tillbaka. Det var ett misstag. +andakt', + texts: [ + 'Änderna tittar på dig. En av dem nickar. Du nickar tillbaka. Det var ett misstag. +andakt', + 'Alla änderna vänder sig samtidigt mot Turning Torso när du kommer. +andakt', + 'Sanden är kall trots solen. Ingen annan verkar märka det. +andakt', + ], effect: { andakt: 8 }, lockedText: 'Stranden är tom nu. Änderna sitter stilla. De väntar på rätt tidpunkt.', }, davidshall: { - text: 'Källarlokalen luktar fortfarande. Du andas djupare än du borde. +andakt', + texts: [ + 'Källarlokalen luktar fortfarande. Du andas djupare än du borde. +andakt', + 'Kaklet från 1923 är kallt att röra vid, oavsett årstid. +andakt', + 'Grannen genom väggen sjunger något som nästan, men inte riktigt, är en psalm. +andakt', + ], effect: { andakt: 10 }, lockedText: 'Davidshallsgatan. Kakel från 1923. Bakom det finns något som väljer att vänta.', }, stortorget: { - text: 'Du vet inte varför du kom hit. Du vet inte hur länge du stod här. +kaos', + texts: [ + 'Du vet inte varför du kom hit. Du vet inte hur länge du stod här. +kaos', + 'Statyn på torget har flyttat en centimeter sedan i förra veckan. Du är den enda som mätt. +kaos', + 'Alla klockor på torget visar olika tid. Ingen av dem är fel. +kaos', + ], effect: { kaos: 8 }, lockedText: 'Stortorget är fullt av folk som inte vet vad de gör här heller. Du passar in.', }, @@ -272,7 +300,7 @@ export function visitLocation(state: State, id: string, cooldowns: Map void, onRest +
+
@@ -172,6 +174,11 @@ export function renderState(state: State): void { setBar('bar-hemlighet', state.hemlighet); setBar('bar-kaos', state.kaos); + // Ambient visual reactivity — the deeper the dread, the more the world tilts; low hemlighet bleeds red at the edges. + const root = document.documentElement.style; + root.setProperty('--dread-intensity', Math.min(1, state.dread / 150).toFixed(3)); + root.setProperty('--hemlighet-danger', (state.hemlighet < 40 ? (1 - state.hemlighet / 40) * 0.35 : 0).toFixed(3)); + const ritualSection = document.getElementById('ritual-section')!; if (state.ritualUnlocked) { ritualSection.style.display = ''; @@ -287,6 +294,13 @@ function renderLog(state: State): void { `
${e.text}
` ).join(''); log.scrollTop = 0; + + if (state.log[0]?.kind === 'kaos') { + const app = document.getElementById('app')!; + app.classList.remove('kaos-glitch'); + void app.offsetWidth; // restart animation + app.classList.add('kaos-glitch'); + } } function showOverlay(state: State): void {