import type { GameState, EventDefinition, AchievementDefinition } from '@ai-tycoon/shared'; import { processEconomy } from './systems/economySystem'; import { processInfrastructure } from './systems/infrastructureSystem'; import { processCompute } from './systems/computeSystem'; import { processResearch } from './systems/researchSystem'; import { processModels } from './systems/modelSystem'; import { processMarket } from './systems/marketSystem'; import { processReputation } from './systems/reputationSystem'; import { processTalent } from './systems/talentSystem'; import { processEvents } from './systems/eventSystem'; import { processCompetitors } from './systems/competitorSystem'; import { processData } from './systems/dataSystem'; import { checkEraTransition } from './systems/eraSystem'; import { processAchievements } from './systems/achievementSystem'; import { computeValuation } from './systems/fundingSystem'; export interface TickResult { state: Partial; notifications: TickNotification[]; } export interface TickNotification { title: string; message: string; type: 'info' | 'success' | 'warning' | 'danger'; } let cachedEventDefs: EventDefinition[] | null = null; let cachedAchievementDefs: AchievementDefinition[] | null = null; export function setEventDefinitions(defs: EventDefinition[]) { cachedEventDefs = defs; } export function setAchievementDefinitions(defs: AchievementDefinition[]) { cachedAchievementDefs = defs; } export function processTick(state: GameState): Partial { const notifications: TickNotification[] = []; const infrastructure = processInfrastructure(state); const stateWithInfra = { ...state, infrastructure }; const modelResult = processModels(stateWithInfra); if (modelResult.modelCompleted) { notifications.push({ title: 'Training Complete', message: `${modelResult.modelCompleted.name} is ready! Benchmark: ${modelResult.modelCompleted.benchmarkScore.toFixed(1)}/100`, type: 'success', }); } const stateWithModels = { ...stateWithInfra, models: modelResult.modelsState }; const market = processMarket(stateWithModels, state.compute); const compute = processCompute(state, infrastructure); compute.tokensPerSecondDemand = market.totalTokenDemand; compute.inferenceUtilization = compute.tokensPerSecondCapacity > 0 ? Math.min(1, market.totalTokenDemand / compute.tokensPerSecondCapacity) : 0; const talent = processTalent(stateWithModels); const stateWithTalent = { ...stateWithModels, talent }; const researchResult = processResearch(stateWithTalent, compute); if (researchResult.researchCompleted) { notifications.push({ title: 'Research Complete', message: `${researchResult.researchCompleted} has been unlocked!`, type: 'success', }); } const reputationResult = processReputation(stateWithTalent); const { _safetyIncident, ...reputation } = reputationResult; if (_safetyIncident) { notifications.push({ title: 'Safety Incident!', message: 'Your AI model caused a safety incident. Public trust and safety record damaged.', type: 'danger', }); } const economy = processEconomy(stateWithTalent, market, infrastructure); const data = processData(stateWithTalent); const competitors = processCompetitors(stateWithTalent); const eventResult = cachedEventDefs ? processEvents(stateWithTalent, cachedEventDefs) : { events: state.events, newEvents: [] }; for (const evt of eventResult.newEvents) { notifications.push({ title: evt.title, message: evt.description, type: evt.category === 'regulatory' ? 'warning' : 'info', }); } const tickCount = state.meta.tickCount + 1; let meta = { ...state.meta, tickCount, lastTickTimestamp: Date.now(), totalPlayTime: state.meta.totalPlayTime + 1, }; const newEra = checkEraTransition({ ...stateWithTalent, economy, reputation, research: researchResult.research }); if (newEra) { meta = { ...meta, currentEra: newEra }; notifications.push({ title: 'Era Transition!', message: `Your company has entered the ${newEra === 'scaleup' ? 'Scale-up' : newEra === 'bigtech' ? 'Big Tech' : 'AGI'} era!`, type: 'success', }); } const valuation = computeValuation({ ...stateWithTalent, economy, reputation, research: researchResult.research }); const updatedEconomy = { ...economy, funding: { ...economy.funding, valuation }, }; const stateForAchievements: GameState = { ...stateWithTalent, meta, economy: updatedEconomy, infrastructure, compute, research: researchResult.research, models: modelResult.modelsState, market: market.marketState, reputation, data, competitors, events: eventResult.events, achievements: state.achievements, }; const achievementResult = cachedAchievementDefs ? processAchievements(stateForAchievements, cachedAchievementDefs) : { achievements: state.achievements, newAchievements: [] }; for (const name of achievementResult.newAchievements) { notifications.push({ title: 'Achievement Unlocked!', message: name, type: 'success', }); } const result: Partial = { meta, economy: updatedEconomy, infrastructure, compute, research: researchResult.research, models: modelResult.modelsState, market: market.marketState, talent, reputation, data, competitors, events: eventResult.events, achievements: achievementResult.achievements, }; (result as Record)['_notifications'] = notifications; return result; }