Economy, buffs & caps
Stats and their ceilings, van parts feeding a buff object, and the shared mutable CAP.
The economy is eight stats, four of them capped, plus a buff layer that van parts feed into. The one subtlety worth real attention is that a cap is shared mutable state.
Stats and caps
Stats live on S: cash, gas, grub, van (0–100), vibes, tapes, blanks, cred (0–100), plus counters (legendaryTapes, showsAttended, miles, day). Gas, Grub, Van, and Vibes have ceilings. The base ceilings are a module constant; the live ceilings are a separate, mutable object:
var BASE_CAP = { gas: 20, grub: 40, van: 100, vibes: 100 }; // game.js:923
var CAP = { gas: 20, grub: 40, van: 100, vibes: 100 }; // game.js:924
Every clamp(v, 0, CAP.x) in the codebase reads CAP, and CAP can change mid-run.
Buffs: van parts fold into an accumulator
Van parts don't mutate stats directly — each contributes to a buff object, and one function folds them all together and re-derives the caps:
1123 function recomputeBuffs(s) { 1124 var b = { gasCap: 0, grubCap: 0, wearReduce: 0, showVibes: 0, bustGuard: 0, tapeQuality: 0, roadLuck: 0 }; 1125 s.vanmods = s.vanmods || {}; 1126 Object.keys(s.vanmods).forEach(function (slot) { 1127 var pid = s.vanmods[slot]; 1128 var part = pid && VAN_PARTS.filter(function (p) { return p.id === pid; })[0]; 1129 if (part) part.buff(b); 1130 }); 1131 s.buff = b; 1132 CAP.gas = BASE_CAP.gas + b.gasCap; 1133 CAP.grub = BASE_CAP.grub + b.grubCap; 1134 // Clamp current gas/grub down if a part was removed and lowered the cap. 1135 if (s.gas > CAP.gas) s.gas = CAP.gas; 1136 if (s.grub > CAP.grub) s.grub = CAP.grub; 1137 }
This is the codebase's sharpest gotcha, so hold it clearly: CAP is shared, module-global, and mutable. Two rules follow, and breaking either produces bugs that only appear after a save/load or a part swap:
- Re-run
recomputeBuffsafter any change to installed parts. - Re-run it on save-resume too — a loaded save restores
S.vanmodsbut not the derivedCAP, so applySave callsrecomputeBuffsexplicitly to rebuild it.
statCap(stat) (game.js:1007) returns the ceiling for a given stat and is what the Peak clamps against.
Mods vs. parts vs. consumables
Three different money-shaped systems, deliberately kept distinct:
- Mods (builder) set stats/flags and are re-derived from
baseStatsevery toggle — so they must never spend cash. - Van parts are bought as gear, installed into slots, and feed
recomputeBuffs. - Consumables live in the stash; some are active (
use(s)), some passive/auto (the spare tire auto-saves a blowout).
VAN_PARTS and CONSUMABLES are indexed together in GEAR_INDEX for name/lookup, which is why a "buy gear" flow can treat them uniformly and only the install step cares which is which.
- Four stats are capped; the live cap (
CAP) is mutable and separate fromBASE_CAP. - Van parts feed a buff accumulator;
recomputeBuffsre-derivesCAPand must run after any part change AND on load. - Mods, parts, and consumables are three distinct systems — mods never touch cash because they're re-derived.