Add Week 2 depth systems: research, events, competitors, talent, data
Tech tree with 21 research nodes across 5 categories (infrastructure, efficiency, generation, specialization, safety). Research page with category-grouped cards, progress tracking, prerequisite gating. Event engine with 34 events across industry/regulatory/PR/internal/market categories, weighted random firing, cooldowns, expiry, and choice modal with consequence preview. Events auto-expire with default choice. Competitor system with 3 rival AI labs (Prometheus AI, Nexus Labs, Titan Computing), personality-driven milestone progression, and comparison UI. Talent page with department hiring, headcount management, and key hire recruitment from a pool of 10 named characters with special abilities. Data marketplace with 8 purchasable datasets, user data flywheel from subscribers, and data system processing in tick loop. Era transition system checks revenue/capability/reputation thresholds. All new systems integrated into tick processor with notifications. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import type { GameState, CompetitorState } from '@ai-tycoon/shared';
|
||||
|
||||
export function processCompetitors(state: GameState): CompetitorState {
|
||||
const tick = state.meta.tickCount;
|
||||
const rivals = state.competitors.rivals.map(rival => {
|
||||
if (rival.status !== 'active') return rival;
|
||||
|
||||
if (tick < rival.nextMilestoneAtTick) return rival;
|
||||
|
||||
const { personality } = rival;
|
||||
const capGrowth = (2 + personality.researchFocus * 5 + personality.riskTolerance * 3) *
|
||||
(1 + tick * 0.00005);
|
||||
const revenueGrowth = rival.estimatedRevenue * (0.02 + personality.marketingFocus * 0.03);
|
||||
const userGrowth = rival.estimatedUsers * (0.01 + personality.marketingFocus * 0.02);
|
||||
|
||||
const newCapability = Math.min(95, rival.estimatedCapability + capGrowth);
|
||||
const newRevenue = rival.estimatedRevenue + revenueGrowth + 50;
|
||||
const newUsers = rival.estimatedUsers + userGrowth + 100;
|
||||
|
||||
const repChange = personality.safetyFocus > 0.6
|
||||
? 1
|
||||
: personality.riskTolerance > 0.7 ? -1 : 0;
|
||||
|
||||
const modelNames = [
|
||||
'Alpha', 'Beta', 'Gamma', 'Delta', 'Epsilon',
|
||||
'Nova', 'Quantum', 'Nexus', 'Apex', 'Zenith',
|
||||
];
|
||||
const modelIdx = Math.floor(newCapability / 10);
|
||||
const latestModelName = `${rival.name.split(' ')[0]}-${modelNames[Math.min(modelIdx, modelNames.length - 1)]}`;
|
||||
|
||||
const milestoneInterval = 200 + Math.floor(Math.random() * 200);
|
||||
|
||||
return {
|
||||
...rival,
|
||||
estimatedCapability: newCapability,
|
||||
estimatedRevenue: newRevenue,
|
||||
estimatedUsers: Math.floor(newUsers),
|
||||
reputation: Math.min(100, Math.max(0, rival.reputation + repChange)),
|
||||
latestModelName,
|
||||
nextMilestoneAtTick: tick + milestoneInterval,
|
||||
};
|
||||
});
|
||||
|
||||
const allCaps = [
|
||||
...rivals.filter(r => r.status === 'active').map(r => r.estimatedCapability),
|
||||
state.models.trainedModels.reduce((best, m) => Math.max(best, m.benchmarkScore), 0),
|
||||
];
|
||||
const industryBenchmark = allCaps.length > 0 ? Math.max(...allCaps) : 0;
|
||||
|
||||
return { rivals, industryBenchmark };
|
||||
}
|
||||
Reference in New Issue
Block a user