February 27, 2026
v0.4: Data-Driven Balance — 1 Million Simulated Games, Cooking Labs, and Teammates
We built a headless simulation tool, ran 1,000,000 AI-driven games, and used the data to rebalance combat, heat, and the economy from scratch.
This release is the most ambitious update to Drug Warz AI yet. We didn't just add features — we built the tools to scientifically measure whether the game is actually fun, then used the data to fix it.
Here's what shipped:
- Cooking/Manufacturing System — buy precursors, cook drugs in labs, upgrade purity
- Teammates — hire runners, enforcers, chemists, and lookouts
- Data-Driven Balance Retuning — 1,000,000 simulated games identified and fixed three critical problems
- 304 unit tests and 3 E2E test suites with Playwright
- TypeScript strict mode across the entire codebase

The Simulation Tool
The star of this release is tools/sim.ts — a headless game simulation CLI that runs the full game engine without any UI. It was built to answer a question we couldn't answer by playtesting: is the game actually balanced?
How It Works
The simulation tool imports the real game engine functions (buyDrug, sellDrug, travel, combatAction, etc.) and runs them through 10 AI strategies, each representing a different playstyle:
| Strategy | Description |
|---|---|
| random | Buys and sells randomly. The control group. |
| greedy | Always buys the cheapest drug, sells the most expensive. No survival instinct. |
| fentanyl-rush | YOLO into fentanyl. Maximum risk, maximum reward. |
| stay-and-grind | Never travels. Trades local market only. |
| banker | Deposits cash aggressively, trades conservatively. |
| property-mogul | Saves up for properties, builds passive income. |
| heat-manager | Buys every heat reduction item, manages federal attention. |
| dealer-network | Hires NPC dealers for bulk discounts. |
| optimal-trader | Buys low, sells high, tracks price history. The "smart" player. |
| marathon | Uses every feature: bank, properties, teammates, heat items, dealers. |
Each strategy runs 50,000 games per mode (Classic and Endless), totaling 1,000,000 simulated games. The tool uses a seeded PRNG (Mulberry32) to make results reproducible — same seed, same outcomes.
CLI Flags
npm run sim # Default: 5,000 games/strategy
npm run sim -- --games 50000 # 1M total (50k × 10 strategies × 2 modes)
npm run sim -- --seed 123 # Custom seed for reproducibility
npm run sim -- --endless-days 500 # Extend endless mode cap
What It Measures
For each game, the tool tracks:
- Final net worth (cash + bank + inventory value - debt)
- Peak net worth reached during the game
- Death cause (combat, loan shark, government strike, timeout)
- Heat metrics (peak heat, government strikes, heat items purchased)
- Feature adoption (did the strategy use bank? properties? teammates?)
- Economy metrics (total drugs moved, profit, most traded drug)
The output is a structured markdown report with tables, rankings, and balance flags — automated warnings when metrics look unhealthy:
- greedy (classic): 100.0% death rate — near-guaranteed death
- stay-and-grind (classic): 85.1% of games hit heat ≥90 — heat may be too aggressive
- marathon (endless, 365 days): 0% reached $1B — economy ceiling may be too low
The full simulation runs in about 2 minutes on a MacBook Pro (1M games, 122.8 seconds).
What the Data Revealed
Running 1,000,000 games exposed three critical problems:
Problem 1: Combat Kills Everyone
100% of deaths were from combat. Zero from loan sharks. Zero from government strikes. Even the best strategy (heat-manager) died 65% of the time in Classic mode. In Endless mode, every strategy hit 100% death rate.
The encounter formula was dangerLevel * 0.03, meaning Detroit (danger level 9) had a 27% encounter chance per travel regardless of how carefully you played. Low-level police did 12 damage per hit — three unlucky fights and you're dead.
Problem 2: Heat Spirals Uncontrollably
62-84% of actively-trading games hit heat ≥90 (the danger zone). Even heat-manager — a strategy that buys every heat reduction item — still hit 87% heat-≥90 rate. The decay of -3 per day couldn't keep up with the +5 to +15 heat generated by each transaction.
Problem 3: Economy Ceiling at ~$20M
Zero games out of 1,000,000 reached $100M. The economy had a hard ceiling:
- Bank charged 30% on deposits and paid 0% interest
- Properties generated $200-$3,000/day (takes 167 days for a Mansion to pay itself back)
- Price spikes capped at 4x the drug's max price

