Initial scaffold: AI Tycoon monorepo with core game loop

Turborepo monorepo with three packages:
- packages/shared: TypeScript types for all 14 game systems + balance constants + formatting utils
- packages/game-engine: Pure TS simulation engine with tick processor, economy, infrastructure, compute, research, market, and reputation systems
- apps/web: React + Vite + Tailwind + Zustand frontend with sidebar dashboard layout, new game screen, dashboard with charts, infrastructure management, and model training pages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-24 16:53:46 -04:00
commit fdc8e544ae
57 changed files with 4753 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
export function formatNumber(n: number): string {
if (n < 0) return `-${formatNumber(-n)}`;
if (n < 1_000) return Math.floor(n).toString();
if (n < 1_000_000) return `${(n / 1_000).toFixed(1)}K`;
if (n < 1_000_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
if (n < 1_000_000_000_000) return `${(n / 1_000_000_000).toFixed(1)}B`;
return `${(n / 1_000_000_000_000).toFixed(1)}T`;
}
export function formatMoney(n: number): string {
if (n < 0) return `-$${formatNumber(-n)}`;
return `$${formatNumber(n)}`;
}
export function formatPercent(n: number, decimals = 1): string {
return `${(n * 100).toFixed(decimals)}%`;
}
export function formatTokens(n: number): string {
return `${formatNumber(n)} tok`;
}
export function formatFlops(n: number): string {
return `${formatNumber(n)} FLOPS`;
}
export function formatDuration(ticks: number): string {
if (ticks < 60) return `${ticks}s`;
if (ticks < 3600) return `${Math.floor(ticks / 60)}m ${ticks % 60}s`;
const hours = Math.floor(ticks / 3600);
const minutes = Math.floor((ticks % 3600) / 60);
return `${hours}h ${minutes}m`;
}