Case study · Side project
Market Floor: prices nobody scripted
A browser trading game where every price comes out of a real order book. 62 computer traders with different strategies compete under the same rules as the player, so the market has to hold together on its own.
01The problem
Most trading games script their price charts. That's easy to build, but players learn the pattern and the market stops feeling alive. I wanted the opposite: a price that is only ever the last trade in an order book, with realistic behaviour (spreads, slippage, trends, panics) coming out of the traders instead of a formula.
That turns a game into a systems problem. The market has to stay liquid, prices have to stay sane over a 250-day season, and every run has to be reproducible, or nobody could trust a leaderboard.
02Architecture
The core decision: the engine is pure TypeScript with zero DOM access, and all of its state is plain JSON. The browser drives Game.step() from an animation loop; a headless script drives the same function in a plain loop; the server runs it too. Saving is JSON.stringify(state).
- Deterministic by construction. Every random draw comes from seeded RNG streams kept in state, so the same seed plus the same player actions at the same ticks always produce the same game.
- No floats in the matching engine. Prices are stored as integer ticks, so the order book never compares floating-point numbers.
- Built in 14 milestones, each with a written "done when" test, from the RNG and fair-value process through the order book, traders, news, margin and balancing, to deployment.
03A market that holds together
Each commodity has a hidden fair value: a mean-reverting random walk in log space, with seasonality and news shocks. Nobody sees it, including the traders. They estimate it, and the price only moves when they trade.
Order book
Limit and market orders, price-time priority, partial fills, self-trade prevention and depth-based cost estimates. Big market orders walk the book, so the player pays slippage and moves the price.
Market makers
Quote both sides with inventory skew and spreads that widen with volatility and fresh news, which keeps the book two-sided through shocks.
Strategies
Trend followers, contrarians, value investors, panic sellers, whales and noise traders, plus institutions that work big orders over days and a stop-loss crowd whose stops cascade through recent highs and lows.
News
51 headline templates. Some land instantly, some days later, and about one rumor in five is false: it never moves fair value, but traders believe it until the denial reaches them.
04Scores the server can prove
A leaderboard is only as good as its weakest client. Instead of trusting a submitted number, the game sends the run's recorded commands. A Supabase edge function loads the same engine bundle the site serves (checked against its content hash), replays the whole market with those commands and records the score only if the result checks out. A 250-day game replays in well under a second.
This only works because of the early decision to keep the engine pure and deterministic. The same property powers save and load, "ghost" races against your best run and narrated replays.
05Testing and balancing
- 340+ automated tests across Vitest and Playwright: order-book priority and partial fills, margin calls and liquidation, save → load → continue matching an uninterrupted run, and "false rumors never move fair value" (checked by comparing twin games), plus fuzz, soak and accessibility suites.
- A 100-game headless balancing harness (
npm run balance) that plays full seasons with a naive bot and a news-reading bot and checks the targets in the spec. The final run met all of them: price tracks fair value within roughly 0.7–1.8%, the book is never empty, no computer trader goes bankrupt, and 99.99% of $100k market orders fill completely. - Smoke tests against the production URL as the final milestone, so "deployed" means "verified live".
06Stack
Why it's on this page
It's the same kind of work I do in data platforms, at game scale: many independent producers, a system that must stay consistent under load, and results you can reproduce and verify instead of trusting.