Redesign infrastructure to hypercluster scale with 4-level hierarchy
CI / build-and-push (push) Successful in 43s
CI / build-and-push (push) Successful in 43s
Replace flat DataCenter/Rack model with Cluster > Campus > Data Center > Racks hierarchy. Individual rack entities eliminated in favor of statistical batch simulation using deployment cohorts. Adds tiered network topology (ToR/agg/core) with proportional outage model, DC retrofitting, bulk operations, and drill-down UI navigation with breadcrumbs. First cluster and campus are free to preserve early game flow. Rebalances starting economy ($600K), funding rounds, and cohort scaling for hypercluster-scale gameplay. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { DCTier, DCTierConfig, RackSkuId, RackSkuConfig } from '../types/infrastructure';
|
||||
import type { DCTier, DCTierConfig, RackSkuId, RackSkuConfig, NetworkTopologyConfig, CampusTierCost, ClusterCostConfig } from '../types/infrastructure';
|
||||
|
||||
export const TICK_INTERVAL_MS = 1000;
|
||||
export const MAX_OFFLINE_TICKS = 86_400;
|
||||
@@ -9,7 +9,7 @@ export const FINANCIAL_SNAPSHOT_INTERVAL = 60;
|
||||
export const MAX_FINANCIAL_HISTORY = 1000;
|
||||
export const MAX_REPUTATION_HISTORY = 500;
|
||||
|
||||
export const STARTING_MONEY = 50_000;
|
||||
export const STARTING_MONEY = 600_000;
|
||||
export const BASE_ENERGY_COST_PER_FLOP = 0.001;
|
||||
|
||||
export const TRAINING_BASE_TICKS = 120;
|
||||
@@ -58,53 +58,84 @@ export const DC_TIER_CONFIGS: Record<DCTier, DCTierConfig> = {
|
||||
small: {
|
||||
tier: 'small',
|
||||
name: 'Small Data Center',
|
||||
rackSlots: 12,
|
||||
powerBudgetKW: 60,
|
||||
baseCost: 10_000,
|
||||
buildTimeTicks: 300,
|
||||
firstBuildTimeTicks: 10,
|
||||
rackSlots: 200,
|
||||
powerBudgetKW: 1_000,
|
||||
baseCost: 500_000,
|
||||
buildTimeTicks: 600,
|
||||
firstBuildTimeTicks: 30,
|
||||
requiredEra: 'startup',
|
||||
requiredResearch: null,
|
||||
baseEnergyCostPerTick: 5,
|
||||
baseEnergyCostPerTick: 50,
|
||||
},
|
||||
medium: {
|
||||
tier: 'medium',
|
||||
name: 'Medium Data Center',
|
||||
rackSlots: 30,
|
||||
powerBudgetKW: 200,
|
||||
baseCost: 50_000,
|
||||
buildTimeTicks: 900,
|
||||
firstBuildTimeTicks: 900,
|
||||
rackSlots: 500,
|
||||
powerBudgetKW: 3_000,
|
||||
baseCost: 2_000_000,
|
||||
buildTimeTicks: 1200,
|
||||
firstBuildTimeTicks: 1200,
|
||||
requiredEra: 'scaleup',
|
||||
requiredResearch: 'dc-engineering-ii',
|
||||
baseEnergyCostPerTick: 15,
|
||||
baseEnergyCostPerTick: 150,
|
||||
},
|
||||
large: {
|
||||
tier: 'large',
|
||||
name: 'Large Data Center',
|
||||
rackSlots: 60,
|
||||
powerBudgetKW: 500,
|
||||
baseCost: 200_000,
|
||||
buildTimeTicks: 1800,
|
||||
firstBuildTimeTicks: 1800,
|
||||
rackSlots: 1000,
|
||||
powerBudgetKW: 7_000,
|
||||
baseCost: 8_000_000,
|
||||
buildTimeTicks: 2400,
|
||||
firstBuildTimeTicks: 2400,
|
||||
requiredEra: 'bigtech',
|
||||
requiredResearch: 'dc-engineering-iii',
|
||||
baseEnergyCostPerTick: 40,
|
||||
baseEnergyCostPerTick: 400,
|
||||
},
|
||||
mega: {
|
||||
tier: 'mega',
|
||||
name: 'Mega Data Center',
|
||||
rackSlots: 120,
|
||||
powerBudgetKW: 1200,
|
||||
baseCost: 1_000_000,
|
||||
rackSlots: 1500,
|
||||
powerBudgetKW: 12_000,
|
||||
baseCost: 25_000_000,
|
||||
buildTimeTicks: 3600,
|
||||
firstBuildTimeTicks: 3600,
|
||||
requiredEra: 'agi',
|
||||
requiredResearch: 'dc-engineering-iv',
|
||||
baseEnergyCostPerTick: 100,
|
||||
baseEnergyCostPerTick: 1000,
|
||||
},
|
||||
};
|
||||
|
||||
// --- Campus Costs (scale with DC tier) ---
|
||||
|
||||
export const CAMPUS_TIER_COSTS: Record<DCTier, CampusTierCost> = {
|
||||
small: { baseCost: 200_000, buildTimeTicks: 300 },
|
||||
medium: { baseCost: 800_000, buildTimeTicks: 600 },
|
||||
large: { baseCost: 3_000_000, buildTimeTicks: 900 },
|
||||
mega: { baseCost: 10_000_000, buildTimeTicks: 1200 },
|
||||
};
|
||||
|
||||
export const FIRST_CAMPUS_BUILD_TICKS = 15;
|
||||
|
||||
// --- Cluster Costs (first is free) ---
|
||||
|
||||
export const CLUSTER_COST_CONFIG: ClusterCostConfig = {
|
||||
baseCost: 250_000,
|
||||
buildTimeTicks: 600,
|
||||
};
|
||||
|
||||
// --- Network Topology ---
|
||||
|
||||
export const NETWORK_TOPOLOGY: NetworkTopologyConfig = {
|
||||
tier1PerCompute: 24,
|
||||
tier2PerTier1: 6,
|
||||
tier3PerDC: 2,
|
||||
tier1FailureRate: 0.0001,
|
||||
tier2FailureRate: 0.00005,
|
||||
tier3FailureRate: 0.00002,
|
||||
tier1BlastRadius: 24,
|
||||
tier2BlastRadiusMultiplier: 6,
|
||||
};
|
||||
|
||||
// --- Rack SKU Configs ---
|
||||
|
||||
export const RACK_SKU_CONFIGS: Record<RackSkuId, RackSkuConfig> = {
|
||||
@@ -260,13 +291,15 @@ export const REDUNDANCY_FAILURE_REDUCTION = 0.5;
|
||||
export const DC_UPGRADE_COST_FRACTION = 0.25;
|
||||
export const DC_UPGRADE_INCREMENT = 0.1;
|
||||
|
||||
export const COHORT_SCALE_FACTOR = 0.0003;
|
||||
|
||||
export const FUNDING_ROUNDS = {
|
||||
seed: { amount: 100_000, dilution: 0.10, requirements: { minRevenue: 100, minUsers: 0, minReputation: 0 } },
|
||||
seriesA: { amount: 500_000, dilution: 0.15, requirements: { minRevenue: 500, minUsers: 100, minReputation: 20 } },
|
||||
seriesB: { amount: 2_000_000, dilution: 0.12, requirements: { minRevenue: 5_000, minUsers: 1_000, minReputation: 30 } },
|
||||
seriesC: { amount: 10_000_000, dilution: 0.10, requirements: { minRevenue: 50_000, minUsers: 10_000, minReputation: 40 } },
|
||||
seriesD: { amount: 50_000_000, dilution: 0.08, requirements: { minRevenue: 500_000, minUsers: 50_000, minReputation: 50 } },
|
||||
ipo: { amount: 200_000_000, dilution: 0.20, requirements: { minRevenue: 5_000_000, minUsers: 100_000, minReputation: 60 } },
|
||||
seed: { amount: 500_000, dilution: 0.10, requirements: { minRevenue: 500, minUsers: 0, minReputation: 0 } },
|
||||
seriesA: { amount: 2_000_000, dilution: 0.15, requirements: { minRevenue: 2_500, minUsers: 100, minReputation: 20 } },
|
||||
seriesB: { amount: 10_000_000, dilution: 0.12, requirements: { minRevenue: 25_000, minUsers: 1_000, minReputation: 30 } },
|
||||
seriesC: { amount: 50_000_000, dilution: 0.10, requirements: { minRevenue: 250_000, minUsers: 10_000, minReputation: 40 } },
|
||||
seriesD: { amount: 200_000_000, dilution: 0.08, requirements: { minRevenue: 2_500_000, minUsers: 50_000, minReputation: 50 } },
|
||||
ipo: { amount: 1_000_000_000, dilution: 0.20, requirements: { minRevenue: 25_000_000, minUsers: 100_000, minReputation: 60 } },
|
||||
} as const;
|
||||
|
||||
export const OPEN_SOURCE_REPUTATION_BOOST = 8;
|
||||
|
||||
@@ -46,7 +46,7 @@ export interface FinancialSnapshot {
|
||||
}
|
||||
|
||||
export const INITIAL_ECONOMY: EconomyState = {
|
||||
money: 50_000,
|
||||
money: 600_000,
|
||||
totalRevenue: 0,
|
||||
totalExpenses: 0,
|
||||
revenuePerTick: 0,
|
||||
@@ -56,7 +56,7 @@ export const INITIAL_ECONOMY: EconomyState = {
|
||||
currentRound: null,
|
||||
completedRounds: [],
|
||||
founderEquity: 1.0,
|
||||
valuation: 100_000,
|
||||
valuation: 1_000_000,
|
||||
isPublic: false,
|
||||
},
|
||||
financialHistory: [],
|
||||
|
||||
@@ -58,4 +58,4 @@ export const INITIAL_SETTINGS: GameSettings = {
|
||||
sfxVolume: 0.7,
|
||||
};
|
||||
|
||||
export const SAVE_VERSION = 2;
|
||||
export const SAVE_VERSION = 3;
|
||||
|
||||
@@ -1,9 +1,38 @@
|
||||
import type { Era } from './gameState';
|
||||
|
||||
// --- Cluster (regional container) ---
|
||||
|
||||
export type ClusterStatus = 'constructing' | 'operational';
|
||||
|
||||
export interface Cluster {
|
||||
id: string;
|
||||
name: string;
|
||||
locationId: LocationId;
|
||||
campuses: Campus[];
|
||||
status: ClusterStatus;
|
||||
constructionProgress: number;
|
||||
constructionTotal: number;
|
||||
}
|
||||
|
||||
// --- Campus (holds same-tier DCs) ---
|
||||
|
||||
export type CampusStatus = 'constructing' | 'operational';
|
||||
|
||||
export interface Campus {
|
||||
id: string;
|
||||
name: string;
|
||||
clusterId: string;
|
||||
dcTier: DCTier;
|
||||
dataCenters: DataCenter[];
|
||||
status: CampusStatus;
|
||||
constructionProgress: number;
|
||||
constructionTotal: number;
|
||||
}
|
||||
|
||||
// --- Data Center ---
|
||||
|
||||
export type DCTier = 'small' | 'medium' | 'large' | 'mega';
|
||||
export type DCStatus = 'constructing' | 'operational';
|
||||
export type DCStatus = 'constructing' | 'operational' | 'retrofitting';
|
||||
|
||||
export interface DCTierConfig {
|
||||
tier: DCTier;
|
||||
@@ -21,19 +50,71 @@ export interface DCTierConfig {
|
||||
export interface DataCenter {
|
||||
id: string;
|
||||
name: string;
|
||||
location: LocationId;
|
||||
campusId: string;
|
||||
tier: DCTier;
|
||||
status: DCStatus;
|
||||
constructionProgress: number;
|
||||
constructionTotal: number;
|
||||
racks: Rack[];
|
||||
rackSkuId: RackSkuId | null;
|
||||
computeRacksOnline: number;
|
||||
computeRacksFailed: number;
|
||||
networkHealth: NetworkHealthState;
|
||||
deploymentCohorts: DeploymentCohort[];
|
||||
retrofitState: RetrofitState | null;
|
||||
coolingLevel: number;
|
||||
redundancyLevel: number;
|
||||
currentUptime: number;
|
||||
energyCostPerTick: number;
|
||||
maintenanceCostPerTick: number;
|
||||
effectiveComputeRacks: number;
|
||||
usedSlots: number;
|
||||
usedPowerKW: number;
|
||||
energyCostPerTick: number;
|
||||
maintenanceCostPerTick: number;
|
||||
currentUptime: number;
|
||||
}
|
||||
|
||||
// --- Network Topology ---
|
||||
|
||||
export interface NetworkHealthState {
|
||||
tier1Required: number;
|
||||
tier1Healthy: number;
|
||||
tier2Required: number;
|
||||
tier2Healthy: number;
|
||||
tier3Required: number;
|
||||
tier3Healthy: number;
|
||||
racksDisconnected: number;
|
||||
}
|
||||
|
||||
export interface NetworkTopologyConfig {
|
||||
tier1PerCompute: number;
|
||||
tier2PerTier1: number;
|
||||
tier3PerDC: number;
|
||||
tier1FailureRate: number;
|
||||
tier2FailureRate: number;
|
||||
tier3FailureRate: number;
|
||||
tier1BlastRadius: number;
|
||||
tier2BlastRadiusMultiplier: number;
|
||||
}
|
||||
|
||||
export function networkSlotsRequired(computeRacks: number): number {
|
||||
if (computeRacks <= 0) return 0;
|
||||
const tier1 = Math.ceil(computeRacks / 24);
|
||||
const tier2 = Math.ceil(tier1 / 6);
|
||||
const tier3 = 2;
|
||||
return tier1 + tier2 + tier3;
|
||||
}
|
||||
|
||||
export function maxComputeRacks(totalSlots: number): number {
|
||||
if (totalSlots <= 2) return 0;
|
||||
let lo = 0;
|
||||
let hi = totalSlots;
|
||||
while (lo < hi) {
|
||||
const mid = Math.ceil((lo + hi) / 2);
|
||||
if (mid + networkSlotsRequired(mid) <= totalSlots) {
|
||||
lo = mid;
|
||||
} else {
|
||||
hi = mid - 1;
|
||||
}
|
||||
}
|
||||
return lo;
|
||||
}
|
||||
|
||||
// --- Racks ---
|
||||
@@ -70,43 +151,64 @@ export interface RackSkuConfig {
|
||||
repairCostFraction: number;
|
||||
}
|
||||
|
||||
export interface Rack {
|
||||
id: string;
|
||||
skuId: RackSkuId;
|
||||
dataCenterId: string;
|
||||
isHealthy: boolean;
|
||||
}
|
||||
// --- Deployment Cohort (batch pipeline) ---
|
||||
|
||||
export interface RackOrder {
|
||||
export interface DeploymentCohort {
|
||||
id: string;
|
||||
count: number;
|
||||
skuId: RackSkuId;
|
||||
dataCenterId: string;
|
||||
stage: PipelineStage;
|
||||
stageProgress: number;
|
||||
stageTotal: number;
|
||||
totalCost: number;
|
||||
repairCount: number;
|
||||
}
|
||||
|
||||
// --- Retrofit ---
|
||||
|
||||
export interface RetrofitState {
|
||||
fromSkuId: RackSkuId;
|
||||
toSkuId: RackSkuId;
|
||||
phase: 'decommissioning' | 'installing';
|
||||
progress: number;
|
||||
total: number;
|
||||
racksRemaining: number;
|
||||
}
|
||||
|
||||
// --- Campus Config ---
|
||||
|
||||
export interface CampusTierCost {
|
||||
baseCost: number;
|
||||
buildTimeTicks: number;
|
||||
}
|
||||
|
||||
// --- Cluster Config ---
|
||||
|
||||
export interface ClusterCostConfig {
|
||||
baseCost: number;
|
||||
buildTimeTicks: number;
|
||||
}
|
||||
|
||||
// --- Infrastructure State ---
|
||||
|
||||
export interface InfrastructureState {
|
||||
dataCenters: DataCenter[];
|
||||
rackPipeline: RackOrder[];
|
||||
clusters: Cluster[];
|
||||
totalFlops: number;
|
||||
totalUptime: number;
|
||||
totalRackCount: number;
|
||||
totalComputeRackCount: number;
|
||||
totalDataCenterCount: number;
|
||||
}
|
||||
|
||||
export const INITIAL_INFRASTRUCTURE: InfrastructureState = {
|
||||
dataCenters: [],
|
||||
rackPipeline: [],
|
||||
clusters: [],
|
||||
totalFlops: 0,
|
||||
totalUptime: 1,
|
||||
totalRackCount: 0,
|
||||
totalComputeRackCount: 0,
|
||||
totalDataCenterCount: 0,
|
||||
};
|
||||
|
||||
// --- Locations (unchanged) ---
|
||||
// --- Locations ---
|
||||
|
||||
export type LocationId = 'us-west' | 'us-east' | 'eu-west' | 'eu-north' | 'asia-east' | 'asia-south' | 'middle-east';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user