Own productLive
Live market order flow, rendered as a 3D battle
A real-time 3D scene that turns XRP trading into two armies, fed by public exchange streams and built to keep running when a feed or the graphics card fails.
- Industry
- Crypto markets
- What it shows
- Real-time data, Data visualisation, 3D on the web
- Year
- 2026
- See it live
- xrpwarzone.com
In numbers
- markets to choose from, including a synthetic XRP/BTC pair
- 3
- exchange hosts with automatic failover
- 3
- soldiers on the field at most, 250 per side
- 500
- automated interface tests, including accessibility checks and 12 screen sizes
- 28
Figures come from the project’s own files and records.
What changes
The steps people did by hand, and the route the work takes now.
Thousands of trades arrive each minute
Before
- Watch the order book
- Scroll the trade tape
- Compare buy and sell volume
- Guess who is winning
With the system
- Live feed turns trades into two armies
- The balance bar shows momentum
Market pressure readable in a second
The problem
An order book is exact and almost impossible to read at a glance. Thousands of trades a minute become a scrolling list of numbers, and the question most people actually have, “who is pushing harder right now?”, stays buried.
What we built
XRP Battlefield turns that stream into a scene you understand in a second. Buyers and sellers are two armies. Every trade sends soldiers onto the field, the depth of waiting orders sets the size of each army, and every 60-second candle is one round. On the XRP market the round goes to the side whose trades added up to more dollars; on the XRP/BTC view, to whichever coin gained on the other.

Large trades arrive as named events. A war log keeps the record, and a balance bar at the top shows momentum in plain terms. It runs as well on a phone as on a desktop.

Built to keep running
Live data fails in ordinary ways: a stream stalls, an exchange host drops, a laptop has no working graphics driver. Each case has a planned answer.
- The feed rotates across three exchange hosts and a watchdog catches stale data.
- If nothing connects, a clearly labelled demo keeps the scene running.
- If 3D can’t start, the live numbers stay available and the visitor chooses what to do next.

