Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

v0 source realm

v0 - Unaudited: This is an initial version that has not yet been formally audited. Use in production at your own risk.

Overview

v0 - Unaudited: This is an initial version that has not yet been formally audited. Use in production at your own risk.

Package arena holds the paid games of gnofly, a multiplayer plane game. A player pays an entry price in ugnot to join a game, the realm keeps the stakes until the game is over, then credits them by a rule it applies itself. Winners take what they are owed with Claim.

Games are created off chain, by the game server at a player's request, and described by a spec (see spec.gno): mode, entry price, seats, lives, game time and kill target. The realm only stores a game once someone paid for it, and forgets it when it is over or its lobby empties: no game nobody played is ever left on chain.

Four kinds of callers write to it:

  • players enter a game with their stake attached, the first one handing the realm its spec, and may leave again until it starts (Enter, Leave);
  • referees, the game servers, start a game with the players of its lobby, and report who died by whose hand when it is over (StartRound, SettleRound, CancelRound);
  • anyone can send the stakes of a game back to its players once the referee is long overdue, and close a lobby whose game never started an hour after it was created (RefundRound, ExpireLobby);
  • the admins of the game realm set the refund delay (SetRefundDelay).

The realm keeps no roles of its own: the owner, the admins, the referees and the treasury are those of gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/game/v0, asked at the time of each call.

The referee is trusted for facts only: who died, and by whom. What these facts are worth is decided by a rule of gno.land/p/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/payout/v0, picked by the mode of the game, and the realm checks what the rule returns before it sends anything.

Money

The realm owes exactly the stakes of its lobbies and of its running games, and the winnings not claimed yet, and counts them in one number, see Escrowed. Every coin that leaves goes to a player of the game it came from, or to the treasury of the game realm:

Example
1Enter        +stake   the envelope of the call stays in the realm
2Leave        -stake   back to the player
3ExpireLobby  -stakes  back to the players of the lobby
4StartRound    0       stakes move from the lobby to the game
5SettleRound  -fee     the fee leaves, the rest is credited to the winners
6Claim        -owed    everything credited to the caller, every game at once
7CancelRound  -pot     back to the players of the game
8RefundRound  -pot     back to the players of the game

A game is closed by exactly one of SettleRound, CancelRound and RefundRound, once.

What a settlement does not pay to the players is the house's cut, a fee of 5% sent to the treasury of the game realm, rounding included.

Reads are plain functions meant for vm/qeval. The ones ending in JSON return a single string holding a JSON document. Render exposes the same data as markdown for gnoweb.

Functions 21

func ArenaJSON

Action
1func ArenaJSON(id string) string
source

ArenaJSON returns one arena in the shape of ArenasJSON, or null.

func ArenasJSON

Action
1func ArenasJSON() string
source

ArenasJSON returns every arena someone paid into and whose game is not over, as a JSON array sorted by id:

Example
1[
2  { "id": "3f2a...", "mode": "deathmatch", "stake": 10000000,
3    "minSeats": 2, "maxSeats": 8, "lives": 3, "seconds": 900, "killTarget": 5,
4    "creator": "g1...", "created": 1790950000, "nonce": "k3x9",
5    "lobby": [ { "address": "g1...", "ticket": "9f86d0...00a08" } ],
6    "round": { "startedAt": 1790950300, "players": [ "g1...", "g1..." ] } }
7]

The output has no whitespace. "round" is null until the game starts. The fields from "mode" to "nonce" are the arena's spec: the game server rebuilds the spec string, and so the id, from them.

func CancelRound

crossing Action
1func CancelRound(cur realm, id string)
source

CancelRound closes the game of an arena without a result: every player gets their stake back in full. Referee only.

The game server uses it for a game it cannot referee, for example one it finds running when it starts.

func Claim

crossing Action
1func Claim(cur realm) int64
source

Claim sends the caller everything the realm owes them from settled games, and returns the amount in ugnot. It panics when there is nothing to claim.

func Claimable

Action
1func Claimable(addr address) int64
source

Claimable returns what a player can claim, in ugnot.

func ClaimsJSON

Action
1func ClaimsJSON(addr address) string
source

ClaimsJSON returns what a player can claim, game by game, oldest first:

Example
1{ "address": "g1...", "total": 19000000, "games": [ { "id": "...", "amount": 19000000 } ] }

The output has no whitespace. An address with nothing to claim returns the same shape with a zero total and no game.

func EarningsJSON

Action
1func EarningsJSON() string
source

EarningsJSON returns the top winners as a JSON array, best first, at most 10 entries:

