Files
AIHostingTycoon/packages/game-engine/src/systems/computeSystem.ts
T
josh c1cc70eeb9
Balance Check / balance-simulation (pull_request) Successful in 38s
Balance Check / multi-run-balance (pull_request) Successful in 13m44s
Rename AI Tycoon to Token Empire across entire codebase
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

79 lines
2.9 KiB
TypeScript

import type { GameState, ComputeState, InfrastructureState } from '@token-empire/shared';
import { FLOPS_TO_TOKENS_MULTIPLIER, COMPUTE_SNAPSHOT_INTERVAL, MAX_COMPUTE_HISTORY } from '@token-empire/shared';
import type { ResearchBonuses } from './researchBonuses';
export interface CapacityResult {
totalFlops: number;
totalTrainingFlops: number;
totalInferenceFlops: number;
totalVramGB: number;
trainingAllocation: number;
inferenceAllocation: number;
effectiveTrainingFlops: number;
effectiveInferenceFlops: number;
tokensPerSecondCapacity: number;
}
export function computeCapacity(state: GameState, infrastructure: InfrastructureState, researchBonuses?: ResearchBonuses): CapacityResult {
const { totalTrainingFlops, totalInferenceFlops, totalVramGB } = infrastructure;
const trainingAllocation = state.compute.trainingAllocation;
const inferenceAllocation = 1 - trainingAllocation;
const effectiveTrainingFlops =
totalTrainingFlops * trainingAllocation +
totalInferenceFlops * trainingAllocation * 0.3;
const inferenceBoost = 1 + (researchBonuses?.tokensPerFlopBonus ?? 0) + (researchBonuses?.inferenceEfficiencyBonus ?? 0);
const effectiveInferenceFlops =
(totalInferenceFlops * inferenceAllocation +
totalTrainingFlops * inferenceAllocation * 0.5) * inferenceBoost;
const tokensPerSecondCapacity = effectiveInferenceFlops * FLOPS_TO_TOKENS_MULTIPLIER;
return {
totalFlops: totalTrainingFlops + totalInferenceFlops,
totalTrainingFlops,
totalInferenceFlops,
totalVramGB,
trainingAllocation,
inferenceAllocation,
effectiveTrainingFlops,
effectiveInferenceFlops,
tokensPerSecondCapacity,
};
}
export function finalizeCompute(capacity: CapacityResult, totalTokenDemand: number, prevHistory: ComputeState['computeHistory'], tickCount: number): ComputeState {
const inferenceUtilization = capacity.tokensPerSecondCapacity > 0
? Math.min(1, totalTokenDemand / capacity.tokensPerSecondCapacity)
: (totalTokenDemand > 0 ? 1 : 0);
const computeHistory = [...prevHistory];
if (tickCount % COMPUTE_SNAPSHOT_INTERVAL === 0) {
computeHistory.push({
tick: tickCount,
totalFlops: capacity.totalFlops,
effectiveTrainingFlops: capacity.effectiveTrainingFlops,
effectiveInferenceFlops: capacity.effectiveInferenceFlops,
inferenceUtilization,
tokensPerSecondCapacity: capacity.tokensPerSecondCapacity,
tokensPerSecondDemand: totalTokenDemand,
});
if (computeHistory.length > MAX_COMPUTE_HISTORY) {
computeHistory.shift();
}
}
return {
...capacity,
tokensPerSecondDemand: totalTokenDemand,
inferenceUtilization,
computeHistory,
};
}
export function processCompute(state: GameState, infrastructure: InfrastructureState): ComputeState {
const cap = computeCapacity(state, infrastructure);
return finalizeCompute(cap, state.compute.tokensPerSecondDemand, state.compute.computeHistory, state.meta.tickCount);
}