You are building the rules pages for a BoardWeaver game: the styled, illustrated pages a player reads to learn how to set up and play. Each page is a file at /src/rules/<slug>.bwss — a JSON document holding a BWSS tree. At commit time the platform compiles every .bwss source into a standalone HTML page; you never write HTML yourself.
This is reference-and-art work, not gameplay logic. A rules page renders no live state and dispatches no actions — it is static, themed presentation: headings, prose, diagrams, piece illustrations, and links between pages.
Work against a single, already-selected game.
game_definition_id yet, call list_my_games and have the author pick one. Only ever touch that one game.get_game to read the game's name, description, mood, and voice, and list_files to see what already exists under /src — existing rules pages, a theme, the game code./src/rules/index.md, read it: it is the author's written rules and the best source for what the pages must cover. (index.md is ordinary markdown text — separate from the styled .bwss pages you build here.)Rules pages should look like they belong to the game. If the game has no theme yet, develop one before writing any rules. Building rules first means redoing them once the visual world exists.
/src/theme.html (the visual style reference) and /theme.json (the structured theme document with $-tokens). Read v2-design-theme-instructions and v2-game-themes for how these are produced.design-game / theme step), or do it now. A theme gives you a palette, typography, and mood to design the rules pages against, and /theme.json $-tokens you can reference directly in BWSS styles.Before writing a single .bwss file, agree with the author on the outline: what pages exist and what each one covers. Don't guess the structure — converge on it together.
index — overview, components, and the goal of the gamesetup — how to set up the boardplay — turn structure and the actions a player can takescoring — how the game ends and how to win/src/rules/<slug>.bwss → compiled page <slug>.html. Pages link to each other by slug (see Anchor below). index is the conventional landing page.Each /src/rules/<slug>.bwss file is one JSON value: a single root BWSS node (almost always a Box) with nested children. Write the file with write_file, passing the game_definition_id and the full JSON.
The rules surface allows four node types:
type |
Purpose |
|---|---|
"Box" |
Generic flex container. children are nested nodes or plain text strings. |
"Image" |
{ src: GameImageKey, alt?, style? } — a game image by key. Unknown keys render nothing. |
"Svg" |
{ viewBox: {width,height}, paths: [{d, fill?, ...}], style? } — inline vector art. Only <svg> + <path> are emitted. |
"Anchor" |
{ href, style?, children? } — a hyperlink. Rules pages are the only surface with links. |
Text is a plain string child inside a Box (or Anchor) — there is no Text node. Style text by setting typography fields (fontSize, fontWeight, color, textAlign, …) on the enclosing Box.
Styling is the standard BWSS allow-list — the same strict, structured style object the marketing surface uses. Read v2-page-styling for the full property list and value grammar. The essentials:
border/background/font shorthands).rgb()/rgba(), named colors, or a $-token ($colors.surface.canvas). No url(), var(), calc().<number>(px|%|em|rem) string, or a $-token. No vh/vw/calc().$colors.*, $semanticTokens.*, $spacing.*, $fonts.*) over hardcoded values so pages track the theme. Tokens resolve against /theme.json; with no theme, $-tokens resolve to nothing, so supply concrete fallbacks if you skip theming.AnchorAnchor.href is validated to internal targets only. Allowed shapes:
setup — a bare sibling page slug (the filename of another .bwss, without extension). Compiles to setup.html.setup#step-2 — a slug plus a fragment.#overview — a same-page fragment.Everything else is rejected: http(s):, javascript:, data:, protocol-relative //host, absolute /path, and ... You cannot link off-site.
Fragment targets — the id field. To make a #fragment link land somewhere, give the destination node an id: set id on the Box (or Anchor) you want to jump to, then link to it with href: "#that-id" on the same page or href: "slug#that-id" from another page. An id must be a fragment identifier — a letter, then letters / digits / _ / - (e.g. "scoring", "step-2"). id is a rules-surface field on Box and Anchor only; to anchor to an Image or Svg, wrap it in a Box with an id.
{ "type": "Box", "children": [
{ "type": "Anchor", "href": "#scoring", "children": ["Jump to scoring"] },
{ "type": "Box", "id": "scoring", "children": ["Scoring rules…"] }
] }
An Anchor wraps content like a Box — its children can be text, an Image, or nested styled boxes (e.g. a card-shaped link to another page).
{
"type": "Box",
"style": {
"display": "flex",
"flexDirection": "column",
"gap": 16,
"padding": 24,
"backgroundColor": "$colors.surface.canvas",
"color": "$semanticTokens.fg.default"
},
"children": [
{
"type": "Box",
"style": { "fontSize": 28, "fontWeight": "bold", "fontFamily": "$fonts.display" },
"children": ["How to Play"]
},
{
"type": "Box",
"children": ["On your turn, place one tile, then draw back up to three."]
},
{
"type": "Anchor",
"href": "scoring",
"style": { "color": "$colors.accent.default", "fontWeight": "bold" },
"children": ["Next: Scoring →"]
}
]
}
Rules pages compile at commit time, not on save. After writing the .bwss files:
commit tool — a developer message (e.g. "Add setup and scoring rules pages") and a player-facing changelogMessage (e.g. "Added illustrated rules.")./src/rules/*.bwss source is validated and rendered to a hidden /rules/<slug>.html artifact. The compile uses the committed theme and game images, so it tracks the current look..bwss is invalid JSON or violates the rules-surface schema, the commit fails with RULES_COMPILE_FAILED and rolls back — nothing partial is committed. Read the error (it names the file and the reason), fix the tree, and commit again..bwss and re-committing regenerates the pages; stale pages for deleted sources disappear.game_definition_id); existing files reviewed.Box / Image / Svg / Anchor; text as string children.#fragment links have a matching id on their target; styles use theme tokens where possible.RULES_COMPILE_FAILED errors resolved.