Skip to content

The market

Six coins this city made up, a price that moves whether anybody is watching or not, and a way to send a holding from one phone to another without a bank hearing about it.

Nothing in it ever asks the outside world what anything is worth. The prices are your server’s.


Opens atSwingWhat it is
Santocoin SNT$42,0003%The first one the city made. Slow, heavy, in everybody’s wallet
Vinewood VNW$3,2008%Fame, priced by the hour
Bayview BAY$1802%Dull on purpose. Somewhere to put money while you decide
Dustcoin DST$1215%Out of the county, and it has been to the moon twice already
Voltline VLT$6409%Power, water and roads. Boring until the lights go out
Omen OMN$422%Nobody knows who made it

Take one out of the config and it stops existing. Nobody’s holding is deleted for it — put the coin back and everybody has what they had.


shared/config/crypto.lua:

Tick = 300, -- seconds between one price and the next
Volatility = 1.0, -- every coin's swing, multiplied. One number for the whole market
History = 48, -- how many prices the chart remembers
Shock = { Chance = 0.02, Size = 0.22 }, -- rare, and the reason anybody checks twice a day
Fee = 0.02, -- the house, on the way in and on the way out
Trade = { Min = 10, Max = 250000 }, -- what one order may be, in money

And per coin: the price it opens at, its Swing, a Drift that biases it up or down over weeks, a Floor and a Ceiling it never leaves, and a Depth — the money it takes to move that coin one percent when somebody trades it. A thin coin is one a rich player can walk up on their own, which is what makes a thin coin worth holding and worth fearing. Depth = 0 means orders do not move the price at all, which is simpler and much easier to farm.

Icon gives a coin its picture; a coin of your own with none falls back to a drawn glyph, and then to the first letter of its symbol.


Wallet = 'character', -- or 'device'

In character mode a stolen phone shows the thief an empty app. In device mode the phone is the wallet, and stealing one takes the portfolio with it.

It ships on character, because the other one turns every mugging into a bank robbery and that should be somebody’s deliberate choice rather than a default.


A price is in cents and a holding is in millionths of a coin, both whole numbers the whole way through, both rounded against whoever is trading, with the commission on top. Buying something and selling it back in the same second always costs money — a market where that comes out even is a market where a loop of buy-sell-buy-sell prints money.

The client is never asked what a coin is worth and never sends a price. Every write to a wallet is behind a lock, because reading the holdings, moving the money and writing them back is three steps with a yield between each of them, and two orders in the same tick would otherwise both sell the same coins.


exports.mic_phone:Coins() --> every coin, with price, change and history
exports.mic_phone:CoinPrice('santo') --> 42137.55, in money
exports.mic_phone:GetCrypto(src, 'santo') --> 0.4218
exports.mic_phone:GetCryptoValue(src) --> the whole portfolio, in money
exports.mic_phone:AddCrypto(src, 'omen', 12.5) --> a hack that pays in coin, a mining script
exports.mic_phone:RemoveCrypto(src, 'omen', 12.5) --> false when they did not have it, and nothing moves
exports.mic_phone:SetCoinPrice('omen', 0.4) --> move the market for a story

RemoveCrypto refuses rather than going negative, so its answer is also were they able to pay — which is the question a shop selling something for coin is actually asking:

if exports.mic_phone:RemoveCrypto(src, 'omen', price) then giveThem(thing) end