Detailed references

v3 · Preview

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

Data files

A data file is JSON that the game logic and the client both read, such as a unit table or a card list. Keep one copy in /src/data/, and both halves read it.

Where data files go

  • Write each data file directly in /src/data/, ending in .json: /src/data/goals.json.
  • Name it with lowercase letters, digits and _, starting with a letter or _. The game logic reads it by that name.
  • Each file holds one JSON value. A file that is not JSON fails the build with bw::data-json, which points at the first line and column that does not read.
  • Data files count toward the build's file limits (Source files).

write_file, patch_file and rename_file refuse a .json path in /src/data/ that is not directly in it, or whose name breaks these rules, with UNBUILDABLE_RUST_SOURCE.

Read a data file in the game logic

boardweaver_sdk::data! reads /src/data/<name>.json when Boardweaver builds the game:

Form Gives
data!(goals) the text of /src/data/goals.json, a &'static str
data!(goals as T) that file read as T with serde, a &'static T

Hexbloom keeps its goals in /src/data/goals.json. This function reads them as a typed map:

use boardweaver_sdk::serde::Deserialize;
use std::collections::BTreeMap;

#[derive(Deserialize)]
#[serde(crate = "boardweaver_sdk::serde")]
pub struct Goal {
    pub title: String,
    pub detail: String,
    pub sets: Vec<Vec<usize>>,
}

pub fn goals() -> &'static BTreeMap<String, Goal> {
    boardweaver_sdk::data!(goals as BTreeMap<String, Goal>)
}
  • Write data!(name as T) once, in a function such as goals() above, and call that function. Each place you write data!(name as T) reads the file the first time a call reaches it and keeps its own copy while the match runs.
  • A data! that names a file the game does not have does not compile. The Rust compiler's error names src/data/<name>.json.
  • Make T match the file. When it does not, the first call that reads it panics with a message that names the file and the type. In a match the move fails with GAME_FAILED. Call the function in a unit test, so validate_code reports the mismatch.
  • A change to a data file builds the game logic again on the next commit.
  • Read a value that never changes from a data file, not from the state (Your own types in maps).

Read a data file in the client

Import the file by a relative path or a /src/ path. The import is the JSON value the file holds:

import goalTexts from "/src/data/goals.json";

Write the words a player reads in the catalogs, and keep their message keys in the data file. Hexbloom's goals.json holds "title": "goal.centre.title" (Text in the player's language).

Data only the client reads can live in any .json file under /src/ outside /src/data/, such as /src/client/layout.json. Only files in /src/data/ count toward the build's file limits and build the game logic again when they change.

Need a hand with this?

Join our Discord