Game logic

v3 · Preview

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

Game messages and logs

Messages from the game logic

The game logic sends no finished text. A log line, an offer's label and a refusal's reason are each a message: a key in the catalogs and the values of its placeholders, built with msg!. Each viewer's client formats it in their own language.

table.log(msg!("log.marks", cell = space_id.as_str()));
{ "log.marks": "{player} marks cell {cell}" }
  • {player} is the line's player. Boardweaver fills it, so a msg! never passes it. Place it where the language needs the name, or leave it out of a message that names no one.
  • A value is a number, text, a seated player, another message or a link. The table of values is in Log lines.
  • The build checks each msg! whose key is a string literal against the default catalog. It does not check a key built at run time. Such a key shows as itself when no catalog has it.
The game log lists moves and links to earlier positions in the match.
The game log lists moves and links to earlier positions in the match. Example data from the local development UI. Select the image to enlarge.

Log lines

table.log(line) adds a line to the step's log, which every viewer sees in the match's history. A step may write several lines, and so may setup for the opening. A line is a message: a key in the game's catalogs (Text in the player's language) and the values of its placeholders. Each viewer's client shows it in their own language. Build a message with msg! and log it as a line by the seat that took the step:

table.log(msg!("log.marks", cell = space_id.as_str()));
table.log(msg!("log.plays", card = link(face.clone(), msg!(format!("card.{face}")))));

Write each message in the catalog of the game's default locale, such as /src/i18n/en.json:

{
  "log.marks": "{player} marks cell {cell}",
  "log.plays": "{player} plays {card}"
}

Boardweaver fills {player} with the line's player, shown by name. Leave {player} out of a message that names no one. Import msg, link and player from boardweaver_sdk.

The build checks every msg! whose key is a string literal against the default catalog. Each of these fails to compile, with the error at the msg!:

  • a key the catalog lacks;
  • a value its message has no placeholder for;
  • a placeholder no value fills;
  • a tag, such as <b>;
  • a value named player.

The build does not check a key built at run time, such as msg!(format!("card.{face}")). When no catalog has it, the line shows as its key.

A placeholder takes one of these values:

Value Write Shows
a number count = 2, an i64, i32, u32 or usize the number in the viewer's language. Count with it in a plural: {count, plural, one {# card} other {# cards}}
text name = "Ys", a &str or a String the text as it is, in every language, such as a name a player typed
a seated player target = player(id) the player's name
another message card = msg!("card.knight") that message in the viewer's language, such as a card's name
a link card = link(key, msg!("card.knight")) the message as a control that useLogLinks hears. key is your own string, such as a card id

To give a line another player, no player or a kind, build it with LogLine::new(message) and these methods. Import LogLine and LinePlayer from boardweaver_sdk.

Method Sets Default
.player(LinePlayer::Seat(id)) whose line it is, which {player} names: LinePlayer::Actor, LinePlayer::Seat(id) or LinePlayer::None LinePlayer::Actor, the seat that took the step
.kind("combat") a label the client styles the line by: 1 to 32 characters of a-z, 0-9 and - none
table.log(LogLine::new(msg!("log.round", round = 2)).player(LinePlayer::None));
  • Every viewer reads every line, whatever they may see of the state. Name only public facts: "takes a card", never the card. This holds for the message, its values, the link keys, the kind and the player.
  • A line with LinePlayer::None whose msg! has a literal key and a message that places {player} panics, since there is no player to fill it. With a key built at run time, the line shows as its key instead.
  • Write a line in each step that players should see as its own row in the game log. A step that writes no line joins another row (Other players' steps).
  • player(id) and LinePlayer::Seat(id) name a seated player. Any other id panics.
  • A Message given a value named player by .arg panics: Boardweaver fills player itself.
  • On the opening, give a line that uses {player} a LinePlayer::Seat(id). LinePlayer::Actor has no player there, because no seat took the opening, and the line shows as its key.
  • A step's lines have limits (Builds, limits and errors). Going past one panics.
The game log lists moves and links to earlier positions in the match.
The game log lists moves and links to earlier positions in the match. Example data from the local development UI. Select the image to enlarge.

Need a hand with this?

Join our Discord