Buy Low. Sell High. Survive.
A modern browser reimagining of the classic Drug Wars game.
Zero frameworks. Pure JavaScript. No installs.
Drug Warz AI is a free, open-source browser game inspired by the 1984 DOS classic Drug Wars by John E. Dell. Trade drugs across 19 cities spanning the US, Latin America, Europe, and Asia. Hire underlings, negotiate with NPC dealers, fight cartels, claim territories, and build your empire — all from your browser with no downloads, accounts, or installs.
The entire game runs client-side with zero backend. Your save data lives in your browser's LocalStorage. The codebase is intentionally minimal: TypeScript modules, one animation library, and pure CSS. The travel map is a real CartoDB Dark Matter cartographic map with hand-mapped city coordinates. 273 automated tests (unit + simulation) keep the game engine stable.
Play it live at drugwarz.pages.dev
| Feature | Description | |
|---|---|---|
| 🌍 | 18 Cities | Trade across NYC, Miami, Medellín, Bangkok, Amsterdam, Lagos, and more |
| 💊 | 12 Drugs | From weed to fentanyl — each with unique price ranges, purity levels, and risk |
| 📈 | Bloomberg Market Terminal | Real-time price tickers, sparkline charts, session high/low, and P&L tracking |
| 🧪 | Purity System | Drug purity varies by city (source vs consumer). Purity directly affects your sell price |
| 🤝 | NPC Dealers | 8 named dealers with personalities. Ally, betray, or defeat them for territory control |
| 🗺️ | Territory System | Defeat dealers in combat to claim cities with permanent 10% buy discounts |
| 💰 | Wealth Events | "Mo Money Mo Problems" — the richer you get, the more heat you attract |
| ⚔️ | Combat | Fight police, gangs, cartels, and military. Choose to attack, defend, flee, or bribe |
| 🔫 | Weapons & Armor | Switchblades to RPGs. Gear up at the shop |
| 🏠 | Properties | Stash houses, trap houses, warehouses, and mansions for storage and passive income |
| 👥 | Crew System | Hire street runners, corner dealers, and lieutenants to sell for you |
| 🕵️ | Hunt Mechanic | Track down plugs who fled with your cash (55% success rate) |
| 🏦 | Banking & Loans | Deposit cash safely. Borrow from the loan shark — 10% daily interest |
| 📊 | Stats Tab | Net worth chart, trading analytics, combat record, and full event log |
| 🌐 | 5 Languages | English, Deutsch, Español, Português, Français |
| 🔊 | Procedural Audio | Sound effects generated at runtime via Web Audio API — zero audio files |
| 📱 | Fully Responsive | Works on mobile, tablet, and desktop |
| 💾 | Persistent Saves | Auto-save to LocalStorage with high score leaderboard |
This project is built with an intentionally minimal dependency footprint. No React, no Tailwind, no bundler — just the browser platform, TypeScript, and a handful of dependencies.
| Technology | Role | Details |
|---|---|---|
| Animations | Screen transitions, staggered UI entrances, ticker flashes, counter animations, and travel modal effects. The only runtime dependency. |
| API | Role |
|---|---|
| Canvas API | Background particle effects (ParticleBackground class) |
| Web Audio API | Procedurally generated buy/sell/travel/alert sound effects — no audio files |
| LocalStorage | Persistent game saves, high scores, and settings |
| Technology | Role |
|---|---|
| Nunjucks | HTML templating engine (via 11ty). Layouts, partials, and localized page generation. |
| Custom i18n system | 5-language support with JSON translation files and 11ty pagination for localized routes (/de/, /es/, /pt/, /fr/). |
| Tool | Role |
|---|---|
| Claude Code | AI pair programmer. Authored game engine, test suites, simulation harness, map capture pipeline, and coordinate picker tool. |
DrugWarzAI/
├── js/ # TypeScript source (compiled to JS)
│ ├── app.ts # Main application — routing, event wiring, screen management
│ ├── game.ts # Game engine — state, buy/sell, travel, combat, plugs, events
│ ├── ui.ts # UI rendering — all screens, tabs, overlays, and charts
│ ├── data.ts # Game data — drugs, locations, weapons, dealers, events, coords
│ ├── types.ts # TypeScript type definitions
│ ├── animations.ts # anime.js integration, particles, procedural audio
│ ├── i18n.ts # Internationalization helper
│ └── __tests__/ # Test suites (Vitest)
│ ├── game-*.test.ts # Unit tests (combat, trading, travel, finance, events, etc.)
│ ├── ui-rendering.test.ts
│ ├── helpers/
│ │ └── state-factory.ts
│ └── simulation/ # AI simulation harness
│ ├── simulator.ts # 4 AI strategies, game runner, aggregation
│ ├── simulate.test.ts # Balance assertion tests (200 games × 4 strategies)
│ └── seeded-random.ts # Mulberry32 deterministic PRNG
├── css/
│ └── main.css # All styles — dark theme, responsive, component classes
├── scripts/ # Dev tooling
│ ├── capture-map.mjs # Playwright: renders CartoDB tiles → screenshots world map
│ └── map-coords.html # Interactive coordinate picker (open in browser, click cities)
├── src/
│ ├── index.njk # Landing page template
│ ├── game/index.njk # Game page (standalone, no base layout)
│ ├── localized-game.njk # i18n game page generator (11ty pagination)
│ ├── _includes/
│ │ └── base.njk # Base HTML layout
│ └── _data/
│ ├── site.cjs # Site metadata
│ ├── languages.cjs # Language configuration
│ └── i18n/ # Translation JSON files (en, de, es, pt, fr)
├── assets/
│ ├── map-world.webp # CartoDB Dark Matter world map (auto-generated via Playwright)
│ ├── og-image.jpg # Social sharing / hero image
│ ├── favicon.ico # Favicon
│ └── icon-*.png # PWA icons
├── e2e/ # Playwright end-to-end tests
├── tsconfig.json # TypeScript config (strict mode)
├── vitest.config.ts # Vitest test runner config
├── playwright.config.ts # Playwright config
├── eleventy.config.cjs # 11ty configuration
├── package.json
└── _site/ # Build output (deploy target)
# Clone
git clone https://github.com/ST215/DrugWarzAI.git
cd DrugWarzAI
# Install dependencies
npm install
# Development server with hot reload (TypeScript watch + 11ty serve)
npm run dev
# Production build
npm run build
# Run tests (273 unit + simulation tests)
npm test
# Type check
npm run typecheck
# Regenerate world map from CartoDB tiles
node scripts/capture-map.mjsThe dev server runs at http://localhost:8080. The production build outputs to _site/.
The travel animation map uses a real CartoDB Dark Matter screenshot with hand-mapped city coordinates:
scripts/capture-map.mjsuses Playwright to render Leaflet + CartoDB tiles and screenshot the mapscripts/map-coords.htmlis an interactive tool — open in a browser, click each city on the map to record its percentage coordinates- Coordinates are pasted into
LOCATION_COORDSinjs/data.ts
- Classic — 30 days to make your fortune. Pay off your $5,500 debt, stack cash, and survive.
- Endless — No time limit. Build your empire and climb the high score leaderboard.
This project stands on the shoulders of incredible open-source work:
- Drug Wars (1984) by John E. Dell — the DOS classic that started it all
- anime.js by Julian Garnier — lightweight and powerful animation engine
- OpenStreetMap — the free, open geographic database powering the world map. Map data © OpenStreetMap contributors
- CARTO — CartoDB Dark Matter basemap tiles (dark, label-free) used for the travel animation map
- Leaflet by Volodymyr Agafonkin — open-source interactive map library used in the map capture pipeline
- TypeScript by Microsoft — strict-mode type safety across the entire codebase
- Vitest — blazing fast test runner powering 273 unit and simulation tests
- Playwright by Microsoft — browser automation for E2E tests and automated map screenshot capture
- Eleventy by Zach Leatherman — the simplest static site generator
- Nunjucks by Mozilla — powerful templating for JavaScript
- Cloudflare Pages — fast, free global edge hosting
- GoatCounter by Martin Tournoij — open-source, privacy-friendly analytics
- Claude Code by Anthropic — AI pair programmer that co-authored the game engine, test suites, simulation harness, and map tooling
- Shields.io — badges for open-source projects
ISC