Work / Games & Simulation
EXIT LIQUIDITY
An incremental game about running pump-and-dumps, on a deterministic order-book sim that counts every victim.
- Godot 4.6
- GDScript
- ENet (authoritative-server multiplayer)
- Custom headless test runner
- JSON data tables
Live demo
Pump it, then dump it
The game's own order book, ported line for line, with a small crowd that chases momentum. Hype the coin, then sell your bag into the bids.
- Price
- 0.993 −0.7%
- Sentiment
- +0.00
- Your bag
- 100%
- Cash out
- 0
- Left holding
- 0
The crowd buys with cash and chases momentum. Hype pushes sentiment; a failed post only tires them.
The book is a TypeScript port of the game’s order_book.gd (0.5% per level, 40 levels, depth decaying away from mid, eaten levels refilling on the other side; limit orders left out), with a reduced version of its retail crowd. Seeded and deterministic: the same clicks give the same candles. Dashed lines mark your exits.
TL;DR
- An incremental game, planned for Steam, set inside a fake desktop OS: you grow a three-person group-chat pump into market manipulation, and a lifetime counter keeps score of everyone left holding the bag.
- Under the jokes is a real market model: a 40-level limit order book with VWAP fills, resilient depth, aggregate retail flow driven by sentiment, and a rival whale that front-runs you.
- 58,045 lines of GDScript and 997 headless tests over 95 commits in 18 days, built by directing AI coding agents.
The problem
Most finance games fake the market with a random walk. A pump-and-dump only makes sense if price impact is real: buying moves the price, the crowd you pull in has to come from somewhere, and selling into thin depth collapses the chart. I wanted a game whose economy runs on a market model a quant could read, and whose satire lands because the consequences are counted.
What I built
The player picks a fictional coin and spends influence on posts, shill threads, fake screenshots, paid promos and bot swarms, rides the chart, then slam-sells or ladders out. The victim count drives Rot, which decays the whole interface from clean to worn to rotten.
- Order book. Each coin has a limit order book with 40 levels a side, exponentially decaying depth and resilience back toward baseline. Market orders walk the book level by level and fill at VWAP.
- Retail flow. One aggregate flow driven by sentiment, momentum and fear. It buys in cash, so rising prices throttle inflow, and sells in tokens, so collapses cascade.
- Agents. A rival whale watches for unusual volume (z above 2.5) and front-runs, counter-dumps or offers to collude. Rival operators, public figures, an in-game ad agency and, in multiplayer, other players all trade through the same book.
- Determinism. The sim is seeded: the same seed plus the same actions gives the same candles, and saves resume bit-exactly.
- Game systems. 16 apps, a 31-node upgrade tree across 6 tiers, heat-gated boss events, five named NPCs, four endings, prestige and offline progress.
- Multiplayer. Direct-IP, authoritative-server multiplayer over ENet. Player intents are applied sorted by participant and sequence, never by arrival order, so every machine computes the same market.
It’s built against a full game design doc, and I directed AI coding agents through all 95 commits.
Key decisions
- Decision: a parametric limit-order-book impact model instead of a full matching engine. Why: it gives real price impact, depth and recovery at game speed. Trade-off: retail is one aggregate flow, not thousands of individual orders.
- Decision: seeded, deterministic simulation. Why: replays, bit-exact saves and multiplayer that agrees on every machine. Trade-off: every source of randomness has to go through the seeded stream.
- Decision: tick-rate-independent hazard math. Why: a pump should peak at the same height whether the game runs fast or slow. Trade-off: rates, decays and probabilities all need tempo-aware formulas.
- Decision: a headless test suite from day one. Why: an agent-built economy needs checks that run on every change. Trade-off: tests are about a third of the codebase.
The hard part
Slicing an order shouldn’t change its price impact. Splitting one large order into 100 small ones moved the price 23% differently from a single order, because the level nearest the mid price “paid for itself twice”. Eat half of that level and the mid moves half a level; eat the rest and the walk counted a whole level again. The error grew with the harmonic number of the slice count, which would let players game the market just by clicking faster.
The fix keeps, for each side of the book, the fraction of the near level already priced into the mid, and nets it out of every walk. A probe compares one order against 2, 5, 10, 25 and 100 slices at three liquidity levels and three order sizes. The worst relative deviation is now 5.7e-15, about 26 ULP: floating-point addition not being associative over a hundred terms. Determinism is untouched.
Results
- 997 headless tests across 49 suites; the project docs report 24,427 assertions and 0 failures.
- Order-slice invariance at 5.7e-15, down from a 23% gap.
- A seeded tuning harness (scripted runs, not players) shows where the economy is still off: the first pump at tier 0 has a median of +55% against a +30–80% target, and laddering out doesn’t yet beat market-dumping at tiers 0 or 2. I track that next to the targets it does hit.
- Art, copy and audio are still code-generated placeholders.
What I’d do next
- Real art and sound, then a first human playtest.
- Re-tune the economy until laddering out beats dumping, which is the lesson the game is meant to teach.
- A demo build, and multiplayer tested between two real machines rather than on one.
Links
- Code: private repo, walkthrough on request.
- Related market modelling: Concord (M&A diligence) · AccountWard (fiduciary accounting)
Verified numbers
| Metric | Value | Source |
|---|---|---|
| Headless tests across 49 suites (docs report 24,427 assertions, 0 failures) | 997 | mit37/exit-liquidity/docs/running-and-testing.md:86 |
| Price-impact gap between one order and the same order in 100 slices, after the fix (23% before) | ≤ 5.7e-15 | mit37/exit-liquidity/market/order_book.gd:38-52 |
| Order-book depth per side | 40 levels | mit37/exit-liquidity/market/order_book.gd:18-27 |
| In-game apps (14 single-player, 2 multiplayer) | 16 | mit37/exit-liquidity/os/app_registry.gd:12-35 |
| Upgrade nodes across 6 tiers | 31 | mit37/exit-liquidity/progression/upgrade_tree.gd:28-103 |