How a round is decided
Replay a dummy round through the real rules, break the feed or the 3D scene on purpose, and see the limits the project is built to. The system map shows all of it in one place: the live path from exchange to battlefield, every fallback under the part it protects, the chat and a release, in ten journeys checked against the code on 12 October 2026.
- exchange hosts, tried in order
- 3
- src/
core/ config. ts - of silence on any book or ticker ends Live
- 5 s
- src/
core/ feed. ts - to a clearly labelled demo if nothing connects
- 4.2 s
- src/
core/ feed. ts - interface tests, with overflow checked at 12 screen sizes
- 28
- tests/
hud-ui. spec. ts
Interactive system map
The live path, and every fallback under it
30 parts and 10 journeys, from a trade becoming soldiers to a refused host, a quiet stream, a failed 3D load and a release. Checked against the code on 12 October 2026.
Play 10 journeys, or click any of its 30 parts.
- exchange hosts, tried in order
- 3
- of silence ends Live
- 5 s
- interface tests, at 12 screen sizes
- 28
A round, replayed
- Each trade calls up soldiers for its side: one per 1,400 XRP, at least 1 and at most 60.
- The top 20 levels of the order book set each army’s standing size: one soldier per $3,800 of resting orders, 40 to 250 a side.
- A trade of $15,000 or more is a big trade, $60,000 or more a whale. Smaller trades count too when they dwarf the recent typical trade. A whale calls up 22 extra soldiers and cuts down up to 26 on the other side.
- After 60 seconds the round goes to the side whose trades added up to more dollars. Closer than $1,500 is a draw.
- 0:07Big buy$18,53112 soldiers
- 0:03Big sell$51,08733 soldiers
- 0:02Big buy$26,83017 soldiers
- 0:14Big buy$29,91519 soldiers
- 0:13Big buy$11,6437 soldiers
- 0:07Big buy$18,53112 soldiers
- 0:27Big sell$24,75016 soldiers
- 0:21Whale sell$41,27726 soldiers + 22
- 0:14Big buy$29,91519 soldiers
- 0:33Big sell$35,31122 soldiers
- 0:32Big buy$18,45312 soldiers
- 0:32Whale sell$72,94746 soldiers + 22
- 0:50Whale buy$48,51831 soldiers + 22
- 0:47Big buy$19,39812 soldiers
- 0:42Big buy$15,05410 soldiers
- 0:54Big buy$31,35020 soldiers
- 0:52Big buy$33,64921 soldiers
- 0:51Whale buy$68,13543 soldiers + 22
- 0:04Whale buy$121,54060 soldiers + 22
- 0:03Big sell$9,6646 soldiers
- 0:02Big sell$8,4275 soldiers
- 0:13Big sell$19,89013 soldiers
- 0:12Big sell$48,42432 soldiers
- 0:10Big sell$14,85810 soldiers
- 0:29Big sell$18,94512 soldiers
- 0:25Big buy$17,42411 soldiers
- 0:22Whale sell$73,62948 soldiers + 22
- 0:36Big sell$13,9799 soldiers
- 0:29Big sell$18,94512 soldiers
- 0:25Big buy$17,42411 soldiers
- 0:49Big sell$25,64417 soldiers
- 0:45Big buy$26,18517 soldiers
- 0:36Big sell$13,9799 soldiers
- 0:57Big sell$16,22611 soldiers
- 0:49Big sell$25,64417 soldiers
- 0:45Big buy$26,18517 soldiers
- 0:02Whale sell$61,01040 soldiers + 22
- 0:01Big sell$6,5744 soldiers
- 0:15Big sell$48,83632 soldiers
- 0:15Big sell$19,15212 soldiers
- 0:12Whale buy$160,18860 soldiers + 22
- 0:15Big sell$48,83632 soldiers
- 0:15Big sell$19,15212 soldiers
- 0:12Whale buy$160,18860 soldiers + 22
- 0:15Big sell$48,83632 soldiers
- 0:15Big sell$19,15212 soldiers
- 0:12Whale buy$160,18860 soldiers + 22
- 0:15Big sell$48,83632 soldiers
- 0:15Big sell$19,15212 soldiers
- 0:12Whale buy$160,18860 soldiers + 22
- 0:58Big buy$31,40821 soldiers
- 0:58Big sell$28,58819 soldiers
- 0:57Big sell$17,93912 soldiers
When things fail
- 1Every pair’s book and ticker have arrived: Live.
- 2A book or ticker silent for 5 s, or the socket closes: Waiting, and the battle pauses.
- 3No complete data within 4.2 s, every host refuses, or the feed drops a fourth time: Demo.
- 4A host refuses: try the next one. A quiet feed: reconnect after 0.8, 1.6, then 2.4 s.
- stream.
binance. Refusedcom - data-stream.
binance. Connectedvision - stream.
binance. Not neededus
- 0 sOpens one socket to the first host, carrying trades, the top 20 book levels and the ticker.
- At onceThat host closes before it opens, so the next host in the list is tried straight away.
- When readyLive only once every pair has sent both a book snapshot and a ticker. A handshake alone is not enough.
- stream.
binance. Connectedcom - data-stream.
binance. Not neededvision - stream.
binance. Not neededus
- Every 1 sA watchdog checks when each book and ticker last arrived.
- 5 s silentAny book or ticker silent for 5 seconds ends Live. The socket is closed and old snapshots are thrown away.
- MeanwhileRounds and combat freeze, and trades are ignored, so partial data never moves the battle.
- 0.8, 1.6, 2.4 sReconnects from the first host, waiting a little longer each time.
- stream.
binance. Refusedcom - data-stream.
binance. Refusedvision - stream.
binance. Refusedus
- From 0 sTries the three hosts in turn. If all three refuse, the demo starts at once.
- 4.2 sStill no complete market data, so a demo generator takes over and the status says Demo.
- After 3 retriesA feed that keeps going quiet ends in the same labelled demo.
- ThenA live socket is never quietly revived under the demo label. Switching market or reloading starts again.
- stream.
binance. Connectedcom - data-stream.
binance. Not neededvision - stream.
binance. Not neededus
- On loadThe 3D scene loads as a separate bundle, behind a 30-second time limit.
- If it failsNo WebGL, a model that won’t load or the time limit: the error is caught and a dialog opens.
- ChoicesRetry battlefield, Reload page, or Continue with HUD. Focus starts on Retry, and the controls behind the dialog wait.
- ThroughoutThe feed and the round keep running underneath, so the price, balance bar and war log stay live.
- stream.
binance. Connectedcom - data-stream.
binance. Not neededvision - stream.
binance. Not neededus
- On arrivalEvery trade, book and ticker is checked: sizes must be real numbers and prices above zero.
- If notThe message is dropped. One bad number would otherwise poison the balance bar for the rest of the session.
- Empty bookA book with no levels does not count towards Live.
Under the hood
Feed
- 3streams per pair on one socket: trades, top 20 book levels every 100 ms, tickersrc/
core/ feed. ts - 3markets to choose from: XRP/BTC, XRP and BTCindex.
html, src/ core/ market. ts - 4pairs behind the synthetic XRP/BTC view, two for each coinsrc/
core/ market. ts - 1 swatchdog intervalsrc/
core/ feed. ts - 3reconnect attempts, 0.8, 1.6 and 2.4 s apart, before the demosrc/
core/ feed. ts
Battle rules
- 60 sper round, one per one-minute candlesrc/
core/ config. ts - $1,500net dollar gap under which a round is a drawsrc/
core/ config. ts - $3,800of resting orders fields one soldiersrc/
core/ config. ts - 250soldiers per side at most, 500 on the fieldsrc/
core/ config. ts - 60soldiers at most from any single tradesrc/
core/ config. ts
Rendering
- 1.5×pixel density cap at 1,024 px wide and below, 2× abovesrc/
render/ scene. ts - 1,024px shadow map on phones and tablets, 2,048 on desktopsrc/
render/ scene. ts - 260instances per soldier class, just over the 250 capsrc/
render/ render3d. ts - 30 stime limit on loading the 3D scenesrc/
main. ts
Tests
- 28interface tests in Playwright: 16 test blocks, two of them repeated per viewport, from 320 to 1,440 pxtests/
hud-ui. spec. ts - 44 pxminimum touch target, checked on phone controlstests/
hud-ui. spec. ts - 2automated accessibility scans, phone and desktoptests/
hud-ui. spec. ts - 6feed tests: 5 lifecycle tests on a fake clock and fake socket, and 1 for number formattingsrc/
dev/ feedtest. ts - 6headless simulation scripts on fixed seeds: formation (16 checks), combat, balance, faction fairness, lifespan, troop trimmingsrc/
dev/
Live chat
- 280characters per messageworker/
index. ts - 30 sbetween messages from one connectionworker/
index. ts - 3connections at most from one addressworker/
index. ts - 50messages replayed to someone joiningworker/
index. ts
What it shows
The same pattern runs behind an operations dashboard: take a fast, noisy data source, decide what a person needs to see, show it in a way that reads in seconds, and make every failure visible and recoverable. That is the work we do for clients, whether the stream is market data, warehouse scans or support tickets.
Under the hood
- TypeScript
- Three.js
- Vite
- Exchange WebSocket streams
- Cloudflare Workers
- Durable Objects
- Playwright
- axe-core
01Exchange streams
Trades, top-20 order book depth and the ticker arrive over public WebSockets, with failover across three hosts.
02Feed
A watchdog spots stale data. If no feed connects, a demo generator keeps the scene alive and says so.
03Simulation
Each trade sends soldiers in, order book depth sets army size, and every 60-second candle is one round.
04Renderer
Three.js with instanced units and baked animation, so hundreds of soldiers stay smooth on a phone.
05Interface
Price, momentum, the round score and a war log of large trades, on desktop and mobile.
06Live chat
A Cloudflare Worker and Durable Object run the chat, with message limits, rate limits and a per-address connection cap.