Add complete game loop: training, revenue, market, offline catch-up
- Model training system: training jobs produce TrainedModels with calculated capabilities based on compute, data, and research - Market system: organic API demand and consumer subscriptions now generate real revenue from deployed models - Talent system: salary costs calculated from department headcount - Toast notification system for game events (training complete, etc.) - Offline catch-up: progress bar + summary screen when returning - Market page: pricing controls for API and subscription products - Finance page: income statement, cash charts, funding history - Tick processor now runs all 7 systems in correct dependency order Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,20 +3,56 @@ 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';
|
||||
|
||||
export interface TickResult {
|
||||
state: Partial<GameState>;
|
||||
notifications: TickNotification[];
|
||||
}
|
||||
|
||||
export interface TickNotification {
|
||||
title: string;
|
||||
message: string;
|
||||
type: 'info' | 'success' | 'warning' | 'danger';
|
||||
}
|
||||
|
||||
export function processTick(state: GameState): Partial<GameState> {
|
||||
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);
|
||||
const research = processResearch(state, compute);
|
||||
const market = processMarket(state, compute);
|
||||
const reputation = processReputation(state);
|
||||
const economy = processEconomy(state, market, 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 research = processResearch(stateWithTalent, compute);
|
||||
const reputation = processReputation(stateWithTalent);
|
||||
const economy = processEconomy(stateWithTalent, market, infrastructure);
|
||||
|
||||
const tickCount = state.meta.tickCount + 1;
|
||||
|
||||
return {
|
||||
const result: Partial<GameState> = {
|
||||
meta: {
|
||||
...state.meta,
|
||||
tickCount,
|
||||
@@ -27,7 +63,13 @@ export function processTick(state: GameState): Partial<GameState> {
|
||||
infrastructure,
|
||||
compute,
|
||||
research,
|
||||
models: modelResult.modelsState,
|
||||
market: market.marketState,
|
||||
talent,
|
||||
reputation,
|
||||
};
|
||||
|
||||
(result as Record<string, unknown>)['_notifications'] = notifications;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user