Game logic

v3 · Preview

Framework v3 is an opt-in preview available to everyone. New games use the stable framework by default.

Decisions, drafts, and Undo

Intents

Intent Means Bots
Choice Adds new information to the open decision and moves it forward. take it
Confirm Ends the decision and sends it. take it
Cancel Changes or takes back something already chosen in the open decision. ignore it

Keep both of these rules:

  1. Every state inside an open decision offers at least one Choice or Confirm. A bot ignores Cancel, so it must always have something else to take.
  2. A Choice never returns the decision to a state it had before. Then a bot that takes only Choice and Confirm always reaches the end.

Worked example: a draft of 12 cards

The seat stages one card, may switch to another, and then takes the staged card.

  • Nothing staged: each of the 12 cards is a Choice.
  • One card staged: the other 11 cards are still offered, so the seat can switch, but as Cancel. The take command is a Confirm.
#[derive(Default, Serialize, Deserialize)]
#[serde(crate = "boardweaver_sdk::serde", default)]
struct Pick {
    staged: Option<usize>,
}

fn offers(table: &Table, player_id: PlayerId) -> Vec<Offer> {
    let pick: Pick = table.state().read(StateOf::PlayerPrivate(player_id));
    let switch = if pick.staged.is_some() { Intent::Cancel } else { Intent::Choice };
    let mut offers: Vec<Offer> = (0..table.state().space("market").pieces.len())
        .filter(|&index| pick.staged != Some(index))
        .map(|index| {
            Offer::new(Action::PieceClick { space_id: "market".into(), index }, switch)
                .label(msg!("offer.stage", card = index))
        })
        .collect();
    if pick.staged.is_some() {
        offers.push(Offer::new(Action::command("take"), Intent::Confirm).label(msg!("offer.take-staged")));
    }
    offers
}

The common mistake is to tag the 11 switches as Choice. Then staging card A, then card B, then card A again returns the decision to a state it had, and a bot can switch between cards forever.

What ends a decision

A decision stays open, as the seat's draft, until a step ends it. The first rule that applies decides:

  1. The step drew from Rng: the decision ends, whatever the step's intent.
  2. The step is a reveal: the decision ends.
  3. The step's intent is Confirm: the decision ends.
  4. Otherwise the decision stays open.

So only the last step of a decision can draw randomness or reveal. Put the random or revealing step last in a decision.

Undo

Undo is not an intent or an action. Boardweaver provides it, and the client draws its button. Allow it with table.allow_undo() (Changing the state).

Need a hand with this?

Join our Discord