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
+80
View File
@@ -0,0 +1,80 @@
import { useGameStore } from '@/store';
export function SettingsPage() {
const settings = useGameStore((s) => s.meta.settings);
const companyName = useGameStore((s) => s.meta.companyName);
const handleReset = () => {
if (confirm('Are you sure you want to reset all progress? This cannot be undone.')) {
localStorage.removeItem('ai-tycoon-save');
window.location.reload();
}
};
const handleExport = () => {
const state = useGameStore.getState();
const { activePage, notifications, ...gameState } = state;
const blob = new Blob([JSON.stringify(gameState)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `ai-tycoon-${companyName.replace(/\s+/g, '-').toLowerCase()}.json`;
a.click();
URL.revokeObjectURL(url);
};
return (
<div className="space-y-6 max-w-2xl">
<h2 className="text-2xl font-bold">Settings</h2>
<div className="bg-surface-900 border border-surface-700 rounded-xl p-4 space-y-4">
<h3 className="font-semibold">Game</h3>
<div className="flex items-center justify-between">
<div>
<div className="text-sm">Sound Effects</div>
<div className="text-xs text-surface-400">Play UI sounds and notifications</div>
</div>
<ToggleSwitch checked={settings.soundEnabled} onChange={() => {}} />
</div>
<div className="flex items-center justify-between">
<div>
<div className="text-sm">Music</div>
<div className="text-xs text-surface-400">Background music (coming soon)</div>
</div>
<ToggleSwitch checked={settings.soundEnabled} onChange={() => {}} />
</div>
</div>
<div className="bg-surface-900 border border-surface-700 rounded-xl p-4 space-y-4">
<h3 className="font-semibold">Save Data</h3>
<div className="flex gap-3">
<button
onClick={handleExport}
className="px-4 py-2 rounded bg-surface-800 hover:bg-surface-700 border border-surface-600 text-sm"
>
Export Save
</button>
<button
onClick={handleReset}
className="px-4 py-2 rounded bg-danger/20 hover:bg-danger/30 border border-danger/50 text-danger text-sm"
>
Reset Progress
</button>
</div>
</div>
</div>
);
}
function ToggleSwitch({ checked, onChange }: { checked: boolean; onChange: () => void }) {
return (
<button
onClick={onChange}
className={`w-10 h-6 rounded-full transition-colors ${checked ? 'bg-accent' : 'bg-surface-600'}`}
>
<div className={`w-4 h-4 bg-white rounded-full transition-transform mx-1 mt-1 ${checked ? 'translate-x-4' : ''}`} />
</button>
);
}