A piece can carry state that belongs to a game: a condition that wears down, a charge, a kill count, an enchantment. That state:
It is written to the chain as a small public announcement, so every arcade reads the same state with no server in between. One announcement carries up to 60 pieces, so a game writes once per play session, not once per hit.
{
"game": {"name": "My Game", "family": "my-game"},
"state": {
"publisher": "<the address that writes state>",
"judge": "<the inscription id of your judge>",
"params": {"anything": "your judge reads"},
"show": {"c": "Condition", "k": "Kills"},
"node": "https://… (only if the publisher is not the arcade players use)"
}
}
| Field | What it is |
|---|---|
family |
the id your game's versions share; state is kept per family, so a new version of your game sees the old state |
publisher |
the address whose announcements count, normally your referee node's own address (its /r/referee says it as state_publisher) |
judge |
decides each change (see below) |
show |
how a page labels each key of your state; keys not listed are shown as they are |
A family belongs to the creator who first declared it. Another creator using the same family name is ignored, so nobody can write state for your items by copying your JSON. To change your publisher or judge, inscribe a new version of your game with the same family: your newest declaration is the one in force.
The same kind of judge prize pools and escrows use: judge(seed, inputs, params),
in a sandbox with no network, no clock and no randomness.
function judge(seed, inputs, params) {
// params.items: [{piece, state}]: what the page asks to write
// params.current: {piece: state or null}: what is written now
// params.family: your family id; inputs: whatever the page sent as `replay`
if (wornFairly(inputs, params)) return {update: true};
return {update: false, why: "that run does not wear it that much"};
}
update: true writes exactly the states asked for.
arcade.state<script src="/r/state.js"></script>
<script>
arcade.state.get(swordTxid, 'my-game').then(function (s) {
var condition = s ? s.state.c : 100; // never written: as new
});
// After a session, everything that wore down, in one go:
arcade.state.update([{piece: swordTxid, state: {c: 61}},
{piece: shieldTxid, state: {c: 88}}],
{replay: theSessionsInputs});
</script>
| Call | What it does |
|---|---|
get(piece) |
every game's state for one piece: [{family, game, name, state, seq, height, show}] |
get(piece, family) |
one family's entry, or null if it has written none |
update(items, {replay}) |
asks your game to write new state; resolves {txids, updates} |
{"c": 61}. Keep
it to numbers and short words; it is a record, not a save file.get shows it once its block lands.The same reads work without a page: GET /r/state/<piece> and
GET /r/state/<family>/<piece>.
{"broken": true}. It stays a piece
its owner holds and can trade, and your game treats it as broken.