Stop 401 responses from wiping local saves and force-reloading. Fix logout
race condition with final cloud save before token invalidation. Replace
hard 3-failure cap with exponential backoff (2min to 30min). Switch cloud
save interval from tick-based (30s) to wall-clock (5min). Add cloud save
status indicator and Force Save button in TopBar. Show save conflict
dialog on login when both local and cloud saves exist. Add cloud save
list, download, and delete in Settings. Server now keeps 10 save snapshots
per user instead of overwriting a single save.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After logout and re-login, the cloud save was never fetched because
useAuthGate.init() had already run with an anonymous token. Now
handleSetRegistered fetches and restores the cloud save when the user
becomes registered, so they return directly to their game.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Moved chords up an octave (C4-E5 range), switched to triangle waves,
faster LFO rates, all major voicings, and higher filter cutoff. The
previous version with sub-bass sine drones and ultra-slow modulation
was genuinely terrifying.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Synthesized audio system with 9 distinct SFX (click, success, warning,
danger, purchase, achievement, era transition, info) mapped to all game
notifications, plus generative ambient background music with chord
progressions. Adds SFX volume slider to settings alongside existing
music volume control. No audio files or npm dependencies needed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cloud saves were fully built but never wired up — useCloudSave() hook was
never called, no load-from-cloud flow existed, and there was no way to
continue a saved game. Logout was completely missing (no endpoint, no UI).
Accounts felt like a gate behind the invite wall rather than real accounts.
Backend: add tokenVersion to users for server-side token invalidation,
POST /auth/logout bumps it to revoke all JWTs, GET /auth/me returns
profile, GET /saves/latest returns most recent save with full gameData.
All createToken calls now include tokenVersion. Auth middleware rejects
tokens with stale tokenVersion.
Frontend: wire up useCloudSave() in App (auto-saves every 60 ticks with
error handling), fetch cloud save on startup for registered users, show
"Continue Your Game" card on NewGameScreen, add Log Out button with
confirmation in Settings, show username in sidebar, 401 interceptor
clears auth and reloads.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Seed checks for any admin role instead of username='admin'
- Username change open to all registered users (was admin-only)
- New change-email endpoint requiring password confirmation
- Settings page: inline editing for username and email
- Invitations: await refresh after generate so list updates visibly
- Invitations: revoke button to delete unused invites (admin only)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use ?? instead of || so empty string (same-origin) is preserved
while undefined still falls back to localhost:3001 for dev.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
VITE_API_URL was /api but all API paths already included /api/,
resulting in /api/api/config etc. Config call failed silently and
defaulted to requireInvite:false. Set VITE_API_URL to empty string
so paths like /api/auth/anonymous go through nginx as-is.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Frontend API_BASE is /api in production, so health check was hitting
/api/health which didn't exist. Added /api/health on the server and
removed the now-unnecessary separate nginx /health proxy rule.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
"Unknown error" was hiding the actual HTTP status (likely 502 from
nginx). Now shows "HTTP 502 Bad Gateway" etc. Network TypeErrors
(connection refused) also get a clear message.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The frontend builds with VITE_API_URL=/api so all API calls target
the same origin. Without a proxy rule, nginx was serving index.html
for API paths, causing JSON parse errors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Frontend now checks /health before starting auth flow. Shows a clear
"Cannot Connect to Server" screen with retry button when backend is
unreachable. Stale non-JWT tokens in localStorage are detected and
cleared automatically. All API calls have a 10s timeout via AbortController.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Run Drizzle migrations before seeding admin user so tables exist
on fresh database. Migration files generated from current schema.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The production Docker stage was copying pnpm symlinks between stages
which broke module resolution. Now does a fresh pnpm install --prod
in the production stage and runs from the server working directory.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Churned subscribers no longer generate revenue the tick they leave,
and the price churn multiplier cap is raised from 10 to 1000 so
astronomical prices empty the subscriber pool in a single tick.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Players could set astronomical prices and still retain subscribers because
price elasticity floored at 10% for any price above $100, satisfaction
ignored pricing entirely, and churn had no price component.
Introduces perceived value per tier (model quality × reputation), replaces
the broken linear formula with sigmoid decay, adds price-aware satisfaction
blending, and applies per-tier price-based churn multipliers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Propagate per-era duration/bottleneck, serving utilization, cash-flow nadir/peak,
and late-game revenue growth through the worker→CSV→interpret pipeline. Add
simulation health archetype classification, per-era bottleneck frequency,
unused-feature frequency table, failed-run AGI gate analysis, and log-scale
variance for exponential metrics. All new CSV columns parse defensively for
backward compatibility with older summary files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Eliminates the 22K-object switchRegistry that caused O(n×m) scans 4x per tick.
Network health is now tracked as aggregate counts per tier (totalByTier/healthyByTier)
with RepairBatch timers, cutting late-game tick cost from ~50ms to ~0.3ms.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fleet template is now rebuilt only when deploymentVersion changes (~68 times per
28,800-tick run instead of every tick). Reuses module-level Maps, arrays, and
utilization objects instead of allocating new ones each tick. Replaces 4x
Object.values().reduce() with single-pass aggregation and sorts fleet in-place.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Model quality for market segments and product lines now derives from deployed
model capabilities (coding, reasoning, agents, etc.) instead of requiring a
separate manual benchmark evaluation step. This eliminates an unbounded
benchmarkResults[] array that was scanned 5x per tick and removes ~480 lines
of dead-weight UI, types, and engine code.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Switch from exec() to spawn() for streaming stderr, add onProgress
callback to runner, and emit per-run progress lines from workers.
CI now shows live percentage, tick count, and era during long runs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Research now costs money (drained per-tick) with ~2.5-3.5x longer durations by category.
Early-game talent budget costs reduced via era multiplier (startup 0.2x → bigtech 1.0x).
New seed-driven PersonaStrategy with 8 axes of variation for meaningful multi-run testing.
CI multi-run switched from greedy to persona strategy.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove misleading Reputation -> Era Gates connection (score 0 meant
"already sufficient," not broken). Add diagnosis and eventLabel fields
to each connection. Group output: broken links first with [!!] and
plain-language explanation, then healthy links as compact one-liners.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a full simulation harness (game-simulation package) with greedy/random strategies,
36-metric diagnostics, multi-run orchestration via child processes, and a statistical
interpreter. Includes 2.3x engine performance optimizations (research bonus caching,
per-DC dirty tracking, reduced allocations in tick pipeline, single-pass loops).
Fixes a critical balance bug where training pipelines stalled on insufficient VRAM would
permanently block training slots — the engine never re-checked stalled pipelines, and the
greedy strategy didn't pre-check VRAM requirements. This caused 20-25% of seeds to get
stuck in Scale-up era. All three fixes (engine un-stalling, strategy VRAM pre-check,
stalled pipeline cancellation) bring pass rate from 75% to 100% across 20 random seeds.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add compute history time-series (capacity vs demand chart), revenue vs expenses
dual-line chart, enhanced system status (training allocation, network uptime,
model freshness), active operations panel, market position bars, and competitor
snapshot. Stat cards expand from 3 to 6 as player progresses through eras.
Graceful v9→v10 save migration preserves existing games.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>