Building a real market into a browser MMO
Building a real market into a browser MMO
Last week I posted that Void Ward's player market was live. A fellow dev replied with the question that cuts straight to the heart of it: "gnarliest part keeping the book consistent across clients?"
That is the right thing to ask. So here is the full answer, plus the story of why a free browser game ended up with a working exchange inside it.
What the market actually is
Void Ward now has a Market page in the top nav, reachable from anywhere, whether or not you are docked. It is the only place to buy and sell items, and it behaves like a real exchange rather than a shop with fixed prices.
The market opens in Buy mode: every item shows the best ask and how many units are listed.
If you just want to trade, there is a big Buy/Sell toggle. Tap Buy and you take the item at the best price on the book. Tap Sell and it goes straight from your station storage. One tap, done.
If you want more control, every row has a "Price" drawer that opens the live order book. Place a limit order at your own price and wait for someone to meet it. Orders match best price first, then oldest first, and they can fill partially. A 1% listing fee on resting orders and a 1% tax on every sale keep credits draining out of the economy so prices stay honest.
Open the drawer and you are looking at the real book: live depth, your own orders, and a ticket to set your own price.
There is one NPC trader on the book, the NOC. It always buys Ore at a guaranteed floor price, so new players can sell what they mine from day one, and it stocks the basic starter-tier gear at a small markup so players can undercut it. Everything past that is traded between players only. The NOC sits on the same book as everyone else: same rows, same matching, no special channel.
Why a real order book
I could have stuck a fixed buy and sell price on every item and saved myself a lot of trouble. I did not, because the economy is the point.
Void Ward is built around players doing the work: mining ore, refining it into iron, building parts, then selling the results. If the game sets every price, none of that matters. A real order book means prices come from supply and demand. Flood the market with one ore and watch its price slide. Find something rare and watch people bid for it. That loop only works if the market underneath it is real.
Sell mode lists what is in your station storage. Pick a stack, name a price, or take the best standing bid.
The hard part: keeping the book straight
Back to the dev's question. With plenty of players hitting the same market at once, how do you stop the order book from falling out of sync?
First, the thing that surprises people: Void Ward has no traditional game loop. Movement, mining and refining are all small jobs on a queue that run on their own clock. The queue is the engine, not a tick running sixty times a second.
The market is the one place that does not fit that mould. An order has to resolve the instant you place it. You cannot queue "did I get the last unit?" and answer it half a second later, because the player is sitting there watching the button. So order placement and matching run right there in the request, and I wrap the whole thing in a single database transaction.
The consistency comes from the database, not the queue. When your order matches against the resting orders on the other side, it locks those rows for the length of the transaction. Picture two buyers going for the last unit at the same price in the same instant. Both reach for the same resting sell order. The database hands the lock to one of them. That buyer fills the unit, takes it off the book, and commits. The other buyer was waiting on the lock the whole time. The moment it lifts, their order re-reads the book and finds the unit gone. One buyer wins, the other gets a clean "sold out," and nothing sells twice.
Credits get the same protection from a different angle. Every wallet change carries a version number and only applies if that number still matches, so two transactions cannot stomp the same balance. If anything collides, the transaction rolls back and tries again.
Only once it commits does the server broadcast the new state of that item's book over websockets. Every open client picks up the update and merges it into the book in place. The screen you are looking at is a mirror of what already settled on the server, never a guess that might disagree with the player next to you.
It took more care than anything else in the feature, and it is a different shape of problem from the rest of the engine. The rest of the game is about scheduling things for later. This one is about settling a thing exactly once, right now, even if three people asked in the same millisecond.
Where it fits
The market is the thing the rest of the game feeds into. Refining turns ore into iron, iron goes into building, and the market is where all of it changes hands. Combat and gate building are still on the way, and when they land they will plug straight into the same economy.
It is a strange feeling to build a working exchange into a game anyone can open in a browser tab. But that is the kind of thing that makes Void Ward fun to work on.
If you want to follow along as more of this gets built, I post updates often. The game is at voidward.com.
Be on the bridge when the first gate opens.
One email when the alpha opens its doors. The build log stays public until then.
You're on the manifest. One transmission when the gates open.