Compare commits

..

2 Commits

Author SHA1 Message Date
josh 035d4f0385 Merge pull request 'Rename AI Tycoon to Token Empire across entire codebase' (#10) from feature/auth-invites into main
Balance Check / balance-simulation (push) Successful in 41s
Balance Check / multi-run-balance (push) Successful in 14m22s
CI / build-and-push (push) Successful in 1m23s
Reviewed-on: #10
2026-04-27 21:08:36 -04:00
josh c1cc70eeb9 Rename AI Tycoon to Token Empire across entire codebase
Balance Check / balance-simulation (pull_request) Successful in 38s
Balance Check / multi-run-balance (pull_request) Successful in 13m44s
Full rebrand: UI display text, package scope (@ai-tycoon/* -> @token-empire/*),
localStorage keys, Docker/CI image paths, database names, and documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 21:04:07 -04:00
123 changed files with 248 additions and 248 deletions
+3 -3
View File
@@ -35,7 +35,7 @@ jobs:
run: pnpm test run: pnpm test
- name: Run greedy simulation - name: Run greedy simulation
run: pnpm --filter @ai-tycoon/game-simulation simulate:ci run: pnpm --filter @token-empire/game-simulation simulate:ci
multi-run-balance: multi-run-balance:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -54,8 +54,8 @@ jobs:
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile
- name: Run multi-simulation (100 runs) - name: Run multi-simulation (100 runs)
run: pnpm --filter @ai-tycoon/game-simulation multirun -- --runs 100 --parallel 10 --strategy persona --ticks 28800 --no-timeseries run: pnpm --filter @token-empire/game-simulation multirun -- --runs 100 --parallel 10 --strategy persona --ticks 28800 --no-timeseries
- name: Interpret results - name: Interpret results
if: always() if: always()
run: pnpm --filter @ai-tycoon/game-simulation interpret -- --summary multirun-summary.csv run: pnpm --filter @token-empire/game-simulation interpret -- --summary multirun-summary.csv
+1 -1
View File
@@ -6,7 +6,7 @@ on:
env: env:
REGISTRY: gitea.thewrightserver.net REGISTRY: gitea.thewrightserver.net
IMAGE_PREFIX: gitea.thewrightserver.net/josh/aihostingtycoon IMAGE_PREFIX: gitea.thewrightserver.net/josh/tokenempire
jobs: jobs:
build-and-push: build-and-push:
+3 -3
View File
@@ -1,4 +1,4 @@
# AI Tycoon # Token Empire
A browser-based incremental/idle game where you manage an AI company from a garage startup to building AGI. Navigate the real tensions of the AI industry: scaling compute, training frontier models, balancing safety vs capability, hiring talent, and competing with rival labs. A browser-based incremental/idle game where you manage an AI company from a garage startup to building AGI. Navigate the real tensions of the AI industry: scaling compute, training frontier models, balancing safety vs capability, hiring talent, and competing with rival labs.
@@ -29,7 +29,7 @@ The web app starts at `http://localhost:5173` (or the next available port). The
## Project Structure ## Project Structure
``` ```
ai-tycoon/ token-empire/
├── apps/ ├── apps/
│ ├── web/ # React frontend (Vite) │ ├── web/ # React frontend (Vite)
│ └── server/ # Hono API backend │ └── server/ # Hono API backend
@@ -81,7 +81,7 @@ pnpm clean # Clean build artifacts
The backend requires PostgreSQL for cloud saves and leaderboards. Set the connection string in `apps/server/.env`: The backend requires PostgreSQL for cloud saves and leaderboards. Set the connection string in `apps/server/.env`:
``` ```
DATABASE_URL=postgresql://user:password@localhost:5432/ai_tycoon DATABASE_URL=postgresql://user:password@localhost:5432/token_empire
``` ```
Run migrations: Run migrations:
+2 -2
View File
@@ -14,8 +14,8 @@ COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/packages/shared/node_modules ./packages/shared/node_modules COPY --from=deps /app/packages/shared/node_modules ./packages/shared/node_modules
COPY --from=deps /app/apps/server/node_modules ./apps/server/node_modules COPY --from=deps /app/apps/server/node_modules ./apps/server/node_modules
COPY . . COPY . .
RUN pnpm --filter @ai-tycoon/shared build && \ RUN pnpm --filter @token-empire/shared build && \
pnpm --filter @ai-tycoon/server typecheck pnpm --filter @token-empire/server typecheck
FROM base AS production FROM base AS production
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./ COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
+1 -1
View File
@@ -5,6 +5,6 @@ export default defineConfig({
schema: './src/db/schema.ts', schema: './src/db/schema.ts',
out: './drizzle', out: './drizzle',
dbCredentials: { dbCredentials: {
url: process.env.DATABASE_URL ?? 'postgresql://localhost:5432/ai_tycoon', url: process.env.DATABASE_URL ?? 'postgresql://localhost:5432/token_empire',
}, },
}); });
+3 -3
View File
@@ -1,5 +1,5 @@
{ {
"name": "@ai-tycoon/server", "name": "@token-empire/server",
"version": "0.0.1", "version": "0.0.1",
"private": true, "private": true,
"type": "module", "type": "module",
@@ -13,7 +13,7 @@
"db:push": "drizzle-kit push" "db:push": "drizzle-kit push"
}, },
"dependencies": { "dependencies": {
"@ai-tycoon/shared": "workspace:*", "@token-empire/shared": "workspace:*",
"@hono/node-server": "^1.13.8", "@hono/node-server": "^1.13.8",
"bcryptjs": "^3.0.3", "bcryptjs": "^3.0.3",
"drizzle-orm": "^0.44.2", "drizzle-orm": "^0.44.2",
@@ -23,7 +23,7 @@
"uuid": "^11.1.0" "uuid": "^11.1.0"
}, },
"devDependencies": { "devDependencies": {
"@ai-tycoon/tsconfig": "workspace:*", "@token-empire/tsconfig": "workspace:*",
"@types/node": "^25.6.0", "@types/node": "^25.6.0",
"drizzle-kit": "^0.31.1", "drizzle-kit": "^0.31.1",
"typescript": "^5.8.3" "typescript": "^5.8.3"
+1 -1
View File
@@ -5,7 +5,7 @@ import { migrate } from 'drizzle-orm/postgres-js/migrator';
import postgres from 'postgres'; import postgres from 'postgres';
import * as schema from './schema'; import * as schema from './schema';
const connectionString = process.env.DATABASE_URL ?? 'postgresql://localhost:5432/ai_tycoon'; const connectionString = process.env.DATABASE_URL ?? 'postgresql://localhost:5432/token_empire';
const client = postgres(connectionString); const client = postgres(connectionString);
export const db = drizzle(client, { schema }); export const db = drizzle(client, { schema });
+1 -1
View File
@@ -40,7 +40,7 @@ app.route('/api/invites', invitesRouter);
const port = Number(process.env.PORT) || 3001; const port = Number(process.env.PORT) || 3001;
console.log(`AI Tycoon API server starting on port ${port}...`); console.log(`Token Empire API server starting on port ${port}...`);
await runMigrations(); await runMigrations();
await seedAdmin(); await seedAdmin();
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"extends": "@ai-tycoon/tsconfig/node.json", "extends": "@token-empire/tsconfig/node.json",
"compilerOptions": { "compilerOptions": {
"outDir": "dist", "outDir": "dist",
"rootDir": "src" "rootDir": "src"
+3 -3
View File
@@ -18,9 +18,9 @@ COPY --from=deps /app/apps/web/node_modules ./apps/web/node_modules
COPY . . COPY . .
ARG VITE_API_URL= ARG VITE_API_URL=
ENV VITE_API_URL=$VITE_API_URL ENV VITE_API_URL=$VITE_API_URL
RUN pnpm --filter @ai-tycoon/shared build && \ RUN pnpm --filter @token-empire/shared build && \
pnpm --filter @ai-tycoon/game-engine build && \ pnpm --filter @token-empire/game-engine build && \
pnpm --filter @ai-tycoon/web build pnpm --filter @token-empire/web build
FROM nginx:alpine FROM nginx:alpine
COPY --from=build /app/apps/web/dist /usr/share/nginx/html COPY --from=build /app/apps/web/dist /usr/share/nginx/html
+1 -1
View File
@@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AI Tycoon</title> <title>Token Empire</title>
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
+4 -4
View File
@@ -1,5 +1,5 @@
{ {
"name": "@ai-tycoon/web", "name": "@token-empire/web",
"private": true, "private": true,
"version": "0.0.1", "version": "0.0.1",
"type": "module", "type": "module",
@@ -10,8 +10,8 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@ai-tycoon/shared": "workspace:*", "@token-empire/shared": "workspace:*",
"@ai-tycoon/game-engine": "workspace:*", "@token-empire/game-engine": "workspace:*",
"react": "^19.1.0", "react": "^19.1.0",
"react-dom": "^19.1.0", "react-dom": "^19.1.0",
"recharts": "^2.15.0", "recharts": "^2.15.0",
@@ -19,7 +19,7 @@
"lucide-react": "^0.475.0" "lucide-react": "^0.475.0"
}, },
"devDependencies": { "devDependencies": {
"@ai-tycoon/tsconfig": "workspace:*", "@token-empire/tsconfig": "workspace:*",
"@types/react": "^19.1.0", "@types/react": "^19.1.0",
"@types/react-dom": "^19.1.0", "@types/react-dom": "^19.1.0",
"@vitejs/plugin-react": "^4.4.0", "@vitejs/plugin-react": "^4.4.0",
+3 -3
View File
@@ -6,7 +6,7 @@ import { OfflineCatchUp } from '@/components/game/OfflineCatchUp';
import { InviteGateScreen } from '@/components/game/InviteGateScreen'; import { InviteGateScreen } from '@/components/game/InviteGateScreen';
import { useGameLoop } from '@/hooks/useGameLoop'; import { useGameLoop } from '@/hooks/useGameLoop';
import { useAuthGate } from '@/hooks/useAuthGate'; import { useAuthGate } from '@/hooks/useAuthGate';
import { TICK_INTERVAL_MS } from '@ai-tycoon/shared'; import { TICK_INTERVAL_MS } from '@token-empire/shared';
import { Sparkles, RefreshCw, WifiOff } from 'lucide-react'; import { Sparkles, RefreshCw, WifiOff } from 'lucide-react';
function LoadingScreen() { function LoadingScreen() {
@@ -16,7 +16,7 @@ function LoadingScreen() {
<div className="inline-flex items-center gap-2 mb-4"> <div className="inline-flex items-center gap-2 mb-4">
<Sparkles className="text-accent-light animate-pulse" size={32} /> <Sparkles className="text-accent-light animate-pulse" size={32} />
<h1 className="text-4xl font-bold bg-gradient-to-r from-accent-light to-accent bg-clip-text text-transparent"> <h1 className="text-4xl font-bold bg-gradient-to-r from-accent-light to-accent bg-clip-text text-transparent">
AI Tycoon Token Empire
</h1> </h1>
</div> </div>
<p className="text-surface-500 text-sm">Loading...</p> <p className="text-surface-500 text-sm">Loading...</p>
@@ -32,7 +32,7 @@ function BackendErrorScreen({ error, onRetry }: { error: string; onRetry: () =>
<div className="inline-flex items-center gap-2 mb-6"> <div className="inline-flex items-center gap-2 mb-6">
<Sparkles className="text-accent-light" size={32} /> <Sparkles className="text-accent-light" size={32} />
<h1 className="text-4xl font-bold bg-gradient-to-r from-accent-light to-accent bg-clip-text text-transparent"> <h1 className="text-4xl font-bold bg-gradient-to-r from-accent-light to-accent bg-clip-text text-transparent">
AI Tycoon Token Empire
</h1> </h1>
</div> </div>
@@ -1,7 +1,7 @@
import { useEffect, useRef } from 'react'; import { useEffect, useRef } from 'react';
import { X, CheckCircle, AlertTriangle, AlertCircle, Info, Bell, Trash2 } from 'lucide-react'; import { X, CheckCircle, AlertTriangle, AlertCircle, Info, Bell, Trash2 } from 'lucide-react';
import { useGameStore, type GameNotification } from '@/store'; import { useGameStore, type GameNotification } from '@/store';
import { formatDuration } from '@ai-tycoon/shared'; import { formatDuration } from '@token-empire/shared';
const ICON_MAP = { const ICON_MAP = {
success: { icon: CheckCircle, color: 'text-success' }, success: { icon: CheckCircle, color: 'text-success' },
+1 -1
View File
@@ -18,7 +18,7 @@ export function DevMenu() {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [activeTab, setActiveTab] = useState<Tab>('resources'); const [activeTab, setActiveTab] = useState<Tab>('resources');
const isEnabled = import.meta.env.DEV || localStorage.getItem('ai-tycoon-dev-menu') === 'true'; const isEnabled = import.meta.env.DEV || localStorage.getItem('token-empire-dev-menu') === 'true';
useEffect(() => { useEffect(() => {
if (!isEnabled) return; if (!isEnabled) return;
@@ -1,6 +1,6 @@
import { useState } from 'react'; import { useState } from 'react';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import type { FundingRoundType } from '@ai-tycoon/shared'; import type { FundingRoundType } from '@token-empire/shared';
function DevButton({ onClick, children, variant = 'default' }: { function DevButton({ onClick, children, variant = 'default' }: {
onClick: () => void; onClick: () => void;
+1 -1
View File
@@ -1,6 +1,6 @@
import { useState } from 'react'; import { useState } from 'react';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatMoney } from '@ai-tycoon/shared'; import { formatMoney } from '@token-empire/shared';
function DevButton({ onClick, children, variant = 'default' }: { function DevButton({ onClick, children, variant = 'default' }: {
onClick: () => void; onClick: () => void;
@@ -1,5 +1,5 @@
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatMoney, formatNumber, formatFlops, formatPercent } from '@ai-tycoon/shared'; import { formatMoney, formatNumber, formatFlops, formatPercent } from '@token-empire/shared';
function Section({ title, children }: { title: string; children: React.ReactNode }) { function Section({ title, children }: { title: string; children: React.ReactNode }) {
return ( return (
@@ -1,7 +1,7 @@
import { useState } from 'react'; import { useState } from 'react';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { processTick, setAchievementDefinitions, ACHIEVEMENT_DEFINITIONS, TECH_TREE } from '@ai-tycoon/game-engine'; import { processTick, setAchievementDefinitions, ACHIEVEMENT_DEFINITIONS, TECH_TREE } from '@token-empire/game-engine';
import type { GameState, Era } from '@ai-tycoon/shared'; import type { GameState, Era } from '@token-empire/shared';
function DevButton({ onClick, children, variant = 'default' }: { function DevButton({ onClick, children, variant = 'default' }: {
onClick: () => void; onClick: () => void;
@@ -1,8 +1,8 @@
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatMoney, formatNumber, formatPercent } from '@ai-tycoon/shared'; import { formatMoney, formatNumber, formatPercent } from '@token-empire/shared';
import { Share2, Copy, Check } from 'lucide-react'; import { Share2, Copy, Check } from 'lucide-react';
import { useState } from 'react'; import { useState } from 'react';
import { ACHIEVEMENT_DEFINITIONS } from '@ai-tycoon/game-engine'; import { ACHIEVEMENT_DEFINITIONS } from '@token-empire/game-engine';
export function CompanyStatsCard({ onClose }: { onClose: () => void }) { export function CompanyStatsCard({ onClose }: { onClose: () => void }) {
const [copied, setCopied] = useState(false); const [copied, setCopied] = useState(false);
@@ -25,7 +25,7 @@ export function CompanyStatsCard({ onClose }: { onClose: () => void }) {
const minutes = Math.floor((totalPlayTime % 3600) / 60); const minutes = Math.floor((totalPlayTime % 3600) / 60);
const statsText = [ const statsText = [
`${companyName}AI Tycoon`, `${companyName}Token Empire`,
`Era: ${eraLabel} | Playtime: ${hours}h ${minutes}m`, `Era: ${eraLabel} | Playtime: ${hours}h ${minutes}m`,
`Cash: ${formatMoney(money)} | Revenue: ${formatMoney(totalRevenue)}`, `Cash: ${formatMoney(money)} | Revenue: ${formatMoney(totalRevenue)}`,
`Valuation: ${formatMoney(valuation)}`, `Valuation: ${formatMoney(valuation)}`,
@@ -111,7 +111,7 @@ export function InviteGateScreen({ onRegistered }: { onRegistered: () => void })
<div className="inline-flex items-center gap-2 mb-4"> <div className="inline-flex items-center gap-2 mb-4">
<Sparkles className="text-accent-light" size={32} /> <Sparkles className="text-accent-light" size={32} />
<h1 className="text-4xl font-bold bg-gradient-to-r from-accent-light to-accent bg-clip-text text-transparent"> <h1 className="text-4xl font-bold bg-gradient-to-r from-accent-light to-accent bg-clip-text text-transparent">
AI Tycoon Token Empire
</h1> </h1>
</div> </div>
<p className="text-surface-400 text-sm"> <p className="text-surface-400 text-sm">
@@ -24,7 +24,7 @@ export function NewGameScreen() {
<div className="inline-flex items-center gap-2 mb-4"> <div className="inline-flex items-center gap-2 mb-4">
<Sparkles className="text-accent-light" size={32} /> <Sparkles className="text-accent-light" size={32} />
<h1 className="text-4xl font-bold bg-gradient-to-r from-accent-light to-accent bg-clip-text text-transparent"> <h1 className="text-4xl font-bold bg-gradient-to-r from-accent-light to-accent bg-clip-text text-transparent">
AI Tycoon Token Empire
</h1> </h1>
</div> </div>
<p className="text-surface-400 text-sm"> <p className="text-surface-400 text-sm">
@@ -1,6 +1,6 @@
import { useState, useEffect, useRef } from 'react'; import { useState, useEffect, useRef } from 'react';
import { formatMoney, formatDuration, formatNumber, MAX_OFFLINE_TICKS, TICK_INTERVAL_MS } from '@ai-tycoon/shared'; import { formatMoney, formatDuration, formatNumber, MAX_OFFLINE_TICKS, TICK_INTERVAL_MS } from '@token-empire/shared';
import { GameEngine } from '@ai-tycoon/game-engine'; import { GameEngine } from '@token-empire/game-engine';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
interface OfflineResult { interface OfflineResult {
@@ -1,7 +1,7 @@
import { useState } from 'react'; import { useState } from 'react';
import { X, Lightbulb } from 'lucide-react'; import { X, Lightbulb } from 'lucide-react';
const DISMISSED_KEY = 'ai-tycoon-dismissed-hints'; const DISMISSED_KEY = 'token-empire-dismissed-hints';
function getDismissed(): Set<string> { function getDismissed(): Set<string> {
try { try {
+3 -3
View File
@@ -26,7 +26,7 @@ const NAV_ITEMS: { page: ActivePage; label: string; icon: typeof LayoutDashboard
function getInitialCollapsed(): boolean { function getInitialCollapsed(): boolean {
try { try {
const stored = localStorage.getItem('ai-tycoon-sidebar-collapsed'); const stored = localStorage.getItem('token-empire-sidebar-collapsed');
if (stored !== null) return stored === 'true'; if (stored !== null) return stored === 'true';
return window.innerWidth < 1280; return window.innerWidth < 1280;
} catch { return false; } } catch { return false; }
@@ -82,7 +82,7 @@ export function Sidebar() {
const toggleCollapse = () => { const toggleCollapse = () => {
setCollapsed(prev => { setCollapsed(prev => {
const next = !prev; const next = !prev;
localStorage.setItem('ai-tycoon-sidebar-collapsed', String(next)); localStorage.setItem('token-empire-sidebar-collapsed', String(next));
return next; return next;
}); });
}; };
@@ -166,7 +166,7 @@ export function Sidebar() {
)} )}
<div className={`${collapsed ? 'px-2 py-3 text-center' : 'p-4'} border-t border-surface-700 text-xs text-surface-500`}> <div className={`${collapsed ? 'px-2 py-3 text-center' : 'p-4'} border-t border-surface-700 text-xs text-surface-500`}>
{collapsed ? 'v0.1' : 'AI Tycoon v0.1'} {collapsed ? 'v0.1' : 'Token Empire v0.1'}
</div> </div>
</aside> </aside>
); );
+2 -2
View File
@@ -3,8 +3,8 @@ import { Pause, Play, Bell, Share2 } from 'lucide-react';
import { CompanyStatsCard } from '@/components/game/CompanyStatsCard'; import { CompanyStatsCard } from '@/components/game/CompanyStatsCard';
import { NotificationPanel } from '@/components/common/NotificationPanel'; import { NotificationPanel } from '@/components/common/NotificationPanel';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatMoney, formatNumber, formatDuration, formatPercent } from '@ai-tycoon/shared'; import { formatMoney, formatNumber, formatDuration, formatPercent } from '@token-empire/shared';
import type { GameSpeed } from '@ai-tycoon/shared'; import type { GameSpeed } from '@token-empire/shared';
import { Tooltip } from '@/components/common/Tooltip'; import { Tooltip } from '@/components/common/Tooltip';
const SPEEDS: GameSpeed[] = [1, 2, 5]; const SPEEDS: GameSpeed[] = [1, 2, 5];
+1 -1
View File
@@ -1,7 +1,7 @@
import { useEffect, useRef } from 'react'; import { useEffect, useRef } from 'react';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { api, getAuthToken, setAuthToken, clearAuthToken, decodeTokenPayload } from '@/lib/api'; import { api, getAuthToken, setAuthToken, clearAuthToken, decodeTokenPayload } from '@/lib/api';
import { AUTO_SAVE_INTERVAL_TICKS } from '@ai-tycoon/shared'; import { AUTO_SAVE_INTERVAL_TICKS } from '@token-empire/shared';
export function useCloudSave() { export function useCloudSave() {
const tickCount = useGameStore((s) => s.meta.tickCount); const tickCount = useGameStore((s) => s.meta.tickCount);
+2 -2
View File
@@ -1,6 +1,6 @@
import { useEffect, useRef } from 'react'; import { useEffect, useRef } from 'react';
import { GameEngine, setAchievementDefinitions, ACHIEVEMENT_DEFINITIONS } from '@ai-tycoon/game-engine'; import { GameEngine, setAchievementDefinitions, ACHIEVEMENT_DEFINITIONS } from '@token-empire/game-engine';
import type { TickNotification } from '@ai-tycoon/game-engine'; import type { TickNotification } from '@token-empire/game-engine';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
export function useGameLoop(skip = false) { export function useGameLoop(skip = false) {
+1 -1
View File
@@ -1,6 +1,6 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useGameStore, type ActivePage } from '@/store'; import { useGameStore, type ActivePage } from '@/store';
import type { GameSpeed } from '@ai-tycoon/shared'; import type { GameSpeed } from '@token-empire/shared';
const PAGE_SHORTCUTS: Record<string, ActivePage> = { const PAGE_SHORTCUTS: Record<string, ActivePage> = {
d: 'dashboard', d: 'dashboard',
+3 -3
View File
@@ -1,10 +1,10 @@
const API_BASE = import.meta.env.VITE_API_URL ?? 'http://localhost:3001'; const API_BASE = import.meta.env.VITE_API_URL ?? 'http://localhost:3001';
let authToken: string | null = localStorage.getItem('ai-tycoon-auth-token'); let authToken: string | null = localStorage.getItem('token-empire-auth-token');
export function setAuthToken(token: string) { export function setAuthToken(token: string) {
authToken = token; authToken = token;
localStorage.setItem('ai-tycoon-auth-token', token); localStorage.setItem('token-empire-auth-token', token);
} }
export function getAuthToken() { export function getAuthToken() {
@@ -13,7 +13,7 @@ export function getAuthToken() {
export function clearAuthToken() { export function clearAuthToken() {
authToken = null; authToken = null;
localStorage.removeItem('ai-tycoon-auth-token'); localStorage.removeItem('token-empire-auth-token');
} }
export interface TokenPayload { export interface TokenPayload {
+3 -3
View File
@@ -1,12 +1,12 @@
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { ACHIEVEMENT_DEFINITIONS } from '@ai-tycoon/game-engine'; import { ACHIEVEMENT_DEFINITIONS } from '@token-empire/game-engine';
import { formatNumber } from '@ai-tycoon/shared'; import { formatNumber } from '@token-empire/shared';
import { import {
Trophy, Lock, Server, Brain, Rocket, DollarSign, Sprout, Users, Trophy, Lock, Server, Brain, Rocket, DollarSign, Sprout, Users,
Globe, Sparkles, TrendingUp, Building2, Atom, Cpu, FlaskConical, Globe, Sparkles, TrendingUp, Building2, Atom, Cpu, FlaskConical,
GitBranch, Zap, GitBranch, Zap,
} from 'lucide-react'; } from 'lucide-react';
import type { AchievementCondition } from '@ai-tycoon/shared'; import type { AchievementCondition } from '@token-empire/shared';
const ICON_MAP: Record<string, React.ComponentType<{ size?: number; className?: string }>> = { const ICON_MAP: Record<string, React.ComponentType<{ size?: number; className?: string }>> = {
Trophy, Server, Brain, Rocket, DollarSign, Sprout, Users, Trophy, Server, Brain, Rocket, DollarSign, Sprout, Users,
+2 -2
View File
@@ -3,8 +3,8 @@ import { Swords, TrendingUp, Shield, Users, Brain, ShoppingCart } from 'lucide-r
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { ConfirmModal } from '@/components/common/ConfirmModal'; import { ConfirmModal } from '@/components/common/ConfirmModal';
import { Tooltip } from '@/components/common/Tooltip'; import { Tooltip } from '@/components/common/Tooltip';
import { formatMoney, formatNumber } from '@ai-tycoon/shared'; import { formatMoney, formatNumber } from '@token-empire/shared';
import type { Era } from '@ai-tycoon/shared'; import type { Era } from '@token-empire/shared';
const ARCHETYPE_LABELS: Record<string, string> = { const ARCHETYPE_LABELS: Record<string, string> = {
'safety-first': 'Safety-First Lab', 'safety-first': 'Safety-First Lab',
+4 -4
View File
@@ -1,8 +1,8 @@
import type React from 'react'; import type React from 'react';
import { useGameStore, type ActivePage } from '@/store'; import { useGameStore, type ActivePage } from '@/store';
import { formatMoney, formatNumber, formatPercent, formatDuration } from '@ai-tycoon/shared'; import { formatMoney, formatNumber, formatPercent, formatDuration } from '@token-empire/shared';
import type { Era } from '@ai-tycoon/shared'; import type { Era } from '@token-empire/shared';
import { TECH_TREE } from '@ai-tycoon/game-engine'; import { TECH_TREE } from '@token-empire/game-engine';
import { import {
DollarSign, TrendingUp, TrendingDown, Minus, Cpu, Brain, Users, DollarSign, TrendingUp, TrendingDown, Minus, Cpu, Brain, Users,
Shield, ChevronRight, Zap, Wifi, Sparkles, FlaskConical, Building2, Shield, ChevronRight, Zap, Wifi, Sparkles, FlaskConical, Building2,
@@ -96,7 +96,7 @@ export function DashboardPage() {
{totalDCs === 0 && ( {totalDCs === 0 && (
<TutorialHint id="welcome"> <TutorialHint id="welcome">
Welcome to AI Tycoon! Start by building a cluster in the Infrastructure tab, then add a campus and data center to deploy racks and train your first AI model. Welcome to Token Empire! Start by building a cluster in the Infrastructure tab, then add a campus and data center to deploy racks and train your first AI model.
</TutorialHint> </TutorialHint>
)} )}
+2 -2
View File
@@ -1,8 +1,8 @@
import { useState } from 'react'; import { useState } from 'react';
import { Database, ShoppingCart, Zap } from 'lucide-react'; import { Database, ShoppingCart, Zap } from 'lucide-react';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatNumber, formatMoney, uuid } from '@ai-tycoon/shared'; import { formatNumber, formatMoney, uuid } from '@token-empire/shared';
import type { OwnedDataset, DataDomain } from '@ai-tycoon/shared'; import type { OwnedDataset, DataDomain } from '@token-empire/shared';
interface MarketplaceDataset { interface MarketplaceDataset {
name: string; name: string;
+4 -4
View File
@@ -1,10 +1,10 @@
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatMoney, formatPercent, formatNumber, FUNDING_ROUNDS } from '@ai-tycoon/shared'; import { formatMoney, formatPercent, formatNumber, FUNDING_ROUNDS } from '@token-empire/shared';
import type { FundingRoundType } from '@ai-tycoon/shared'; import type { FundingRoundType } from '@token-empire/shared';
import { TrendingUp, DollarSign, PiggyBank, BarChart3, Rocket, Check, X as XIcon } from 'lucide-react'; import { TrendingUp, DollarSign, PiggyBank, BarChart3, Rocket, Check, X as XIcon } from 'lucide-react';
import { AreaChart, Area, XAxis, YAxis, ResponsiveContainer, LineChart, Line, Tooltip } from 'recharts'; import { AreaChart, Area, XAxis, YAxis, ResponsiveContainer, LineChart, Line, Tooltip } from 'recharts';
import { canRaiseFunding } from '@ai-tycoon/game-engine'; import { canRaiseFunding } from '@token-empire/game-engine';
import type { GameState } from '@ai-tycoon/shared'; import type { GameState } from '@token-empire/shared';
export function FinancePage() { export function FinancePage() {
const money = useGameStore((s) => s.economy.money); const money = useGameStore((s) => s.economy.money);
+2 -2
View File
@@ -18,11 +18,11 @@ import {
SWITCH_TIER_CONFIGS, SWITCH_TIER_CONFIGS,
DC_UPGRADE_COST_FRACTION, DC_UPGRADE_INCREMENT, DC_UPGRADE_COST_FRACTION, DC_UPGRADE_INCREMENT,
skuTotalFlops, skuTotalFlops,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import type { import type {
DCTier, RackSkuId, LocationId, PipelineStage, Era, DCTier, RackSkuId, LocationId, PipelineStage, Era,
Cluster, Campus, DataCenter, DeploymentCohort, Cluster, Campus, DataCenter, DeploymentCohort,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
const ERA_ORDER: Era[] = ['startup', 'scaleup', 'bigtech', 'agi']; const ERA_ORDER: Era[] = ['startup', 'scaleup', 'bigtech', 'agi'];
+1 -1
View File
@@ -1,7 +1,7 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { Trophy, Medal, Clock, TrendingUp } from 'lucide-react'; import { Trophy, Medal, Clock, TrendingUp } from 'lucide-react';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatMoney, formatNumber } from '@ai-tycoon/shared'; import { formatMoney, formatNumber } from '@token-empire/shared';
import { api, getAuthToken } from '@/lib/api'; import { api, getAuthToken } from '@/lib/api';
interface LeaderboardEntry { interface LeaderboardEntry {
+2 -2
View File
@@ -13,12 +13,12 @@ import {
SIZE_TIER_LABELS, SIZE_TIER_LABELS,
SFT_SPECIALIZATION_BONUSES, SFT_SPECIALIZATION_BONUSES,
PRETRAINING_BASE_TICKS, PRETRAINING_BASE_TICKS,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import type { import type {
ModelArchitecture, DataMixAllocation, SFTSpecialization, AlignmentMethod, ModelArchitecture, DataMixAllocation, SFTSpecialization, AlignmentMethod,
DataDomain, QuantizationLevel, BaseModel, ModelVariant, DataDomain, QuantizationLevel, BaseModel, ModelVariant,
SizeTier, ModelFamily, SizeTier, ModelFamily,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
const DATA_MIX_PRESETS: Record<string, { label: string; mix: DataMixAllocation }> = { const DATA_MIX_PRESETS: Record<string, { label: string; mix: DataMixAllocation }> = {
balanced: { label: 'Balanced', mix: DEFAULT_DATA_MIX }, balanced: { label: 'Balanced', mix: DEFAULT_DATA_MIX },
+3 -3
View File
@@ -1,9 +1,9 @@
import { FlaskConical, Lock, Check, Play, ListOrdered, X } from 'lucide-react'; import { FlaskConical, Lock, Check, Play, ListOrdered, X } from 'lucide-react';
import { TutorialHint } from '@/components/game/TutorialHint'; import { TutorialHint } from '@/components/game/TutorialHint';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatDuration, formatPercent, formatNumber, formatMoney } from '@ai-tycoon/shared'; import { formatDuration, formatPercent, formatNumber, formatMoney } from '@token-empire/shared';
import { TECH_TREE, getAvailableResearch } from '@ai-tycoon/game-engine'; import { TECH_TREE, getAvailableResearch } from '@token-empire/game-engine';
import type { ResearchNode } from '@ai-tycoon/shared'; import type { ResearchNode } from '@token-empire/shared';
const CATEGORY_COLORS: Record<string, string> = { const CATEGORY_COLORS: Record<string, string> = {
generation: 'border-purple-500/50 bg-purple-500/10', generation: 'border-purple-500/50 bg-purple-500/10',
+1 -1
View File
@@ -3,7 +3,7 @@ import {
formatNumber, formatPercent, formatNumber, formatPercent,
type TrafficPriority, type OverflowBehavior, type RoutingStrategy, type TrafficPriority, type OverflowBehavior, type RoutingStrategy,
TRAFFIC_PRIORITIES, TRAFFIC_PRIORITIES,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import { import {
Activity, Shield, Clock, CheckCircle, XCircle, Layers, Activity, Shield, Clock, CheckCircle, XCircle, Layers,
AlertTriangle, Zap, Server, ArrowRight, AlertTriangle, Zap, Server, ArrowRight,
+4 -4
View File
@@ -21,7 +21,7 @@ export function SettingsPage() {
}; };
const handleReset = () => { const handleReset = () => {
localStorage.removeItem('ai-tycoon-save'); localStorage.removeItem('token-empire-save');
window.location.reload(); window.location.reload();
}; };
@@ -32,7 +32,7 @@ export function SettingsPage() {
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
const a = document.createElement('a'); const a = document.createElement('a');
a.href = url; a.href = url;
a.download = `ai-tycoon-${companyName.replace(/\s+/g, '-').toLowerCase()}.json`; a.download = `token-empire-${companyName.replace(/\s+/g, '-').toLowerCase()}.json`;
a.click(); a.click();
URL.revokeObjectURL(url); URL.revokeObjectURL(url);
}; };
@@ -51,7 +51,7 @@ export function SettingsPage() {
} }
setImportData({ data, name: data.meta.companyName }); setImportData({ data, name: data.meta.companyName });
} catch { } catch {
addNotification({ title: 'Import Failed', message: 'Could not read save file. Make sure it is a valid AI Tycoon export.', type: 'danger', tick: useGameStore.getState().meta.tickCount }); addNotification({ title: 'Import Failed', message: 'Could not read save file. Make sure it is a valid Token Empire export.', type: 'danger', tick: useGameStore.getState().meta.tickCount });
} }
}; };
reader.readAsText(file); reader.readAsText(file);
@@ -60,7 +60,7 @@ export function SettingsPage() {
const confirmImport = () => { const confirmImport = () => {
if (!importData) return; if (!importData) return;
localStorage.setItem('ai-tycoon-save', JSON.stringify({ state: importData.data })); localStorage.setItem('token-empire-save', JSON.stringify({ state: importData.data }));
window.location.reload(); window.location.reload();
}; };
+3 -3
View File
@@ -1,9 +1,9 @@
import { useState } from 'react'; import { useState } from 'react';
import { Users, Plus, Star, Briefcase } from 'lucide-react'; import { Users, Plus, Star, Briefcase } from 'lucide-react';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatMoney } from '@ai-tycoon/shared'; import { formatMoney } from '@token-empire/shared';
import { KEY_HIRE_POOL } from '@ai-tycoon/game-engine'; import { KEY_HIRE_POOL } from '@token-empire/game-engine';
import type { DepartmentId } from '@ai-tycoon/shared'; import type { DepartmentId } from '@token-empire/shared';
const DEPT_LABELS: Record<string, string> = { const DEPT_LABELS: Record<string, string> = {
research: 'Research', research: 'Research',
+2 -2
View File
@@ -1,7 +1,7 @@
import { useState, useEffect, useRef, useCallback } from 'react'; import { useState, useEffect, useRef, useCallback } from 'react';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatNumber, formatMoney, formatPercent } from '@ai-tycoon/shared'; import { formatNumber, formatMoney, formatPercent } from '@token-empire/shared';
import type { ApiTierId } from '@ai-tycoon/shared'; import type { ApiTierId } from '@token-empire/shared';
import { Code, Check } from 'lucide-react'; import { Code, Check } from 'lucide-react';
const TIER_ORDER: ApiTierId[] = ['free', 'payg', 'scale', 'enterprise-api']; const TIER_ORDER: ApiTierId[] = ['free', 'payg', 'scale', 'enterprise-api'];
@@ -1,7 +1,7 @@
import { useState, useEffect, useRef, useCallback } from 'react'; import { useState, useEffect, useRef, useCallback } from 'react';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatNumber, formatMoney, formatPercent } from '@ai-tycoon/shared'; import { formatNumber, formatMoney, formatPercent } from '@token-empire/shared';
import type { ConsumerTierId } from '@ai-tycoon/shared'; import type { ConsumerTierId } from '@token-empire/shared';
import { Users, Check } from 'lucide-react'; import { Users, Check } from 'lucide-react';
const TIER_ORDER: ConsumerTierId[] = ['free', 'plus', 'pro', 'team']; const TIER_ORDER: ConsumerTierId[] = ['free', 'plus', 'pro', 'team'];
@@ -1,6 +1,6 @@
import { useState, useEffect, useRef, useCallback } from 'react'; import { useState, useEffect, useRef, useCallback } from 'react';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatNumber, formatMoney, formatPercent } from '@ai-tycoon/shared'; import { formatNumber, formatMoney, formatPercent } from '@token-empire/shared';
import { Boxes, Check } from 'lucide-react'; import { Boxes, Check } from 'lucide-react';
function useAppliedFeedback() { function useAppliedFeedback() {
@@ -1,6 +1,6 @@
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatNumber, formatMoney, formatPercent } from '@ai-tycoon/shared'; import { formatNumber, formatMoney, formatPercent } from '@token-empire/shared';
import type { EnterprisePipelineStage, EnterpriseSegment } from '@ai-tycoon/shared'; import type { EnterprisePipelineStage, EnterpriseSegment } from '@token-empire/shared';
import { Building2, AlertTriangle } from 'lucide-react'; import { Building2, AlertTriangle } from 'lucide-react';
const STAGE_ORDER: EnterprisePipelineStage[] = ['lead', 'qualification', 'poc', 'negotiation']; const STAGE_ORDER: EnterprisePipelineStage[] = ['lead', 'qualification', 'poc', 'negotiation'];
@@ -1,6 +1,6 @@
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatNumber, formatPercent } from '@ai-tycoon/shared'; import { formatNumber, formatPercent } from '@token-empire/shared';
import type { TAMSegmentId } from '@ai-tycoon/shared'; import type { TAMSegmentId } from '@token-empire/shared';
import { Globe, TrendingUp, Clock, Thermometer } from 'lucide-react'; import { Globe, TrendingUp, Clock, Thermometer } from 'lucide-react';
const SEGMENT_LABELS: Record<TAMSegmentId, string> = { const SEGMENT_LABELS: Record<TAMSegmentId, string> = {
@@ -1,6 +1,6 @@
import { useState, useEffect, useRef, useCallback } from 'react'; import { useState, useEffect, useRef, useCallback } from 'react';
import { useGameStore } from '@/store'; import { useGameStore } from '@/store';
import { formatNumber, formatMoney, formatPercent } from '@ai-tycoon/shared'; import { formatNumber, formatMoney, formatPercent } from '@token-empire/shared';
import { Wrench, Bot, Check, Lock } from 'lucide-react'; import { Wrench, Bot, Check, Lock } from 'lucide-react';
function useAppliedFeedback() { function useAppliedFeedback() {
+5 -5
View File
@@ -16,7 +16,7 @@ import type {
ModelArchitecture, AlignmentMethod, SizeTier, ModelArchitecture, AlignmentMethod, SizeTier,
SFTSpecialization, QuantizationLevel, VariantCreationJob, SFTSpecialization, QuantizationLevel, VariantCreationJob,
ConsumerTierId, ApiTierId, ConsumerTierId, ApiTierId,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import { import {
INITIAL_SETTINGS, SAVE_VERSION, INITIAL_SETTINGS, SAVE_VERSION,
INITIAL_ECONOMY, INITIAL_INFRASTRUCTURE, INITIAL_COMPUTE, INITIAL_ECONOMY, INITIAL_INFRASTRUCTURE, INITIAL_COMPUTE,
@@ -39,12 +39,12 @@ import {
SFT_TIME_FRACTION, ALIGNMENT_TIME_FRACTION, SFT_TIME_FRACTION, ALIGNMENT_TIME_FRACTION,
SIZE_TIER_MAP, SIZE_TIER_LABELS, SIZE_TIER_MAP, SIZE_TIER_LABELS,
POINT_RELEASE_TIME_FRACTION, POINT_RELEASE_MAX_VERSION, POINT_RELEASE_TIME_FRACTION, POINT_RELEASE_MAX_VERSION,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import { import {
emptyDCNetworkSummary, emptyCampusNetworkSummary, emptyClusterNetworkSummary, emptyDCNetworkSummary, emptyCampusNetworkSummary, emptyClusterNetworkSummary,
TECH_TREE, onModelDeployed, TECH_TREE, onModelDeployed,
} from '@ai-tycoon/game-engine'; } from '@token-empire/game-engine';
import { INITIAL_RIVALS } from '@ai-tycoon/game-engine'; import { INITIAL_RIVALS } from '@token-empire/game-engine';
export type ActivePage = 'dashboard' | 'infrastructure' | 'research' | 'models' export type ActivePage = 'dashboard' | 'infrastructure' | 'research' | 'models'
| 'market' | 'serving' | 'talent' | 'data' | 'competitors' | 'finance' | 'achievements' | 'leaderboard' | 'invitations' | 'settings'; | 'market' | 'serving' | 'talent' | 'data' | 'competitors' | 'finance' | 'achievements' | 'leaderboard' | 'invitations' | 'settings';
@@ -1428,7 +1428,7 @@ export const useGameStore = create<Store>()(
}), }),
}), }),
{ {
name: 'ai-tycoon-save', name: 'token-empire-save',
version: SAVE_VERSION, version: SAVE_VERSION,
partialize: (state) => { partialize: (state) => {
const { activePage, notifications, infraNav, modelsTab, ...rest } = state; const { activePage, notifications, infraNav, modelsTab, ...rest } = state;
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"extends": "@ai-tycoon/tsconfig/react.json", "extends": "@token-empire/tsconfig/react.json",
"compilerOptions": { "compilerOptions": {
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
+7 -7
View File
@@ -1,6 +1,6 @@
services: services:
web: web:
image: gitea.thewrightserver.net/josh/aihostingtycoon/web:latest image: gitea.thewrightserver.net/josh/tokenempire/web:latest
ports: ports:
- "80:80" - "80:80"
depends_on: depends_on:
@@ -8,11 +8,11 @@ services:
restart: unless-stopped restart: unless-stopped
server: server:
image: gitea.thewrightserver.net/josh/aihostingtycoon/server:latest image: gitea.thewrightserver.net/josh/tokenempire/server:latest
ports: ports:
- "3001:3001" - "3001:3001"
environment: environment:
- DATABASE_URL=postgresql://aitycoon:aitycoon@db:5432/aitycoon - DATABASE_URL=postgresql://tokenempire:tokenempire@db:5432/tokenempire
- PORT=3001 - PORT=3001
- CORS_ORIGIN=* - CORS_ORIGIN=*
- JWT_SECRET=change-me-to-a-random-secret - JWT_SECRET=change-me-to-a-random-secret
@@ -26,13 +26,13 @@ services:
db: db:
image: postgres:17-alpine image: postgres:17-alpine
environment: environment:
- POSTGRES_USER=aitycoon - POSTGRES_USER=tokenempire
- POSTGRES_PASSWORD=aitycoon - POSTGRES_PASSWORD=tokenempire
- POSTGRES_DB=aitycoon - POSTGRES_DB=tokenempire
volumes: volumes:
- pgdata:/var/lib/postgresql/data - pgdata:/var/lib/postgresql/data
healthcheck: healthcheck:
test: ["CMD-SHELL", "pg_isready -U aitycoon"] test: ["CMD-SHELL", "pg_isready -U tokenempire"]
interval: 5s interval: 5s
timeout: 5s timeout: 5s
retries: 5 retries: 5
+2 -2
View File
@@ -17,7 +17,7 @@ The game engine and simulation core have no React dependency. They can run ident
## Monorepo Layout ## Monorepo Layout
``` ```
ai-tycoon/ token-empire/
├── turbo.json # Turborepo task config ├── turbo.json # Turborepo task config
├── pnpm-workspace.yaml # Workspace definition ├── pnpm-workspace.yaml # Workspace definition
@@ -122,7 +122,7 @@ The store uses a slice pattern with 14 slices, each owning a portion of the game
### Persistence ### Persistence
- **localStorage**: Auto-save every 60 ticks under key `ai-tycoon-save`. The Zustand `persist` middleware handles serialization. - **localStorage**: Auto-save every 60 ticks under key `token-empire-save`. The Zustand `persist` middleware handles serialization.
- **Cloud saves**: Optional. POST to `/api/saves` every 5 minutes when authenticated. Requires the Hono backend + PostgreSQL. - **Cloud saves**: Optional. POST to `/api/saves` every 5 minutes when authenticated. Requires the Hono backend + PostgreSQL.
- **Save format versioning**: A `version` field in meta enables migration functions for breaking state changes. - **Save format versioning**: A `version` field in meta enables migration functions for breaking state changes.
+3 -3
View File
@@ -1,5 +1,5 @@
{ {
"name": "ai-tycoon", "name": "token-empire",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "turbo dev", "dev": "turbo dev",
@@ -9,8 +9,8 @@
"test": "vitest run", "test": "vitest run",
"test:watch": "vitest", "test:watch": "vitest",
"clean": "turbo clean", "clean": "turbo clean",
"simulate": "turbo simulate --filter=@ai-tycoon/game-simulation", "simulate": "turbo simulate --filter=@token-empire/game-simulation",
"simulate:ci": "pnpm --filter @ai-tycoon/game-simulation simulate:ci" "simulate:ci": "pnpm --filter @token-empire/game-simulation simulate:ci"
}, },
"devDependencies": { "devDependencies": {
"turbo": "^2.5.0", "turbo": "^2.5.0",
+3 -3
View File
@@ -1,5 +1,5 @@
{ {
"name": "@ai-tycoon/game-engine", "name": "@token-empire/game-engine",
"private": true, "private": true,
"version": "0.0.1", "version": "0.0.1",
"type": "module", "type": "module",
@@ -11,10 +11,10 @@
"test": "vitest run" "test": "vitest run"
}, },
"dependencies": { "dependencies": {
"@ai-tycoon/shared": "workspace:*" "@token-empire/shared": "workspace:*"
}, },
"devDependencies": { "devDependencies": {
"@ai-tycoon/tsconfig": "workspace:*", "@token-empire/tsconfig": "workspace:*",
"typescript": "^5.8.0" "typescript": "^5.8.0"
} }
} }
@@ -2,8 +2,8 @@ import type {
Cluster, Campus, DataCenter, DeploymentCohort, Cluster, Campus, DataCenter, DeploymentCohort,
DCNetworkSummary, CampusNetworkSummary, ClusterNetworkSummary, DCNetworkSummary, CampusNetworkSummary, ClusterNetworkSummary,
TrainingPipeline, BaseModel, ModelFamily, TrainingPipeline, BaseModel, ModelFamily,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import { uuid } from '@ai-tycoon/shared'; import { uuid } from '@token-empire/shared';
import type { DeepPartial } from './createTestState'; import type { DeepPartial } from './createTestState';
function emptyDCNetwork(): DCNetworkSummary { function emptyDCNetwork(): DCNetworkSummary {
@@ -1,11 +1,11 @@
import type { GameState } from '@ai-tycoon/shared'; import type { GameState } from '@token-empire/shared';
import { import {
INITIAL_SETTINGS, SAVE_VERSION, INITIAL_SETTINGS, SAVE_VERSION,
INITIAL_ECONOMY, INITIAL_INFRASTRUCTURE, INITIAL_COMPUTE, INITIAL_ECONOMY, INITIAL_INFRASTRUCTURE, INITIAL_COMPUTE,
INITIAL_RESEARCH, INITIAL_MODELS, INITIAL_MARKET, INITIAL_RESEARCH, INITIAL_MODELS, INITIAL_MARKET,
INITIAL_COMPETITORS, INITIAL_TALENT, INITIAL_DATA, INITIAL_COMPETITORS, INITIAL_TALENT, INITIAL_DATA,
INITIAL_REPUTATION, INITIAL_ACHIEVEMENTS, INITIAL_REPUTATION, INITIAL_ACHIEVEMENTS,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
export type DeepPartial<T> = T extends object export type DeepPartial<T> = T extends object
? { [K in keyof T]?: DeepPartial<T[K]> } ? { [K in keyof T]?: DeepPartial<T[K]> }
@@ -1,4 +1,4 @@
import type { AchievementDefinition } from '@ai-tycoon/shared'; import type { AchievementDefinition } from '@token-empire/shared';
export const ACHIEVEMENT_DEFINITIONS: AchievementDefinition[] = [ export const ACHIEVEMENT_DEFINITIONS: AchievementDefinition[] = [
{ {
+1 -1
View File
@@ -1,4 +1,4 @@
import type { Competitor } from '@ai-tycoon/shared'; import type { Competitor } from '@token-empire/shared';
export const INITIAL_RIVALS: Competitor[] = [ export const INITIAL_RIVALS: Competitor[] = [
{ {
@@ -1,4 +1,4 @@
import type { EnterpriseSegment } from '@ai-tycoon/shared'; import type { EnterpriseSegment } from '@token-empire/shared';
export const ENTERPRISE_NAMES: Record<EnterpriseSegment, string[]> = { export const ENTERPRISE_NAMES: Record<EnterpriseSegment, string[]> = {
startup: [ startup: [
+1 -1
View File
@@ -1,4 +1,4 @@
import type { DepartmentId } from '@ai-tycoon/shared'; import type { DepartmentId } from '@token-empire/shared';
/** /**
* A recruitable key hire as it appears in the available pool. * A recruitable key hire as it appears in the available pool.
+1 -1
View File
@@ -1,4 +1,4 @@
import type { ResearchNode } from '@ai-tycoon/shared'; import type { ResearchNode } from '@token-empire/shared';
export const TECH_TREE: ResearchNode[] = [ export const TECH_TREE: ResearchNode[] = [
// === COMPUTE / INFRASTRUCTURE === // === COMPUTE / INFRASTRUCTURE ===
+1 -1
View File
@@ -1,4 +1,4 @@
import type { GameState } from '@ai-tycoon/shared'; import type { GameState } from '@token-empire/shared';
import { processTick } from './tick'; import { processTick } from './tick';
export interface GameEngineCallbacks { export interface GameEngineCallbacks {
@@ -1,7 +1,7 @@
import { describe, it, expect } from 'vitest'; import { describe, it, expect } from 'vitest';
import { processAchievements } from './achievementSystem'; import { processAchievements } from './achievementSystem';
import { createTestState } from '../__test-utils__'; import { createTestState } from '../__test-utils__';
import type { AchievementDefinition } from '@ai-tycoon/shared'; import type { AchievementDefinition } from '@token-empire/shared';
function makeDef(overrides: Partial<AchievementDefinition> = {}): AchievementDefinition { function makeDef(overrides: Partial<AchievementDefinition> = {}): AchievementDefinition {
return { return {
@@ -1,4 +1,4 @@
import type { GameState, AchievementState, AchievementDefinition } from '@ai-tycoon/shared'; import type { GameState, AchievementState, AchievementDefinition } from '@token-empire/shared';
export interface AchievementTickResult { export interface AchievementTickResult {
achievements: AchievementState; achievements: AchievementState;
@@ -1,8 +1,8 @@
import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { processCompetitors } from './competitorSystem'; import { processCompetitors } from './competitorSystem';
import { createTestState, createSeededRNG } from '../__test-utils__'; import { createTestState, createSeededRNG } from '../__test-utils__';
import { FRESHNESS_DECAY_RATE } from '@ai-tycoon/shared'; import { FRESHNESS_DECAY_RATE } from '@token-empire/shared';
import type { Competitor } from '@ai-tycoon/shared'; import type { Competitor } from '@token-empire/shared';
const rng = createSeededRNG(42); const rng = createSeededRNG(42);
beforeEach(() => rng.install()); beforeEach(() => rng.install());
@@ -1,10 +1,10 @@
import type { GameState, CompetitorState, Competitor } from '@ai-tycoon/shared'; import type { GameState, CompetitorState, Competitor } from '@token-empire/shared';
import { import {
COMPETITOR_PRODUCT_THRESHOLDS, COMPETITOR_PRODUCT_THRESHOLDS,
COMPETITOR_CATCHUP_SHARE_THRESHOLD, COMPETITOR_CATCHUP_SHARE_THRESHOLD,
COMPETITOR_CATCHUP_PRICE_CUT, COMPETITOR_CATCHUP_PRICE_CUT,
FRESHNESS_DECAY_RATE, FRESHNESS_DECAY_RATE,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
function updateCompetitorProducts(rival: Competitor): Competitor['products'] { function updateCompetitorProducts(rival: Competitor): Competitor['products'] {
const cap = rival.estimatedCapability; const cap = rival.estimatedCapability;
@@ -1,8 +1,8 @@
import { describe, it, expect } from 'vitest'; import { describe, it, expect } from 'vitest';
import { createTestState } from '../__test-utils__'; import { createTestState } from '../__test-utils__';
import { computeCapacity, finalizeCompute } from './computeSystem'; import { computeCapacity, finalizeCompute } from './computeSystem';
import type { InfrastructureState } from '@ai-tycoon/shared'; import type { InfrastructureState } from '@token-empire/shared';
import { INITIAL_INFRASTRUCTURE, FLOPS_TO_TOKENS_MULTIPLIER, COMPUTE_SNAPSHOT_INTERVAL, MAX_COMPUTE_HISTORY } from '@ai-tycoon/shared'; import { INITIAL_INFRASTRUCTURE, FLOPS_TO_TOKENS_MULTIPLIER, COMPUTE_SNAPSHOT_INTERVAL, MAX_COMPUTE_HISTORY } from '@token-empire/shared';
function createInfrastructure(overrides: Partial<InfrastructureState> = {}): InfrastructureState { function createInfrastructure(overrides: Partial<InfrastructureState> = {}): InfrastructureState {
return { ...INITIAL_INFRASTRUCTURE, ...overrides }; return { ...INITIAL_INFRASTRUCTURE, ...overrides };
@@ -1,5 +1,5 @@
import type { GameState, ComputeState, InfrastructureState } from '@ai-tycoon/shared'; import type { GameState, ComputeState, InfrastructureState } from '@token-empire/shared';
import { FLOPS_TO_TOKENS_MULTIPLIER, COMPUTE_SNAPSHOT_INTERVAL, MAX_COMPUTE_HISTORY } from '@ai-tycoon/shared'; import { FLOPS_TO_TOKENS_MULTIPLIER, COMPUTE_SNAPSHOT_INTERVAL, MAX_COMPUTE_HISTORY } from '@token-empire/shared';
import type { ResearchBonuses } from './researchBonuses'; import type { ResearchBonuses } from './researchBonuses';
export interface CapacityResult { export interface CapacityResult {
@@ -1,7 +1,7 @@
import { describe, it, expect } from 'vitest'; import { describe, it, expect } from 'vitest';
import { processData } from './dataSystem'; import { processData } from './dataSystem';
import { createTestState } from '../__test-utils__'; import { createTestState } from '../__test-utils__';
import type { DataPartnership } from '@ai-tycoon/shared'; import type { DataPartnership } from '@token-empire/shared';
function makePartnership(tokensPerTick: number): DataPartnership { function makePartnership(tokensPerTick: number): DataPartnership {
return { return {
@@ -1,4 +1,4 @@
import type { GameState, DataState } from '@ai-tycoon/shared'; import type { GameState, DataState } from '@token-empire/shared';
export function processData(state: GameState): DataState { export function processData(state: GameState): DataState {
const subscribers = state.market.consumerTiers.totalUsers; const subscribers = state.market.consumerTiers.totalUsers;
@@ -2,7 +2,7 @@ import { describe, it, expect } from 'vitest';
import { processEconomy } from './economySystem'; import { processEconomy } from './economySystem';
import { createTestState, createTestCluster } from '../__test-utils__'; import { createTestState, createTestCluster } from '../__test-utils__';
import type { MarketTickResult } from './marketSystem'; import type { MarketTickResult } from './marketSystem';
import type { InfrastructureState } from '@ai-tycoon/shared'; import type { InfrastructureState } from '@token-empire/shared';
function createMarketResult( function createMarketResult(
overrides: Partial<MarketTickResult> = {}, overrides: Partial<MarketTickResult> = {},
@@ -1,5 +1,5 @@
import type { GameState, EconomyState, InfrastructureState } from '@ai-tycoon/shared'; import type { GameState, EconomyState, InfrastructureState } from '@token-empire/shared';
import { FINANCIAL_SNAPSHOT_INTERVAL, MAX_FINANCIAL_HISTORY, REGULATION_COMPLIANCE_PER_CAPABILITY } from '@ai-tycoon/shared'; import { FINANCIAL_SNAPSHOT_INTERVAL, MAX_FINANCIAL_HISTORY, REGULATION_COMPLIANCE_PER_CAPABILITY } from '@token-empire/shared';
import { TECH_TREE } from '../data/techTree'; import { TECH_TREE } from '../data/techTree';
import type { MarketTickResult } from './marketSystem'; import type { MarketTickResult } from './marketSystem';
@@ -1,5 +1,5 @@
import type { GameState, Era } from '@ai-tycoon/shared'; import type { GameState, Era } from '@token-empire/shared';
import { ERA_THRESHOLDS } from '@ai-tycoon/shared'; import { ERA_THRESHOLDS } from '@token-empire/shared';
export function checkEraTransition(state: GameState): Era | null { export function checkEraTransition(state: GameState): Era | null {
const current = state.meta.currentEra; const current = state.meta.currentEra;
@@ -1,5 +1,5 @@
import type { GameState, FundingState, FundingRoundType } from '@ai-tycoon/shared'; import type { GameState, FundingState, FundingRoundType } from '@token-empire/shared';
import { FUNDING_ROUNDS } from '@ai-tycoon/shared'; import { FUNDING_ROUNDS } from '@token-empire/shared';
const ROUND_ORDER: FundingRoundType[] = ['seed', 'seriesA', 'seriesB', 'seriesC', 'seriesD', 'ipo']; const ROUND_ORDER: FundingRoundType[] = ['seed', 'seriesA', 'seriesB', 'seriesC', 'seriesD', 'ipo'];
@@ -3,7 +3,7 @@ import type {
DeploymentCohort, PipelineStage, RackSkuId, DeploymentCohort, PipelineStage, RackSkuId,
SwitchTier, DCNetworkSummary, CampusNetworkSummary, ClusterNetworkSummary, SwitchTier, DCNetworkSummary, CampusNetworkSummary, ClusterNetworkSummary,
RepairBatch, CampusRetrofitQueue, DCTier, IntraNodeInterconnect, NetworkFabric, RackSkuConfig, RepairBatch, CampusRetrofitQueue, DCTier, IntraNodeInterconnect, NetworkFabric, RackSkuConfig,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import { import {
LOCATION_CONFIGS, LOCATION_CONFIGS,
RACK_SKU_CONFIGS, RACK_SKU_CONFIGS,
@@ -22,7 +22,7 @@ import {
COOLING_TYPE_CONFIGS, COOLING_TYPE_CONFIGS,
NETWORK_FABRIC_CONFIGS, NETWORK_FABRIC_CONFIGS,
estimateNetworkSlots, estimateNetworkSlots,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import type { TickNotification } from '../tick'; import type { TickNotification } from '../tick';
import type { ResearchBonuses } from './researchBonuses'; import type { ResearchBonuses } from './researchBonuses';
@@ -1,11 +1,11 @@
import type { ApiTierState, ApiTierId, DeveloperEcosystem, TierServingMetrics } from '@ai-tycoon/shared'; import type { ApiTierState, ApiTierId, DeveloperEcosystem, TierServingMetrics } from '@token-empire/shared';
import { import {
API_TIER_ORDER, API_TIER_ORDER,
API_CONVERSION_RATES, API_CONVERSION_RATES,
API_TIER_CHURN_RATES, API_TIER_CHURN_RATES,
API_TOKENS_PER_DEVELOPER_PER_TICK, API_TOKENS_PER_DEVELOPER_PER_TICK,
REJECTION_CHURN_MULTIPLIER, REJECTION_CHURN_MULTIPLIER,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
export interface ApiTickResult { export interface ApiTickResult {
apiTiers: ApiTierState; apiTiers: ApiTierState;
@@ -1,4 +1,4 @@
import type { ConsumerTierState, ConsumerTierId, TierServingMetrics } from '@ai-tycoon/shared'; import type { ConsumerTierState, ConsumerTierId, TierServingMetrics } from '@token-empire/shared';
import { import {
CONSUMER_TIER_ORDER, CONSUMER_TIER_ORDER,
CONVERSION_RATES, CONVERSION_RATES,
@@ -14,7 +14,7 @@ import {
PRICE_SATISFACTION_WEIGHT, PRICE_SATISFACTION_WEIGHT,
PRICE_CHURN_EXPONENT, PRICE_CHURN_EXPONENT,
PRICE_CHURN_MAX_MULTIPLIER, PRICE_CHURN_MAX_MULTIPLIER,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
export interface ConsumerTickResult { export interface ConsumerTickResult {
consumerTiers: ConsumerTierState; consumerTiers: ConsumerTierState;
@@ -1,4 +1,4 @@
import type { DeveloperEcosystem } from '@ai-tycoon/shared'; import type { DeveloperEcosystem } from '@token-empire/shared';
import { import {
BASE_DEV_GROWTH, BASE_DEV_GROWTH,
FREE_TIER_DEV_MULTIPLIER, FREE_TIER_DEV_MULTIPLIER,
@@ -9,8 +9,8 @@ import {
STARTUP_ADOPTION_PER_DEV, STARTUP_ADOPTION_PER_DEV,
ENTERPRISE_REFERRAL_PER_STARTUP, ENTERPRISE_REFERRAL_PER_STARTUP,
TAM_BASE_SIZES, TAM_BASE_SIZES,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import type { Era } from '@ai-tycoon/shared'; import type { Era } from '@token-empire/shared';
export function processDeveloperEcosystem( export function processDeveloperEcosystem(
eco: DeveloperEcosystem, eco: DeveloperEcosystem,
@@ -6,7 +6,7 @@ import type {
EnterprisePipelineStage, EnterprisePipelineStage,
DeveloperEcosystem, DeveloperEcosystem,
TierServingMetrics, TierServingMetrics,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import { import {
BASE_LEAD_RATE, BASE_LEAD_RATE,
LEAD_EXPIRY_TICKS, LEAD_EXPIRY_TICKS,
@@ -19,7 +19,7 @@ import {
ENTERPRISE_CAPABILITY_REQUIREMENTS, ENTERPRISE_CAPABILITY_REQUIREMENTS,
ENTERPRISE_TOKENS_PER_TICK, ENTERPRISE_TOKENS_PER_TICK,
ENTERPRISE_REJECTION_SLA_MULTIPLIER, ENTERPRISE_REJECTION_SLA_MULTIPLIER,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import { ENTERPRISE_NAMES } from '../../data/enterpriseNames'; import { ENTERPRISE_NAMES } from '../../data/enterpriseNames';
let leadIdCounter = 0; let leadIdCounter = 0;
@@ -1,6 +1,6 @@
import type { GameState, MarketState, ModelCapabilities } from '@ai-tycoon/shared'; import type { GameState, MarketState, ModelCapabilities } from '@token-empire/shared';
import { CONSUMER_TOKENS_PER_SUBSCRIBER, API_TOKENS_PER_DEVELOPER_PER_TICK, BATCH_API_DEMAND_PER_DEV, makeInitialServingMetrics } from '@ai-tycoon/shared'; import { CONSUMER_TOKENS_PER_SUBSCRIBER, API_TOKENS_PER_DEVELOPER_PER_TICK, BATCH_API_DEMAND_PER_DEV, makeInitialServingMetrics } from '@token-empire/shared';
import type { TrafficPriority, TierServingMetrics } from '@ai-tycoon/shared'; import type { TrafficPriority, TierServingMetrics } from '@token-empire/shared';
import { computeSeasonal } from './seasonalSystem'; import { computeSeasonal } from './seasonalSystem';
import { updateObsolescence } from './obsolescenceSystem'; import { updateObsolescence } from './obsolescenceSystem';
import { buildPlayerProfile, buildCompetitorProfile, computeMarketShares, updateTAMGrowth } from './tamSystem'; import { buildPlayerProfile, buildCompetitorProfile, computeMarketShares, updateTAMGrowth } from './tamSystem';
@@ -1,10 +1,10 @@
import type { ObsolescenceState, Era } from '@ai-tycoon/shared'; import type { ObsolescenceState, Era } from '@token-empire/shared';
import { import {
OBSOLESCENCE_BASELINE_GROWTH, OBSOLESCENCE_BASELINE_GROWTH,
OBSOLESCENCE_ERA_ACCELERATOR, OBSOLESCENCE_ERA_ACCELERATOR,
FRESHNESS_DECAY_RATE, FRESHNESS_DECAY_RATE,
NEW_MODEL_BOOST_TICKS, NEW_MODEL_BOOST_TICKS,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
export function updateObsolescence( export function updateObsolescence(
obs: ObsolescenceState, obs: ObsolescenceState,
@@ -1,4 +1,4 @@
import type { CodeAssistantState, AgentsPlatformState, ModelCapabilities } from '@ai-tycoon/shared'; import type { CodeAssistantState, AgentsPlatformState, ModelCapabilities } from '@token-empire/shared';
import { import {
CODE_ASSISTANT_MIN_CODING_SCORE, CODE_ASSISTANT_MIN_CODING_SCORE,
CODE_ASSISTANT_BASE_ADOPTION_RATE, CODE_ASSISTANT_BASE_ADOPTION_RATE,
@@ -6,7 +6,7 @@ import {
AGENTS_PLATFORM_MIN_AGENTS_SCORE, AGENTS_PLATFORM_MIN_AGENTS_SCORE,
AGENTS_PLATFORM_BASE_ADOPTION_RATE, AGENTS_PLATFORM_BASE_ADOPTION_RATE,
AGENTS_PLATFORM_CHURN_RATE, AGENTS_PLATFORM_CHURN_RATE,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
export interface ProductLineResult { export interface ProductLineResult {
codeAssistant: CodeAssistantState; codeAssistant: CodeAssistantState;
@@ -1,5 +1,5 @@
import type { SeasonalPhase } from '@ai-tycoon/shared'; import type { SeasonalPhase } from '@token-empire/shared';
import { SEASONAL_CYCLE_TICKS, SEASONAL_MULTIPLIERS } from '@ai-tycoon/shared'; import { SEASONAL_CYCLE_TICKS, SEASONAL_MULTIPLIERS } from '@token-empire/shared';
export interface SeasonalResult { export interface SeasonalResult {
phase: SeasonalPhase; phase: SeasonalPhase;
@@ -5,8 +5,8 @@ import type {
ServingMetrics, ServingMetrics,
ModelUtilizationEntry, ModelUtilizationEntry,
BatchApiState, BatchApiState,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import type { BaseModel, ModelsState, SizeTier } from '@ai-tycoon/shared'; import type { BaseModel, ModelsState, SizeTier } from '@token-empire/shared';
import { import {
MODEL_SIZE_THROUGHPUT_SCALER, MODEL_SIZE_THROUGHPUT_SCALER,
MOE_SPEED_MULTIPLIER, MOE_SPEED_MULTIPLIER,
@@ -18,8 +18,8 @@ import {
BASE_LATENCY_MS, BASE_LATENCY_MS,
QUEUE_LATENCY_MS_PER_PERCENT, QUEUE_LATENCY_MS_PER_PERCENT,
BATCH_API_MAX_PENDING, BATCH_API_MAX_PENDING,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import { makeInitialServingMetrics } from '@ai-tycoon/shared'; import { makeInitialServingMetrics } from '@token-empire/shared';
export interface ModelServingSlot { export interface ModelServingSlot {
modelId: string; modelId: string;
@@ -6,7 +6,7 @@ import type {
Era, Era,
ObsolescenceState, ObsolescenceState,
DeveloperEcosystem, DeveloperEcosystem,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import { import {
TAM_BASE_SIZES, TAM_BASE_SIZES,
TAM_GROWTH_PER_TICK, TAM_GROWTH_PER_TICK,
@@ -17,7 +17,7 @@ import {
NEW_MODEL_BOOST_VALUE, NEW_MODEL_BOOST_VALUE,
CONSUMER_TIER_BASE_PERCEIVED_VALUE, CONSUMER_TIER_BASE_PERCEIVED_VALUE,
PERCEIVED_VALUE_REPUTATION_RANGE, PERCEIVED_VALUE_REPUTATION_RANGE,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
export interface ParticipantProfile { export interface ParticipantProfile {
id: string; id: string;
@@ -1,4 +1,4 @@
import type { GameState } from '@ai-tycoon/shared'; import type { GameState } from '@token-empire/shared';
import { processMarketV2 } from './market/index'; import { processMarketV2 } from './market/index';
import type { ResearchBonuses } from './researchBonuses'; import type { ResearchBonuses } from './researchBonuses';
@@ -10,7 +10,7 @@ import { processModels } from './modelSystem';
import { import {
POINT_RELEASE_CAPABILITY_GAIN, POINT_RELEASE_CAPABILITY_GAIN,
VRAM_REQUIREMENTS_BY_GENERATION, VRAM_REQUIREMENTS_BY_GENERATION,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import type { ResearchBonuses } from './researchBonuses'; import type { ResearchBonuses } from './researchBonuses';
const rng = createSeededRNG(42); const rng = createSeededRNG(42);
@@ -2,7 +2,7 @@ import type {
GameState, ModelsState, BaseModel, ModelCapabilities, SafetyProfile, GameState, ModelsState, BaseModel, ModelCapabilities, SafetyProfile,
TrainingPipeline, TrainingEvent, TrainingEventType, TrainingPipeline, TrainingEvent, TrainingEventType,
ModelVariant, VariantCreationJob, ModelVariant, VariantCreationJob,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import { import {
uuid, VRAM_REQUIREMENTS_BY_GENERATION, uuid, VRAM_REQUIREMENTS_BY_GENERATION,
MOE_CAPABILITY_MULTIPLIER, MOE_SPEED_MULTIPLIER, MOE_CAPABILITY_MULTIPLIER, MOE_SPEED_MULTIPLIER,
@@ -17,7 +17,7 @@ import {
POINT_RELEASE_CAPABILITY_GAIN, POINT_RELEASE_CAPABILITY_GAIN,
SIZE_TIER_LABELS, SIZE_TIER_LABELS,
MODEL_BASE_SAFETY, MODEL_BASE_SAFETY,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import type { ResearchBonuses } from './researchBonuses'; import type { ResearchBonuses } from './researchBonuses';
export interface ModelTickResult { export interface ModelTickResult {
@@ -6,7 +6,7 @@ import {
LOW_SAFETY_THRESHOLD, LOW_SAFETY_THRESHOLD,
SAFETY_RECORD_RECOVERY_RATE, SAFETY_RECORD_RECOVERY_RATE,
SAFETY_INCIDENT_REPUTATION_HIT, SAFETY_INCIDENT_REPUTATION_HIT,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
const rng = createSeededRNG(42); const rng = createSeededRNG(42);
beforeEach(() => rng.install()); beforeEach(() => rng.install());
@@ -1,4 +1,4 @@
import type { GameState, ReputationState } from '@ai-tycoon/shared'; import type { GameState, ReputationState } from '@token-empire/shared';
import { import {
MAX_REPUTATION_HISTORY, MAX_REPUTATION_HISTORY,
SAFETY_INCIDENT_PROBABILITY_BASE, SAFETY_INCIDENT_PROBABILITY_BASE,
@@ -6,7 +6,7 @@ import {
LOW_SAFETY_THRESHOLD, LOW_SAFETY_THRESHOLD,
SAFETY_RECORD_RECOVERY_RATE, SAFETY_RECORD_RECOVERY_RATE,
PUBLIC_PERCEPTION_GROWTH_RATE, PUBLIC_PERCEPTION_GROWTH_RATE,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import type { ResearchBonuses } from './researchBonuses'; import type { ResearchBonuses } from './researchBonuses';
export interface ReputationTickResult { export interface ReputationTickResult {
@@ -1,4 +1,4 @@
import type { GameState, ResearchState, ActiveResearch, ComputeState } from '@ai-tycoon/shared'; import type { GameState, ResearchState, ActiveResearch, ComputeState } from '@token-empire/shared';
import { TECH_TREE } from '../data/techTree'; import { TECH_TREE } from '../data/techTree';
export interface ResearchTickResult { export interface ResearchTickResult {
@@ -1,5 +1,5 @@
import type { GameState, TalentState } from '@ai-tycoon/shared'; import type { GameState, TalentState } from '@token-empire/shared';
import { ERA_BUDGET_COST_MULTIPLIER } from '@ai-tycoon/shared'; import { ERA_BUDGET_COST_MULTIPLIER } from '@token-empire/shared';
const SALARY_PER_HEADCOUNT_PER_TICK = 5; const SALARY_PER_HEADCOUNT_PER_TICK = 5;
+1 -1
View File
@@ -1,4 +1,4 @@
import type { GameState, AchievementDefinition } from '@ai-tycoon/shared'; import type { GameState, AchievementDefinition } from '@token-empire/shared';
import { processEconomy } from './systems/economySystem'; import { processEconomy } from './systems/economySystem';
import { processInfrastructure } from './systems/infrastructureSystem'; import { processInfrastructure } from './systems/infrastructureSystem';
import { computeCapacity, finalizeCompute } from './systems/computeSystem'; import { computeCapacity, finalizeCompute } from './systems/computeSystem';
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"extends": "@ai-tycoon/tsconfig/base.json", "extends": "@token-empire/tsconfig/base.json",
"compilerOptions": { "compilerOptions": {
"outDir": "dist", "outDir": "dist",
"rootDir": "src" "rootDir": "src"
+4 -4
View File
@@ -1,5 +1,5 @@
{ {
"name": "@ai-tycoon/game-simulation", "name": "@token-empire/game-simulation",
"private": true, "private": true,
"version": "0.0.1", "version": "0.0.1",
"type": "module", "type": "module",
@@ -19,11 +19,11 @@
"test": "vitest run" "test": "vitest run"
}, },
"dependencies": { "dependencies": {
"@ai-tycoon/shared": "workspace:*", "@token-empire/shared": "workspace:*",
"@ai-tycoon/game-engine": "workspace:*" "@token-empire/game-engine": "workspace:*"
}, },
"devDependencies": { "devDependencies": {
"@ai-tycoon/tsconfig": "workspace:*", "@token-empire/tsconfig": "workspace:*",
"@types/node": "^22.0.0", "@types/node": "^22.0.0",
"tsx": "^4.19.4", "tsx": "^4.19.4",
"typescript": "^5.8.0" "typescript": "^5.8.0"
@@ -1,4 +1,4 @@
import type { GameState } from '@ai-tycoon/shared'; import type { GameState } from '@token-empire/shared';
export function acquireCompetitor(state: GameState, competitorId: string): boolean { export function acquireCompetitor(state: GameState, competitorId: string): boolean {
const rival = state.competitors.rivals.find(r => r.id === competitorId); const rival = state.competitors.rivals.find(r => r.id === competitorId);
+1 -1
View File
@@ -1,4 +1,4 @@
import type { GameState, OwnedDataset } from '@ai-tycoon/shared'; import type { GameState, OwnedDataset } from '@token-empire/shared';
export function purchaseDataset(state: GameState, dataset: OwnedDataset, cost: number): boolean { export function purchaseDataset(state: GameState, dataset: OwnedDataset, cost: number): boolean {
if (state.economy.money < cost) return false; if (state.economy.money < cost) return false;
@@ -1,6 +1,6 @@
import type { GameState, FundingRoundType } from '@ai-tycoon/shared'; import type { GameState, FundingRoundType } from '@token-empire/shared';
import { FUNDING_ROUNDS } from '@ai-tycoon/shared'; import { FUNDING_ROUNDS } from '@token-empire/shared';
import { canRaiseFunding, getNextFundingRound } from '@ai-tycoon/game-engine'; import { canRaiseFunding, getNextFundingRound } from '@token-empire/game-engine';
export function raiseFunding(state: GameState, roundType: FundingRoundType): boolean { export function raiseFunding(state: GameState, roundType: FundingRoundType): boolean {
const config = FUNDING_ROUNDS[roundType]; const config = FUNDING_ROUNDS[roundType];
@@ -2,7 +2,7 @@ import type {
GameState, Era, LocationId, DCTier, RackSkuId, GameState, Era, LocationId, DCTier, RackSkuId,
Cluster, Campus, DataCenter, DeploymentCohort, Cluster, Campus, DataCenter, DeploymentCohort,
CoolingType, NetworkFabric, PipelineStage, CoolingType, NetworkFabric, PipelineStage,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import { import {
LOCATION_CONFIGS, DC_TIER_CONFIGS, RACK_SKU_CONFIGS, LOCATION_CONFIGS, DC_TIER_CONFIGS, RACK_SKU_CONFIGS,
CLUSTER_COST_CONFIG, CAMPUS_TIER_COSTS, FIRST_CAMPUS_BUILD_TICKS, CLUSTER_COST_CONFIG, CAMPUS_TIER_COSTS, FIRST_CAMPUS_BUILD_TICKS,
@@ -11,10 +11,10 @@ import {
FABRIC_ORDER, NETWORK_FABRIC_CONFIGS, FABRIC_ORDER, NETWORK_FABRIC_CONFIGS,
DC_UPGRADE_COST_FRACTION, DC_UPGRADE_INCREMENT, DC_UPGRADE_COST_FRACTION, DC_UPGRADE_INCREMENT,
estimateNetworkSlots, maxComputeRacks, estimateNetworkSlots, maxComputeRacks,
} from '@ai-tycoon/shared'; } from '@token-empire/shared';
import { import {
emptyDCNetworkSummary, emptyCampusNetworkSummary, emptyClusterNetworkSummary, emptyDCNetworkSummary, emptyCampusNetworkSummary, emptyClusterNetworkSummary,
} from '@ai-tycoon/game-engine'; } from '@token-empire/game-engine';
import { simId } from './ids'; import { simId } from './ids';
const ERA_ORDER: Era[] = ['startup', 'scaleup', 'bigtech', 'agi']; const ERA_ORDER: Era[] = ['startup', 'scaleup', 'bigtech', 'agi'];
@@ -1,4 +1,4 @@
import type { GameState, ConsumerTierId, ApiTierId } from '@ai-tycoon/shared'; import type { GameState, ConsumerTierId, ApiTierId } from '@token-empire/shared';
export function setTrainingAllocation(state: GameState, ratio: number): void { export function setTrainingAllocation(state: GameState, ratio: number): void {
state.compute.trainingAllocation = ratio; state.compute.trainingAllocation = ratio;

Some files were not shown because too many files have changed in this diff Show More