Overhaul market system with shared TAM competition, multi-tier pricing, enterprise pipeline, and developer ecosystem
CI / build-and-push (push) Successful in 42s
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:
@@ -0,0 +1,106 @@
|
||||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import { useGameStore } from '@/store';
|
||||
import { formatNumber, formatMoney, formatPercent } from '@ai-tycoon/shared';
|
||||
import { Boxes, Check } from 'lucide-react';
|
||||
|
||||
function useAppliedFeedback() {
|
||||
const [show, setShow] = useState(false);
|
||||
const timerRef = useRef<ReturnType<typeof setTimeout>>(undefined);
|
||||
const trigger = useCallback(() => {
|
||||
setShow(true);
|
||||
clearTimeout(timerRef.current);
|
||||
timerRef.current = setTimeout(() => setShow(false), 1200);
|
||||
}, []);
|
||||
useEffect(() => () => clearTimeout(timerRef.current), []);
|
||||
return { show, trigger };
|
||||
}
|
||||
|
||||
export function DeveloperEcosystemPanel() {
|
||||
const devEco = useGameStore((s) => s.market.developerEcosystem);
|
||||
const setDevRelSpending = useGameStore((s) => s.setDevRelSpending);
|
||||
const feedback = useAppliedFeedback();
|
||||
|
||||
const metrics = [
|
||||
{ label: 'Community Size', value: formatNumber(devEco.communitySize), sub: `Growth: ${devEco.communityGrowthRate.toFixed(2)}/t` },
|
||||
{ label: 'Active Developers', value: formatNumber(devEco.activeDevelopers), sub: `${devEco.communitySize > 0 ? formatPercent(devEco.activeDevelopers / devEco.communitySize) : '0%'} active` },
|
||||
{ label: 'SDK Coverage', value: formatPercent(devEco.sdkCoverage), sub: 'Hire engineers to improve' },
|
||||
{ label: 'Doc Quality', value: formatPercent(devEco.documentationQuality), sub: 'Increase dev-rel spending' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<Boxes size={16} className="text-green-400" />
|
||||
<span className="text-sm font-semibold">Developer Ecosystem</span>
|
||||
</div>
|
||||
<div className="text-xs text-surface-400">
|
||||
Ecosystem Score: <span className="font-mono text-surface-200 text-sm">{devEco.ecosystemScore.toFixed(1)}</span>/100
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-4 gap-3">
|
||||
{metrics.map(m => (
|
||||
<div key={m.label} className="bg-surface-900 border border-surface-700 rounded-xl p-3">
|
||||
<div className="text-[10px] text-surface-400 uppercase mb-1">{m.label}</div>
|
||||
<div className="text-lg font-bold font-mono">{m.value}</div>
|
||||
<div className="text-[10px] text-surface-500 mt-0.5">{m.sub}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="bg-surface-900 border border-surface-700 rounded-xl p-4">
|
||||
<h4 className="text-sm font-semibold mb-3">Flywheel Effects</h4>
|
||||
<div className="space-y-2 text-xs">
|
||||
<div className="flex justify-between text-surface-300">
|
||||
<span>Startups using your API</span>
|
||||
<span className="font-mono">{formatNumber(devEco.startupsAdopted)}</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-surface-300">
|
||||
<span>Enterprise referrals generated</span>
|
||||
<span className="font-mono">{formatNumber(devEco.enterpriseReferrals)}</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-surface-300">
|
||||
<span>Open-source contributions</span>
|
||||
<span className="font-mono">{devEco.openSourceContributions}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3 p-2 bg-surface-800 rounded text-[10px] text-surface-400">
|
||||
Free tier generosity attracts devs, who build startups on your API, which generates enterprise referrals.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-surface-900 border border-surface-700 rounded-xl p-4">
|
||||
<h4 className="text-sm font-semibold mb-3">
|
||||
Dev-Rel Budget
|
||||
{feedback.show && <span className="inline-flex items-center gap-0.5 text-success ml-2 animate-pulse text-[10px]"><Check size={8} /> Applied</span>}
|
||||
</h4>
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<label className="block text-xs text-surface-400 mb-1">Spending ($/tick)</label>
|
||||
<input
|
||||
type="number"
|
||||
value={devEco.devRelSpending}
|
||||
onChange={(e) => { setDevRelSpending(Number(e.target.value)); feedback.trigger(); }}
|
||||
className="w-full bg-surface-800 border border-surface-600 rounded px-3 py-1.5 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-accent/50"
|
||||
min={0}
|
||||
step={0.1}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-[10px] text-surface-500 space-y-1">
|
||||
<p>Dev-rel spending improves documentation quality and community engagement.</p>
|
||||
<p>Current cost: <span className="font-mono text-surface-300">{formatMoney(devEco.devRelSpending)}/s</span></p>
|
||||
</div>
|
||||
<div className="h-1.5 bg-surface-800 rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full rounded-full bg-green-500"
|
||||
style={{ width: `${Math.min(100, devEco.ecosystemScore)}%` }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user