The Balance Fixes
Armed with data, we made surgical changes to each system.
Combat: Fewer Encounters, Better Survivability
Before: encounterChance = dangerLevel * 0.03
After: encounterChance = dangerLevel * 0.02 * max(0.3, heat/100)
The new formula ties encounter frequency to heat. At low heat, you get 70% fewer encounters. At heat 50, encounters are halved. At heat 100, it's close to the old rate. This means careful players who manage their heat profile can trade safely, while reckless players still face consequences.
Other combat changes:
- Starting weapon upgraded from fists (5 dmg) to switchblade (12 dmg)
- Police damage reduced from 12 to 8, flee chance raised to 85%
- Street mugger damage reduced from 10 to 7, flee chance raised to 90%
- State Troopers and Gang Ambush flee chances raised from 50% to 60%
Heat: Slower Burn, Faster Recovery
| Setting | Before | After |
|---|---|---|
| Daily heat decay | -3 | -5 |
| Fentanyl heat per trade | 15 | 10 |
| Cocaine heat per trade | 7 | 5 |
| Heroin/Meth heat per trade | 8 | 6 |
| Large inventory penalty | +2/day | +1/day |
| Property heat (≥$500K) | +3/day | +2/day |
| Heat item cooldown | 3 days | 2 days |
| Diminishing returns floor | 30% | 40% |
| US strike threshold | heat ≥85 | heat ≥92 |
| International strike multiplier | 1.0 | 0.5 |
Economy: Bank Interest, Better Properties, Higher Ceiling
| Setting | Before | After |
|---|---|---|
| Bank deposit fee | 30% | 20% |
| Bank interest | 0% | 1%/day compounding |
| Price ceiling multiplier | 4x | 6x |
| Trap House income | $200/day | $500/day |
| Warehouse income | $800/day | $2,000/day |
| Mansion income | $3,000/day | $8,000/day |
| Cook Lab income | $500/day | $1,200/day |
The bank interest is the game-changer. Deposit $100K (pay 20% fee = $80K). By day 30 it's $107K. By day 100 it's $216K. By day 365 it's $2.94M. Combined with Mansion income ($8K/day), the path to $100M+ in Endless mode is now real.
Results: Before vs. After
We re-ran the full 1M simulation after the balance changes:
| Metric | Before | After | Change |
|---|---|---|---|
| Best median NW (Classic) | $315K | $558K | +77% |
| $1M milestone rate | 15-43% | 43-65% | +20-22pp |
| Max NW (Endless) | $22.7M | $121.6M | +435% |
| Death rate (heat-manager, Classic) | 70.3% | 65.3% | -5pp |
| Death rate (banker, Classic) | 90.1% | 85.1% | -5pp |
| heat-manager $10M milestone | 2.1% | 6.4% | +4.3pp |
The game is still deadly — that's intentional. But now smart strategies are meaningfully rewarded, the economy has room to grow, and the heat system actually responds to player choices.

New Features
Cooking/Manufacturing System
Buy precursors at market prices, cook them in upgradeable labs, and produce higher-purity product. Six cookable drug recipes, each with its own precursor chain. Lab upgrades improve yield and purity, but disasters can destroy batches and damage your health.
Teammates
Renamed from "plugs" to better reflect the system. Hire up to 4 teammate types:
- Runners — sell drugs passively while you travel
- Enforcers — combat damage bonus, reduce incoming damage
- Chemists — cooking yield bonus, reduce disaster rate
- Lookouts — heat reduction, early warning on encounters

Testing Infrastructure
304 Unit Tests with Vitest
Every game system has dedicated test coverage:
| Test Suite | Tests | What It Covers |
|---|---|---|
game-trading.test.ts |
42 | Buy/sell, purity, price ceilings, bulk deals |
game-combat.test.ts |
28 | Damage calculation, flee mechanics, death |
game-finance.test.ts |
35 | Bank deposits, loans, interest, debt |
game-travel.test.ts |
31 | Travel, heat decay, property income, events |
game-shop.test.ts |
24 | Weapons, armor, heat items, cooldowns |
game-teammates.test.ts |
22 | Hire, assign, collect, auto-assign |
game-cooking.test.ts |
18 | Precursors, labs, cook jobs, disasters |
game-getters.test.ts |
15 | Net worth, inventory, score calculation |
data.test.ts |
12 | Data integrity, drug/location/weapon validation |
ui-rendering.test.ts |
11 | DOM rendering, HUD display, nav tabs |
simulation/simulate.test.ts |
6 | Balance check — 4 strategies, 100 games each |
Tests run in ~400ms locally using Vitest with the V8 coverage provider.
npm test # Run all 304 tests
npm run test:coverage # With code coverage report
3 E2E Suites with Playwright
End-to-end tests using Playwright verify the actual browser experience:
- Navigation (9 tests) — Every tab switches correctly
- Market Trading (2 tests) — Buy drugs, verify cash decreases, error toasts
- Game Flow (3 tests) — Start game, travel, complete a session
Plus the screenshot spec that generated every image in this post.
npx playwright test # Run all E2E tests
Deterministic Test State
A custom createTestState() factory (state-factory.ts) generates deterministic game states with fixed prices, purity values, and starting conditions. Zero Math.random() calls — every test is reproducible.
The Map Coordinate Tool
The travel map shows 19 cities across 4 regions, plotted on a CartoDB Dark Matter basemap. Getting the coordinates right required a custom tool: scripts/map-coords.html.
It's a standalone HTML page that:
- Loads the game's world map image
- Displays a crosshair cursor with live percentage coordinates
- Lists all 19 cities in a sidebar
- Click a city, click the map — coordinates are recorded
- Exports a ready-to-paste TypeScript
LOCATION_COORDSobject
The coordinates are stored as percentage-based { x, y } values (not pixels), so they scale correctly at any viewport size. This approach means the map works on mobile without any responsive breakpoint logic.

Tech Stack
This entire game is built with zero frameworks:
- TypeScript — Strict mode, ES2022 target, erasable syntax
- Eleventy (11ty) — Static site generation for landing, history, blog, i18n
- Vitest — Unit testing (304 tests, ~400ms)
- Playwright — End-to-end browser testing
- anime.js v4 — Screen transitions and particle animations
- CartoDB Dark Matter — Map basemap tiles
- IBM Plex Mono — Monospace font for the terminal aesthetic
- GoatCounter — Privacy-friendly analytics
- Cloudflare Pages — Hosting and CDN
- Claude Code — AI pair programming (built this entire release)
No React. No Next.js. No Webpack. No Tailwind. Just ES modules, CSS custom properties, Canvas API, and Web Audio API.
What's Next
The simulation tool opens up a whole new development workflow: change a number, run 1M games, see what happens. Future balance patches will follow this data-driven approach.
Planned for v0.5:
- Leaderboard system (global high scores)
- More cooking recipes and precursor chains
- Expanded Endless mode with prestige mechanics
- Mobile-optimized touch controls
Play Drug Warz AI now and see how your strategy stacks up against 1,000,000 simulated games.
Built with Claude Code. Tested with Vitest and Playwright. Hosted on Cloudflare Pages.