Overhaul market system with shared TAM competition, multi-tier pricing, enterprise pipeline, and developer ecosystem
CI / build-and-push (push) Successful in 42s

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>
This commit is contained in:
2026-04-25 08:30:24 -04:00
parent 4c1c0e9ff2
commit 09a5cb69a7
34 changed files with 2851 additions and 408 deletions
@@ -0,0 +1,69 @@
import type { DeveloperEcosystem } from '@ai-tycoon/shared';
import {
BASE_DEV_GROWTH,
FREE_TIER_DEV_MULTIPLIER,
OPEN_SOURCE_DEV_BOOST,
DEV_REL_EFFECTIVENESS,
SDK_GROWTH_BONUS,
DEV_ECOSYSTEM_WEIGHTS,
STARTUP_ADOPTION_PER_DEV,
ENTERPRISE_REFERRAL_PER_STARTUP,
TAM_BASE_SIZES,
} from '@ai-tycoon/shared';
import type { Era } from '@ai-tycoon/shared';
export function processDeveloperEcosystem(
eco: DeveloperEcosystem,
openSourceCount: number,
apiFreeTierDevs: number,
apiTotalDevs: number,
engineeringHeadcount: number,
era: Era,
): DeveloperEcosystem {
const updated = { ...eco };
const growthRate =
BASE_DEV_GROWTH +
apiFreeTierDevs * FREE_TIER_DEV_MULTIPLIER +
openSourceCount * OPEN_SOURCE_DEV_BOOST +
updated.devRelSpending * DEV_REL_EFFECTIVENESS +
updated.sdkCoverage * SDK_GROWTH_BONUS;
updated.communityGrowthRate = growthRate;
updated.communitySize = Math.max(0, updated.communitySize + updated.communitySize * growthRate);
if (updated.communitySize < 10 && apiTotalDevs > 0) {
updated.communitySize += 1 + apiTotalDevs * 0.1;
}
updated.activeDevelopers = apiTotalDevs;
updated.openSourceContributions = openSourceCount;
const sdkTarget = Math.min(1, engineeringHeadcount / 50);
updated.sdkCoverage += (sdkTarget - updated.sdkCoverage) * 0.005;
updated.sdkCoverage = Math.min(1, Math.max(0, updated.sdkCoverage));
const docTarget = Math.min(1, updated.devRelSpending / 500);
updated.documentationQuality += (docTarget - updated.documentationQuality) * 0.003;
updated.documentationQuality = Math.min(1, Math.max(0, updated.documentationQuality));
const eraCap = TAM_BASE_SIZES[era].developer;
const communityNorm = Math.min(1, updated.communitySize / Math.max(1, eraCap * 0.1));
const activeRatio = updated.communitySize > 0
? Math.min(1, updated.activeDevelopers / updated.communitySize)
: 0;
const osNorm = Math.min(1, openSourceCount / 5);
updated.ecosystemScore = (
DEV_ECOSYSTEM_WEIGHTS.communitySize * communityNorm +
DEV_ECOSYSTEM_WEIGHTS.activeRatio * activeRatio +
DEV_ECOSYSTEM_WEIGHTS.sdkCoverage * updated.sdkCoverage +
DEV_ECOSYSTEM_WEIGHTS.docQuality * updated.documentationQuality +
DEV_ECOSYSTEM_WEIGHTS.openSource * osNorm
) * 100;
updated.startupsAdopted = Math.floor(updated.activeDevelopers * STARTUP_ADOPTION_PER_DEV);
updated.enterpriseReferrals = Math.floor(updated.startupsAdopted * ENTERPRISE_REFERRAL_PER_STARTUP);
return updated;
}