Add research money costs, longer research times, era-scaled talent costs, and persona strategy
Balance Check / balance-simulation (push) Successful in 11m19s
Balance Check / multi-run-balance (push) Has been cancelled
CI / build-and-push (push) Successful in 40s

Research now costs money (drained per-tick) with ~2.5-3.5x longer durations by category.
Early-game talent budget costs reduced via era multiplier (startup 0.2x → bigtech 1.0x).
New seed-driven PersonaStrategy with 8 axes of variation for meaningful multi-run testing.
CI multi-run switched from greedy to persona strategy.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-26 16:14:27 -04:00
parent b906592af4
commit 416b6bfe8d
14 changed files with 721 additions and 64 deletions
+45 -45
View File
@@ -9,7 +9,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'startup',
category: 'infrastructure',
prerequisites: [],
cost: { researchPoints: 0, compute: 5, ticks: 60 },
cost: { researchPoints: 0, compute: 5, ticks: 150, money: 2250 },
effects: [{ type: 'cost_reduction', target: 'energy', value: 0.25 }],
},
{
@@ -19,7 +19,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'startup',
category: 'infrastructure',
prerequisites: [],
cost: { researchPoints: 0, compute: 5, ticks: 60 },
cost: { researchPoints: 0, compute: 5, ticks: 150, money: 2250 },
effects: [{ type: 'cost_reduction', target: 'failure_rate', value: 0.5 }],
},
{
@@ -29,7 +29,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'startup',
category: 'infrastructure',
prerequisites: [],
cost: { researchPoints: 0, compute: 10, ticks: 90 },
cost: { researchPoints: 0, compute: 10, ticks: 225, money: 3375 },
effects: [{ type: 'unlock_rack', target: 'a100', value: 1 }],
},
{
@@ -39,7 +39,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'infrastructure',
prerequisites: ['advanced-gpu-arch'],
cost: { researchPoints: 2, compute: 40, ticks: 240 },
cost: { researchPoints: 2, compute: 40, ticks: 600, money: 30000 },
effects: [{ type: 'unlock_rack', target: 'h100', value: 1 }],
},
{
@@ -49,7 +49,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'bigtech',
category: 'infrastructure',
prerequisites: ['next-gen-gpu'],
cost: { researchPoints: 5, compute: 200, ticks: 480 },
cost: { researchPoints: 5, compute: 200, ticks: 1200, money: 240000 },
effects: [{ type: 'unlock_rack', target: 'b200', value: 1 }],
},
{
@@ -59,7 +59,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'agi',
category: 'infrastructure',
prerequisites: ['frontier-compute'],
cost: { researchPoints: 10, compute: 500, ticks: 900 },
cost: { researchPoints: 10, compute: 500, ticks: 2250, money: 1125000 },
effects: [{ type: 'unlock_rack', target: 'custom', value: 1 }],
},
{
@@ -69,7 +69,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'infrastructure',
prerequisites: ['advanced-gpu-arch'],
cost: { researchPoints: 2, compute: 30, ticks: 200 },
cost: { researchPoints: 2, compute: 30, ticks: 500, money: 25000 },
effects: [{ type: 'unlock_rack', target: 'amd', value: 1 }],
},
{
@@ -79,7 +79,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'infrastructure',
prerequisites: ['quantization'],
cost: { researchPoints: 2, compute: 20, ticks: 150 },
cost: { researchPoints: 2, compute: 20, ticks: 375, money: 18750 },
effects: [{ type: 'unlock_rack', target: 'inference', value: 1 }],
},
{
@@ -89,7 +89,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'agi',
category: 'infrastructure',
prerequisites: ['frontier-compute'],
cost: { researchPoints: 8, compute: 400, ticks: 720 },
cost: { researchPoints: 8, compute: 400, ticks: 1800, money: 900000 },
effects: [{ type: 'unlock_rack', target: 'gb200-nvl72', value: 1 }],
},
{
@@ -99,7 +99,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'infrastructure',
prerequisites: ['advanced-cooling'],
cost: { researchPoints: 2, compute: 25, ticks: 180 },
cost: { researchPoints: 2, compute: 25, ticks: 450, money: 22500 },
effects: [{ type: 'unlock_feature', target: 'liquid-cooling', value: 1 }],
},
{
@@ -109,7 +109,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'bigtech',
category: 'infrastructure',
prerequisites: ['liquid-cooling-tech'],
cost: { researchPoints: 5, compute: 100, ticks: 400 },
cost: { researchPoints: 5, compute: 100, ticks: 1000, money: 200000 },
effects: [{ type: 'unlock_feature', target: 'immersion-cooling', value: 1 }],
},
{
@@ -119,7 +119,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'infrastructure',
prerequisites: ['network-engineering-i'],
cost: { researchPoints: 3, compute: 40, ticks: 240 },
cost: { researchPoints: 3, compute: 40, ticks: 600, money: 30000 },
effects: [{ type: 'unlock_feature', target: 'infiniband', value: 1 }],
},
{
@@ -129,7 +129,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'startup',
category: 'infrastructure',
prerequisites: ['advanced-cooling'],
cost: { researchPoints: 1, compute: 15, ticks: 120 },
cost: { researchPoints: 1, compute: 15, ticks: 300, money: 4500 },
effects: [{ type: 'unlock_dc_tier', target: 'medium', value: 1 }],
},
{
@@ -139,7 +139,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'infrastructure',
prerequisites: ['dc-engineering-ii'],
cost: { researchPoints: 3, compute: 60, ticks: 300 },
cost: { researchPoints: 3, compute: 60, ticks: 750, money: 37500 },
effects: [{ type: 'unlock_dc_tier', target: 'large', value: 1 }],
},
{
@@ -149,7 +149,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'bigtech',
category: 'infrastructure',
prerequisites: ['dc-engineering-iii'],
cost: { researchPoints: 6, compute: 150, ticks: 600 },
cost: { researchPoints: 6, compute: 150, ticks: 1500, money: 300000 },
effects: [{ type: 'unlock_dc_tier', target: 'mega', value: 1 }],
},
{
@@ -159,7 +159,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'startup',
category: 'infrastructure',
prerequisites: ['redundancy-protocols'],
cost: { researchPoints: 1, compute: 10, ticks: 90 },
cost: { researchPoints: 1, compute: 10, ticks: 225, money: 3375 },
effects: [{ type: 'cost_reduction', target: 'test_failure_rate', value: 0.25 }],
},
{
@@ -169,7 +169,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'infrastructure',
prerequisites: ['redundancy-protocols'],
cost: { researchPoints: 2, compute: 20, ticks: 150 },
cost: { researchPoints: 2, compute: 20, ticks: 375, money: 18750 },
effects: [{ type: 'cost_reduction', target: 'network_failure_rate', value: 0.4 }],
},
{
@@ -179,7 +179,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'bigtech',
category: 'infrastructure',
prerequisites: ['network-engineering-i'],
cost: { researchPoints: 4, compute: 80, ticks: 360 },
cost: { researchPoints: 4, compute: 80, ticks: 900, money: 180000 },
effects: [{ type: 'cost_reduction', target: 'network_failure_rate', value: 0.5 }],
},
{
@@ -189,7 +189,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'infrastructure',
prerequisites: ['network-engineering-i'],
cost: { researchPoints: 3, compute: 40, ticks: 240 },
cost: { researchPoints: 3, compute: 40, ticks: 600, money: 30000 },
effects: [{ type: 'efficiency_boost', target: 'network_uplinks', value: 1 }],
},
{
@@ -199,7 +199,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'bigtech',
category: 'infrastructure',
prerequisites: ['network-engineering-ii'],
cost: { researchPoints: 5, compute: 100, ticks: 400 },
cost: { researchPoints: 5, compute: 100, ticks: 1000, money: 200000 },
effects: [{ type: 'efficiency_boost', target: 'network_repair_speed', value: 0.4 }],
},
{
@@ -209,7 +209,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'agi',
category: 'infrastructure',
prerequisites: ['network-fast-repair'],
cost: { researchPoints: 8, compute: 250, ticks: 600 },
cost: { researchPoints: 8, compute: 250, ticks: 1500, money: 750000 },
effects: [{ type: 'efficiency_boost', target: 'network_hot_standby', value: 5 }],
},
{
@@ -219,7 +219,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'infrastructure',
prerequisites: ['dc-engineering-ii'],
cost: { researchPoints: 2, compute: 25, ticks: 180 },
cost: { researchPoints: 2, compute: 25, ticks: 450, money: 22500 },
effects: [{ type: 'efficiency_boost', target: 'pipeline_speed', value: 0.2 }],
},
{
@@ -229,7 +229,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'infrastructure',
prerequisites: ['advanced-gpu-arch'],
cost: { researchPoints: 2, compute: 30, ticks: 180 },
cost: { researchPoints: 2, compute: 30, ticks: 450, money: 22500 },
effects: [{ type: 'efficiency_boost', target: 'training_speed', value: 0.2 }],
},
@@ -241,7 +241,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'startup',
category: 'efficiency',
prerequisites: [],
cost: { researchPoints: 0, compute: 8, ticks: 75 },
cost: { researchPoints: 0, compute: 8, ticks: 188, money: 2820 },
effects: [{ type: 'efficiency_boost', target: 'inference', value: 0.15 }],
},
{
@@ -251,7 +251,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'efficiency',
prerequisites: ['quantization'],
cost: { researchPoints: 2, compute: 25, ticks: 180 },
cost: { researchPoints: 2, compute: 25, ticks: 450, money: 22500 },
effects: [{ type: 'capability_boost', target: 'all', value: 5 }],
},
{
@@ -261,7 +261,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'efficiency',
prerequisites: ['quantization'],
cost: { researchPoints: 2, compute: 20, ticks: 150 },
cost: { researchPoints: 2, compute: 20, ticks: 375, money: 18750 },
effects: [{ type: 'efficiency_boost', target: 'tokens_per_flop', value: 0.3 }],
},
@@ -273,7 +273,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'startup',
category: 'generation',
prerequisites: [],
cost: { researchPoints: 0, compute: 10, ticks: 90 },
cost: { researchPoints: 0, compute: 10, ticks: 225, money: 3375 },
effects: [{ type: 'capability_boost', target: 'all', value: 10 }],
},
{
@@ -284,7 +284,7 @@ export const TECH_TREE: ResearchNode[] = [
category: 'specialization',
branch: 'reasoning',
prerequisites: ['transformer-v2'],
cost: { researchPoints: 3, compute: 40, ticks: 240 },
cost: { researchPoints: 3, compute: 40, ticks: 720, money: 36000 },
effects: [{ type: 'capability_boost', target: 'reasoning', value: 15 }],
},
{
@@ -295,7 +295,7 @@ export const TECH_TREE: ResearchNode[] = [
category: 'specialization',
branch: 'coding',
prerequisites: ['transformer-v2'],
cost: { researchPoints: 3, compute: 35, ticks: 210 },
cost: { researchPoints: 3, compute: 35, ticks: 735, money: 36750 },
effects: [{ type: 'capability_boost', target: 'coding', value: 15 }],
},
{
@@ -306,7 +306,7 @@ export const TECH_TREE: ResearchNode[] = [
category: 'specialization',
branch: 'creative',
prerequisites: ['transformer-v2'],
cost: { researchPoints: 3, compute: 30, ticks: 210 },
cost: { researchPoints: 3, compute: 30, ticks: 735, money: 36750 },
effects: [{ type: 'capability_boost', target: 'creative', value: 15 }],
},
{
@@ -317,7 +317,7 @@ export const TECH_TREE: ResearchNode[] = [
category: 'specialization',
branch: 'multimodal',
prerequisites: ['transformer-v2'],
cost: { researchPoints: 4, compute: 50, ticks: 300 },
cost: { researchPoints: 4, compute: 50, ticks: 1050, money: 52500 },
effects: [
{ type: 'capability_boost', target: 'multimodal', value: 20 },
{ type: 'unlock_product_line', target: 'image', value: 1 },
@@ -331,7 +331,7 @@ export const TECH_TREE: ResearchNode[] = [
category: 'specialization',
branch: 'agents',
prerequisites: ['reasoning-enhancement', 'code-generation'],
cost: { researchPoints: 6, compute: 100, ticks: 480 },
cost: { researchPoints: 6, compute: 100, ticks: 1680, money: 336000 },
effects: [
{ type: 'capability_boost', target: 'agents', value: 20 },
{ type: 'unlock_product_line', target: 'agents', value: 1 },
@@ -346,7 +346,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'startup',
category: 'safety',
prerequisites: [],
cost: { researchPoints: 0, compute: 8, ticks: 90 },
cost: { researchPoints: 0, compute: 8, ticks: 270, money: 4050 },
effects: [
{ type: 'safety_boost', target: 'models', value: 10 },
{ type: 'capability_boost', target: 'reputation', value: 5 },
@@ -359,7 +359,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'safety',
prerequisites: ['alignment-research'],
cost: { researchPoints: 3, compute: 40, ticks: 240 },
cost: { researchPoints: 3, compute: 40, ticks: 720, money: 36000 },
effects: [
{ type: 'safety_boost', target: 'models', value: 10 },
{ type: 'capability_boost', target: 'reputation', value: 5 },
@@ -372,7 +372,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'bigtech',
category: 'safety',
prerequisites: ['interpretability'],
cost: { researchPoints: 5, compute: 80, ticks: 420 },
cost: { researchPoints: 5, compute: 80, ticks: 1260, money: 252000 },
effects: [
{ type: 'safety_boost', target: 'models', value: 15 },
{ type: 'capability_boost', target: 'reputation', value: 10 },
@@ -388,7 +388,7 @@ export const TECH_TREE: ResearchNode[] = [
category: 'specialization',
branch: 'coding',
prerequisites: ['code-generation'],
cost: { researchPoints: 2, compute: 20, ticks: 150 },
cost: { researchPoints: 2, compute: 20, ticks: 525, money: 26250 },
effects: [{ type: 'unlock_product_line', target: 'code-assistant', value: 1 }],
},
{
@@ -398,7 +398,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'startup',
category: 'efficiency',
prerequisites: [],
cost: { researchPoints: 0, compute: 3, ticks: 45 },
cost: { researchPoints: 0, compute: 3, ticks: 158, money: 2370 },
effects: [{ type: 'unlock_feature', target: 'developer-relations', value: 1 }],
},
{
@@ -408,7 +408,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'startup',
category: 'efficiency',
prerequisites: [],
cost: { researchPoints: 0, compute: 3, ticks: 45 },
cost: { researchPoints: 0, compute: 3, ticks: 112, money: 1680 },
effects: [{ type: 'unlock_feature', target: 'enterprise-sales', value: 1 }],
},
{
@@ -418,7 +418,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'efficiency',
prerequisites: ['developer-relations'],
cost: { researchPoints: 2, compute: 15, ticks: 120 },
cost: { researchPoints: 2, compute: 15, ticks: 300, money: 15000 },
effects: [{ type: 'efficiency_boost', target: 'sdk_coverage', value: 0.3 }],
},
{
@@ -429,7 +429,7 @@ export const TECH_TREE: ResearchNode[] = [
category: 'specialization',
branch: 'agents',
prerequisites: ['agentic-architecture'],
cost: { researchPoints: 4, compute: 60, ticks: 300 },
cost: { researchPoints: 4, compute: 60, ticks: 1050, money: 210000 },
effects: [{ type: 'unlock_product_line', target: 'agents-platform', value: 1 }],
},
@@ -441,7 +441,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'efficiency',
prerequisites: ['inference-optimization'],
cost: { researchPoints: 2, compute: 25, ticks: 150 },
cost: { researchPoints: 2, compute: 25, ticks: 375, money: 18750 },
effects: [{ type: 'unlock_feature', target: 'request-routing', value: 1 }],
},
{
@@ -451,7 +451,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'efficiency',
prerequisites: ['request-routing'],
cost: { researchPoints: 3, compute: 30, ticks: 180 },
cost: { researchPoints: 3, compute: 30, ticks: 450, money: 22500 },
effects: [{ type: 'unlock_feature', target: 'priority-queues', value: 1 }],
},
{
@@ -461,7 +461,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'scaleup',
category: 'efficiency',
prerequisites: ['inference-optimization'],
cost: { researchPoints: 2, compute: 20, ticks: 120 },
cost: { researchPoints: 2, compute: 20, ticks: 300, money: 15000 },
effects: [{ type: 'unlock_feature', target: 'request-batching', value: 1 }],
},
{
@@ -471,7 +471,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'bigtech',
category: 'efficiency',
prerequisites: ['request-routing'],
cost: { researchPoints: 4, compute: 60, ticks: 300 },
cost: { researchPoints: 4, compute: 60, ticks: 750, money: 150000 },
effects: [{ type: 'efficiency_boost', target: 'auto_scaling', value: 0.2 }],
},
@@ -483,7 +483,7 @@ export const TECH_TREE: ResearchNode[] = [
era: 'startup',
category: 'efficiency',
prerequisites: [],
cost: { researchPoints: 0, compute: 5, ticks: 60 },
cost: { researchPoints: 0, compute: 5, ticks: 150, money: 2250 },
effects: [{ type: 'efficiency_boost', target: 'data_quality', value: 0.2 }],
},
];
@@ -1,5 +1,6 @@
import type { GameState, EconomyState, InfrastructureState } from '@ai-tycoon/shared';
import { FINANCIAL_SNAPSHOT_INTERVAL, MAX_FINANCIAL_HISTORY, REGULATION_COMPLIANCE_PER_CAPABILITY } from '@ai-tycoon/shared';
import { TECH_TREE } from '../data/techTree';
import type { MarketTickResult } from './marketSystem';
export function processEconomy(
@@ -27,7 +28,16 @@ export function processEconomy(
const complianceCost = bestCapability > 30 ? bestCapability * REGULATION_COMPLIANCE_PER_CAPABILITY * (1 + eraIdx * 0.5) / 100 : 0;
const devRelExpenses = state.market.developerEcosystem.devRelSpending;
const expenses = infraExpenses + talentExpenses + dataExpenses + complianceCost + devRelExpenses + extraCosts;
let researchExpenses = 0;
if (state.research.activeResearch) {
const node = TECH_TREE.find(n => n.id === state.research.activeResearch!.researchId);
if (node) {
researchExpenses = node.cost.money / node.cost.ticks;
}
}
const expenses = infraExpenses + talentExpenses + dataExpenses + complianceCost + devRelExpenses + researchExpenses + extraCosts;
const money = state.economy.money + revenue - expenses;
@@ -30,6 +30,7 @@ function promoteFromQueue(
totalTicks: node.cost.ticks,
allocatedResearchers: state.talent.departments.research.headcount,
allocatedCompute: node.cost.compute,
moneySpent: 0,
};
return {
@@ -52,6 +53,10 @@ export function processResearch(state: GameState, compute: ComputeState): Resear
const newProgress = active.progressTicks + speedMultiplier;
const node = TECH_TREE.find(n => n.id === active.researchId);
const moneyPerTick = node ? node.cost.money / node.cost.ticks : 0;
const newMoneySpent = (active.moneySpent ?? 0) + moneyPerTick;
if (newProgress >= active.totalTicks) {
const completedResearch = {
...state.research,
@@ -72,7 +77,7 @@ export function processResearch(state: GameState, compute: ComputeState): Resear
return {
research: {
...state.research,
activeResearch: { ...active, progressTicks: newProgress },
activeResearch: { ...active, progressTicks: newProgress, moneySpent: newMoneySpent },
},
researchCompleted: null,
};
@@ -53,8 +53,9 @@ describe('processTalent', () => {
expect(result.totalSalaryPerTick).toBe(70);
});
it('adds 1% of department budget per tick', () => {
it('adds 1% of department budget per tick scaled by era', () => {
const state = createTestState({
meta: { currentEra: 'bigtech' },
talent: {
departments: {
research: { id: 'research', headcount: 0, budget: 10_000, effectiveness: 0.5, morale: 0.8 },
@@ -66,10 +67,28 @@ describe('processTalent', () => {
},
});
const result = processTalent(state);
// 10000 * 0.01 + 5000 * 0.01 = 100 + 50 = 150
// bigtech multiplier = 1.0: 10000 * 0.01 + 5000 * 0.01 = 150
expect(result.totalSalaryPerTick).toBe(150);
});
it('applies startup era discount to budget costs', () => {
const state = createTestState({
meta: { currentEra: 'startup' },
talent: {
departments: {
research: { id: 'research', headcount: 0, budget: 10_000, effectiveness: 0.5, morale: 0.8 },
engineering: { id: 'engineering', headcount: 0, budget: 5_000, effectiveness: 0.5, morale: 0.8 },
operations: { id: 'operations', headcount: 0, budget: 0, effectiveness: 0.5, morale: 0.8 },
sales: { id: 'sales', headcount: 0, budget: 0, effectiveness: 0.5, morale: 0.8 },
},
keyHires: [],
},
});
const result = processTalent(state);
// startup multiplier = 0.2: (10000 + 5000) * 0.01 * 0.2 = 30
expect(result.totalSalaryPerTick).toBe(30);
});
it('adds key hire salaries to total', () => {
const state = createTestState({
talent: {
@@ -110,6 +129,7 @@ describe('processTalent', () => {
it('combines headcount salary, budget cost, and key hire salary', () => {
const state = createTestState({
meta: { currentEra: 'bigtech' },
talent: {
departments: {
research: { id: 'research', headcount: 4, budget: 2_000, effectiveness: 0.5, morale: 0.8 },
@@ -133,7 +153,7 @@ describe('processTalent', () => {
});
const result = processTalent(state);
// headcount: (4 + 6) * 5 = 50
// budget: 2000 * 0.01 + 3000 * 0.01 = 20 + 30 = 50
// budget (bigtech 1.0x): 2000 * 0.01 + 3000 * 0.01 = 50
// key hires: 15
// total = 50 + 50 + 15 = 115
expect(result.totalSalaryPerTick).toBe(115);
@@ -1,14 +1,16 @@
import type { GameState, TalentState } from '@ai-tycoon/shared';
import { ERA_BUDGET_COST_MULTIPLIER } from '@ai-tycoon/shared';
const SALARY_PER_HEADCOUNT_PER_TICK = 5;
export function processTalent(state: GameState): TalentState {
const departments = { ...state.talent.departments };
const budgetMultiplier = ERA_BUDGET_COST_MULTIPLIER[state.meta.currentEra] ?? 1.0;
let totalSalary = 0;
for (const [id, dept] of Object.entries(departments)) {
totalSalary += dept.headcount * SALARY_PER_HEADCOUNT_PER_TICK;
totalSalary += dept.budget * 0.01;
totalSalary += dept.budget * 0.01 * budgetMultiplier;
}
for (const hire of state.talent.keyHires) {