import './style.css'; import { createState, tick, buyUpgrade, visitLocation, resolveEventChoice, startGame, abandonGame, saveState, loadState, clearSave } from './engine.ts'; import { initUI, renderState, setPausedUI } from './ui.ts'; import { initMap, updateMap } from './map.ts'; let state = loadState() ?? createState(); let visitCooldowns = new Map(); let paused = false; let lastTime = 0; const TARGET_FPS = 30; const FRAME_MS = 1000 / TARGET_FPS; const SAVE_INTERVAL_MS = 10_000; let lastSaveTime = 0; function start(): void { const app = document.getElementById('app')!; initUI(app, (id) => { state = buyUpgrade(state, id); renderState(state); saveState(state); }, () => { clearSave(); state = createState(); visitCooldowns = new Map(); document.getElementById('overlay')!.classList.remove('visible'); renderState(state); }, (index) => { state = resolveEventChoice(state, index); renderState(state); saveState(state); }, () => { state = startGame(state); renderState(state); saveState(state); }, () => { state = abandonGame(state); renderState(state); saveState(state); }, () => { paused = !paused; setPausedUI(paused); } ); initMap('map', (locationId) => { const result = visitLocation(state, locationId, visitCooldowns); state = result.state; visitCooldowns = result.cooldowns; renderState(state); }); renderState(state); requestAnimationFrame(loop); } function loop(now: number): void { if (now - lastTime >= FRAME_MS) { lastTime = now; if (state.phase === 'playing' && !paused) { state = tick(state); renderState(state); updateMap(state.dread, state.areas); } if (now - lastSaveTime >= SAVE_INTERVAL_MS) { lastSaveTime = now; saveState(state); } } requestAnimationFrame(loop); } start();