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 |
Two rules follow, and a game must keep both:
- Every state inside an open decision offers at least one
ChoiceorConfirm. A bot ignoresCancel, so it must always have something else to take. - A
Choicenever returns the decision to a state it had before. A bot taking onlyChoiceandConfirmmust always reach 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. Thetakecommand is aConfirm.
#[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:
- The step drew from
Rng: the decision ends, whatever the step's intent. - The step is a reveal: the decision ends.
- The step's intent is
Confirm: the decision ends. - Otherwise the decision stays open.
So only the last step of a decision can draw randomness or reveal. Plan multi-step moves so the random or revealing part comes last.
Undo
Undo is not an intent and not an action: it is the platform's, and the client shows its button. The game logic allows it with table.allow_undo() (Changing the state).