Example
1[ { "address": "g1...", "won": 19000000, "rounds": 3 } ]

The output has no whitespace. "won" adds up, round after round, what the player was paid above their own stake, never less than zero for a round. "rounds" is how many settled rounds they played. With equal winnings, the player who got there first stays ahead.

func Enter

crossing Action
1func Enter(cur realm, spec string, ticket string) string
source

Enter puts the caller in the lobby of the arena that spec describes, and returns its id. The exact stake must be attached to the transaction (-send "<stake>ugnot") and stays in the realm until the player leaves or the game is over.

The first entry creates the arena, the next ones join it: the realm recomputes the id from the spec every time. An arena takes entries for an hour after it was created, and until its game starts.

ticket is 64 lowercase hex characters, the SHA-256 of a secret the player's client made up: the game server gives the seat to whoever shows the secret.

It must be called directly by a user (maketx call): a call relayed by another realm or by a maketx run script is refused.

func Escrowed

Action
1func Escrowed() int64
source

Escrowed returns what the realm owes to players, in ugnot: the stakes of every lobby and of every running round. The balance of the realm's address is never below it.

func ExpireLobby

crossing Action
1func ExpireLobby(cur realm, id string)
source

ExpireLobby closes an arena whose game never started: every player in the lobby gets their stake back, and the arena is deleted. Anyone can call it once the arena stopped taking entries, an hour after it was created.

func Leave

crossing Action
1func Leave(cur realm, id string)
source

Leave takes the caller out of the lobby of an arena and sends their stake back. It works until the game starts. The last player out deletes the arena: nothing is left on chain of a game nobody played.

func PlayerJSON

Action
1func PlayerJSON(addr address) string
source

PlayerJSON returns one player's totals as a JSON object:

Example
1{ "address": "g1...", "won": 19000000, "rounds": 3 }

The output has no whitespace. An unknown address returns the same shape with zero won and zero rounds.

func RefundRound

crossing Action
1func RefundRound(cur realm, id string)
source

RefundRound closes the game of an arena without a result, like CancelRound, and can be called by anyone, once

Example
1startedAt + seconds + RefundDelay()

has passed on the block clock. It is the players' way out when the referee never settles: no stake depends on a server staying up.

func Render

1func Render(path string) string
source

Render returns the state of the arenas as markdown, for gnoweb:

Example
1""            the open arenas and the last games played
2"arena/<id>"  one arena: its rules, lobby and game, or its result
3"earnings"    the top winners

Everything printed here was validated against a narrow charset when it was written (see spec.gno and validate.gno), or is an address the chain gave the realm. The only caller-supplied value, the id of an arena page, is printed only if it is a valid id. Nothing needs markdown escaping.

func ResultJSON

Action
1func ResultJSON(id string) string
source

ResultJSON returns the result of one closed game in the shape of ResultsJSON, or null when the realm does not have it (still running, or too old).

func ResultsJSON

Action
1func ResultsJSON() string
source

ResultsJSON returns the last closed games, newest first, at most 50:

Example
1[ { "id": "3f2a...", "mode": "deathmatch", "stake": 10000000,
2    "outcome": "settled", "players": 2, "pot": 20000000, "fee": 500000,
3    "closedAt": 1790951000,
4    "payouts": [ { "address": "g1...", "amount": 19500000 } ] } ]

func SetRefundDelay

crossing Action
1func SetRefundDelay(cur realm, seconds int64)
source

SetRefundDelay sets how long after a game's time limit anyone may refund it. Admin only.

func SettleRound

crossing Action
1func SettleRound(cur realm, id string, deaths string)
source

SettleRound closes the game of an arena: it applies the rule of its mode to what happened, pays the players, and pays the fee to the treasury. Referee only.

deaths is "victim:killer" entries separated by ";", in the order they happened, "victim:" when nobody shot the victim down, and the empty string when nobody died. A player dies at most as often as the arena has lives.

The referee is trusted for these facts and for nothing else. The rule refuses a victim or a killer who is not a player of the round, and decides the amounts. The realm then checks them (see settle) before it pays.

func StartRound

crossing Action
1func StartRound(cur realm, id string) int64
source

StartRound starts the game of an arena with every player of its lobby. Referee only. The lobby must hold at least minSeats players; it holds at most maxSeats, Enter sees to that. No coin moves: the stakes that were owed to the lobby are now owed to the round. It returns how many play.

func Version

Action
1func Version() int64
source

Version returns a counter that bumps on every admin write: the refund delay. Player and referee actions do not bump it.

Imports 12

Source Files 15