Fix rack order race condition allowing slots/power to exceed DC limits
CI / build-and-push (push) Successful in 47s

Rapid clicks on order rack bypassed capacity checks because usedSlots
and usedPowerKW were only updated during the tick. Now both the store
action and UI compute slot/power usage live from racks + pipeline,
so each order immediately reflects in the next check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-24 20:05:11 -04:00
parent 38097478da
commit 03ef94c22c
2 changed files with 16 additions and 6 deletions
+8 -4
View File
@@ -103,6 +103,7 @@ function CapacityBar({ label, used, max, unit, icon: Icon }: {
function DataCenterCard({ dcId }: { dcId: string }) {
const dc = useGameStore((s) => s.infrastructure.dataCenters.find(d => d.id === dcId))!;
const pipelineForDc = useGameStore((s) => s.infrastructure.rackPipeline.filter(o => o.dataCenterId === dcId));
const money = useGameStore((s) => s.economy.money);
const era = useGameStore((s) => s.meta.currentEra);
const completedResearch = useGameStore((s) => s.research.completedResearch);
@@ -112,6 +113,9 @@ function DataCenterCard({ dcId }: { dcId: string }) {
const tierConfig = DC_TIER_CONFIGS[dc.tier];
const currentEraIdx = ERA_ORDER.indexOf(era);
const liveUsedSlots = dc.racks.length + pipelineForDc.length;
const liveUsedPower = dc.racks.reduce((s, r) => s + RACK_SKU_CONFIGS[r.skuId].powerDrawKW, 0)
+ pipelineForDc.reduce((s, o) => s + RACK_SKU_CONFIGS[o.skuId].powerDrawKW, 0);
const availableSkus = Object.values(RACK_SKU_CONFIGS).filter(sku => {
if (ERA_ORDER.indexOf(sku.era) > currentEraIdx) return false;
@@ -163,8 +167,8 @@ function DataCenterCard({ dcId }: { dcId: string }) {
</div>
<div className="flex gap-4 mb-3">
<CapacityBar label="Slots" used={dc.usedSlots} max={tierConfig.rackSlots} unit="" icon={HardDrive} />
<CapacityBar label="Power" used={dc.usedPowerKW} max={tierConfig.powerBudgetKW} unit="kW" icon={Zap} />
<CapacityBar label="Slots" used={liveUsedSlots} max={tierConfig.rackSlots} unit="" icon={HardDrive} />
<CapacityBar label="Power" used={liveUsedPower} max={tierConfig.powerBudgetKW} unit="kW" icon={Zap} />
</div>
{expanded && (
@@ -195,8 +199,8 @@ function DataCenterCard({ dcId }: { dcId: string }) {
<div className="flex gap-2 flex-wrap">
{availableSkus.map(sku => {
const canAfford = money >= sku.baseCost;
const hasSlot = dc.usedSlots < tierConfig.rackSlots;
const hasPower = dc.usedPowerKW + sku.powerDrawKW <= tierConfig.powerBudgetKW;
const hasSlot = liveUsedSlots < tierConfig.rackSlots;
const hasPower = liveUsedPower + sku.powerDrawKW <= tierConfig.powerBudgetKW;
const disabled = !canAfford || !hasSlot || !hasPower;
return (