Game balance audit: wire research effects, rework capability formula, fix dead systems
CI / build-and-push (push) Successful in 32s

- Create researchBonuses utility to aggregate tech tree effects into all game systems
  (infrastructure energy costs, compute efficiency, training speed, model capability, reputation)
- Rework model capability from sqrt(compute) to 4-pillar formula (params + compute + data + research)
- Make context window affect benchmarks and inference speed
- Add MoE tradeoffs: 1.5x VRAM, 0.8x training speed
- Enforce research point costs as a gate for unlocking research
- Add real consequences to data contamination events (reputation hit, legal costs)
- Scale talent costs from $0.03 to $5/tick per headcount
- Scale compliance costs 100x to be meaningful
- Rework competitor acquisition: cheaper but grants headcount, RP, and reputation
- Remove dead code: sfxVolume, autoSaveInterval, notificationsEnabled,
  FAST_FORWARD_BATCH_SIZE, CHINCHILLA_OPTIMAL_RATIO

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-25 09:36:31 -04:00
parent 8d650fefae
commit 00e790591e
14 changed files with 205 additions and 54 deletions
+17 -5
View File
@@ -12,6 +12,7 @@ import { processData } from './systems/dataSystem';
import { checkEraTransition } from './systems/eraSystem';
import { processAchievements } from './systems/achievementSystem';
import { computeValuation } from './systems/fundingSystem';
import { getResearchBonuses } from './systems/researchBonuses';
export interface TickResult {
state: Partial<GameState>;
@@ -32,13 +33,14 @@ export function setAchievementDefinitions(defs: AchievementDefinition[]) {
export function processTick(state: GameState): Partial<GameState> {
const notifications: TickNotification[] = [];
const researchBonuses = getResearchBonuses(state.research.completedResearch);
const infraResult = processInfrastructure(state);
const infraResult = processInfrastructure(state, researchBonuses);
const infrastructure = infraResult.infrastructure;
notifications.push(...infraResult.notifications);
const stateWithInfra = { ...state, infrastructure };
const modelResult = processModels(stateWithInfra);
const modelResult = processModels(stateWithInfra, researchBonuses);
for (const completed of modelResult.completedModels) {
notifications.push({
@@ -51,7 +53,7 @@ export function processTick(state: GameState): Partial<GameState> {
const stateWithModels = { ...stateWithInfra, models: modelResult.modelsState };
const capacity = computeCapacity(state, infrastructure);
const capacity = computeCapacity(state, infrastructure, researchBonuses);
const market = processMarket(stateWithModels, capacity.tokensPerSecondCapacity);
const compute = finalizeCompute(capacity, market.totalTokenDemand);
@@ -67,7 +69,7 @@ export function processTick(state: GameState): Partial<GameState> {
});
}
const reputationResult = processReputation(stateWithTalent);
const reputationResult = processReputation(stateWithTalent, researchBonuses);
const { _safetyIncident, ...reputation } = reputationResult;
if (_safetyIncident) {
notifications.push({
@@ -76,7 +78,17 @@ export function processTick(state: GameState): Partial<GameState> {
type: 'danger',
});
}
const economy = processEconomy(stateWithTalent, market, infrastructure, infraResult.repairCosts);
if (modelResult.reputationHit > 0) {
reputation.publicPerception = Math.max(0, reputation.publicPerception - modelResult.reputationHit);
reputation.score = Math.round(
reputation.safetyRecord * 0.3 +
reputation.publicPerception * 0.3 +
reputation.employeeSatisfaction * 0.2 +
reputation.regulatoryStanding * 0.2,
);
}
const extraCosts = infraResult.repairCosts + modelResult.legalCosts;
const economy = processEconomy(stateWithTalent, market, infrastructure, extraCosts);
const data = processData(stateWithTalent);
const competitors = processCompetitors(stateWithTalent);