nimiq.games logonimiq.games
Developers ยท Rive

Build your game in Rive

Every game on nimiq.games is a .riv file. The store runs it, tells it what the player owns, and handles checkout when the player taps buy.

Starter .rivStarter source
storeA view model the store fills: owned extras and sign-in.
store.buyAn event your buy button fires. The store does the rest.
SignedFiles with scripts must be built with rive --publish.

Start from the starter

  1. Download the starter source, open the folder and run rive . to see it live. Set name in rive.yaml: it names your built file.
  2. Replace the art. Keep the store view model and the two events.
  3. Sign in once with rive login, then run rive push once. Push links the folder to a file in your Rive account; without it, every publish carries Rive's watermark.
  4. Build with rive . --publish and send us build/<name>.riv with your application.

What the store fills in

Bind your art to these. Declare only what your game shows; anything missing is skipped.

PathWhat it holds
store/readybooleanTrue once the store has read the player's purchases
store/signedInbooleanA wallet is signed in
store/ownsGamebooleanThe player owns the full game
store/owned/<key>booleanOne per extra, in a view model named NGOwned
store/busybooleanCheckout is open over your game
store/lastResultstringpaid:<key>, cancelled:<key> or failed:<key>
store/net/*see belowThe answer to your last store.fetch, in NGNet

The store property sits on your main artboard's view model and holds a view model named NGStore. An extra's <key> is its type and key in camelCase: a Character with the key gold-skin is store/owned/characterGoldSkin, and your buy button fires store.buy with that same sku. The apply form shows the exact name next to each add-on.

What your file fires

EventPropertiesWhat the store does
store.buyskuOpens checkout for that extra, then updates store/*
store.fetchid, url, method, bodyCalls your server, writes the answer to store/net

Fire them from a listener on your button. Prices never live in the file: you set them when you apply.

Leaderboards and your own server

RuleValue
WhereOnly the https origins you list when you apply
MethodsGET or POST with a JSON body
SizesBody up to 8 KB, answer up to 64 KB
Rate10 calls per 10 seconds per player, one at a time per id
Timeout10 seconds
CookiesNone are sent. Answer CORS for https://nimiq.games

The store writes store/net/id, status, body and error, then increases store/net/seq last. Watch seq and read the rest. Scripts inside a .riv cannot reach the network on our player, so every call goes through store.fetch.

-- Leaderboard.luau in the starter: fill three rows when an answer lands
self.seq:addListener(function() show(self) end)
-- your server answers {"top":[{"name":"MATT","score":9001}, ...]}

Already calling your server from your own web page's JavaScript? That code does not come with you. Move each call into a store.fetch event and read the answer from store/net.

Signing

Your fileOn nimiq.games
No scriptsPlays as built
Scripts, built with rive --publishPlays, scripts run
Scripts, built without itWe reject it: the scripts would silently not run

rive . --screenshot and rive . --once rebuild the file unsigned in the same place. Copy your published .riv somewhere safe before taking screenshots.

Runtime flags

FlagDefaultSet it when
gpuCanvasonYour file draws black with GPU Canvas on. Some do.
artboardthe firstYour game is not the first artboard
stateMachinethe firstYour game uses a different state machine
fitlayoutYou want contain, cover or fill

Tell us these when you apply. We set them for your game.

Test it before you send it

rive . --verify                                    # compiles your scripts
rive . --data=store/owned/characterGoldSkin=true   # see the owned look
rive . --data=store/net/body='{"top":[{"name":"A","score":1}]}' --data=store/net/id=top --data=store/net/status=200 --data=store/net/seq=1
rive login && rive push                            # once: no watermark on your publishes
rive . --publish                                   # the file you send us
ApplyDeveloper program