Files
AIHostingTycoon/packages/game-engine/src/systems/fundingSystem.ts
T
josh 09a5cb69a7
CI / build-and-push (push) Successful in 42s
Overhaul market system with shared TAM competition, multi-tier pricing, enterprise pipeline, and developer ecosystem
Replaces the simplified single-subscriber market with a full competitive simulation:
shared TAM with softmax market shares across 4 segments, multi-tier consumer
subscriptions (Free/Plus/Pro/Team) and API tiers (Free/PAYG/Scale/Enterprise),
enterprise sales pipeline (Lead→Qualification→POC→Negotiation→Active→Renewal)
with SLA tracking, developer ecosystem flywheel, technology obsolescence pressure,
seasonal demand cycles, and two new product lines (Code Assistant, AI Agents Platform).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-25 08:30:24 -04:00

41 lines
1.8 KiB
TypeScript

import type { GameState, FundingState, FundingRoundType } from '@ai-tycoon/shared';
import { FUNDING_ROUNDS } from '@ai-tycoon/shared';
const ROUND_ORDER: FundingRoundType[] = ['seed', 'seriesA', 'seriesB', 'seriesC', 'seriesD', 'ipo'];
export function getNextFundingRound(funding: FundingState): FundingRoundType | null {
if (funding.isPublic) return null;
const completedTypes = new Set(funding.completedRounds.map(r => r.type));
for (const type of ROUND_ORDER) {
if (!completedTypes.has(type)) return type;
}
return null;
}
export function canRaiseFunding(state: GameState): { canRaise: boolean; nextRound: FundingRoundType | null; reason?: string } {
const nextRound = getNextFundingRound(state.economy.funding);
if (!nextRound) return { canRaise: false, nextRound: null, reason: 'No more funding rounds available' };
const config = FUNDING_ROUNDS[nextRound];
const reqs = config.requirements;
if (reqs.minRevenue && state.economy.totalRevenue < reqs.minRevenue) {
return { canRaise: false, nextRound, reason: `Need $${reqs.minRevenue.toLocaleString()} total revenue` };
}
if (reqs.minUsers && state.market.consumerTiers.totalUsers < reqs.minUsers) {
return { canRaise: false, nextRound, reason: `Need ${reqs.minUsers.toLocaleString()} subscribers` };
}
if (reqs.minReputation && state.reputation.score < reqs.minReputation) {
return { canRaise: false, nextRound, reason: `Need ${reqs.minReputation} reputation` };
}
return { canRaise: true, nextRound };
}
export function computeValuation(state: GameState): number {
const revenueMultiple = state.economy.revenuePerTick * 86400 * 365;
const subscriberValue = state.market.consumerTiers.totalUsers * 500;
const capabilityValue = Math.pow(state.models.bestDeployedModelScore, 2) * 1000;
return Math.max(100_000, revenueMultiple * 10 + subscriberValue + capabilityValue);
}