Docs: Views

Views: how a game lies on the table

A game has three layers, each in its own file:

LayerFileRead by
Rulesthe modelengine, validator, diagram, player
Playersa tacticthe engine, as a player (see tactics)
Viewa viewthe player: the Board tab of the table

The engine never reads a view: it changes nothing about the rules or the results.

Using a view with your model. In the validator, paste the view into "View (optional YAML)" below the model and press Check. "Open in the player" then opens your model with that view. The validator only checks that the view is readable YAML ("The view cannot be read" otherwise); a slot that names a zone, variable or board the model does not have shows up in the player (for example "board x not found"). The built-in games of the player come with their own views; "Start from" in the validator loads an example together with its view.

Without a view the player lays out the table itself: shuffled or hidden zones as a deck, open zones as a row, a meter for every per-player variable with a numeric init, and an area per player for the zones with owner: player.

Cards are drawn as typographic cards (name, type, numbers, tokens), never as the original artwork. What a viewer sees follows the visibility in the model: in the player you can "view as player p", and hidden zones and other players' hands then show only card backs.

Structure

view: my-card-game                  # label only; the view belongs to the model it is used with

card:
  lang: en                          # language of card names, for hyphenation (default en)
  type_field: type                  # field with the card type (small text in the colour band)
  type_names: {hero: Hero, ally: Ally}            # optional: display names of the types
  color:                            # colour band: the first entry that matches
    - {field: sphere, values: {leadership: "#6d4c9f", tactics: "#a53a2c"}}
    - {field: type, values: {enemy: "#6b4a32"}}
  corner: [cost, threat]            # number top right: the first of these fields the card has
  stats:                            # numbers at the bottom, with an icon
    - {field: willpower, icon: "✦", name: willpower}
    - {field: hp, icon: "♥", name: hit points}
  tokens:                           # numbers on the instance shown as tokens on the card
    damage: {color: "#c0392b", name: damage}
  sideways: exhausted               # turn the card sideways while this property is true

table:                              # the middle of the table, row by row
  - row:
      - {zone: encounter_deck, as: deck}
      - {zone: encounter_discard, as: discard}      # top card face up
      - {quest: {var: quest_card, catalogue: quests, progress: progress, goal: quest_points}}
      - {zone: staging, name: staging area, wide: true}

player:                             # the area of every player (per-player zones show that player's part)
  - row:
      - {meter: {var: threat, max: 50, name: threat}}
      - {zone: heroes, attachments: {zone: attachments, field: host}}
      - {zone: hand, small: true, wide: true}

card

KeyTypeDefaultMeaning
langtextenLanguage of the card names (the lang attribute, for hyphenation)
type_fieldtexttypeField that holds the card type
type_names{type: name}Display name per type; otherwise the type itself
colorlist of {field, values}Colour band: the first entry whose field value is in values. No match: a colour derived from the type
cornerlist of fieldsNumber in the top right corner: the first listed field that holds a number
statslist of {field, icon, name}the first 4 numeric fields of the content itemNumbers along the bottom; name is the tooltip
tokens{property: {color, name}}Numeric properties of the instance shown as coloured tokens. Without tokens, every positive number on the instance that the content item does not have is shown as a token
sidewayspropertyThe card is turned sideways while this property is true

A card's fields are the content item's fields (looked up by id) overlaid with the current properties of the instance. Properties that are true (other than sideways) show as tags.

table and player

Both are lists of rows: - row: [slot, slot, ...]. table is drawn once; player once per player, and a per-player zone in it shows that player's part.

SlotKeyMeaning
ZonezoneName of a zone in the model
asrow (all cards side by side), deck (a face-down pile with a count) or discard (a pile with the top card face up, if the viewer may see it). Default: deck for shuffled or hidden zones, row otherwise
nameHeading; default the zone name
wideTake the rest of the row
smallSmaller cards
attachments: {zone, field}Cards from that zone whose field equals the uid of a card in this zone are shown under it
Metermeter: {var, max, name}A dial for a numeric variable; for a per-player variable, that player's value. max default: the larger of 10 and the value
Questquest: {var, catalogue, progress, goal}A landscape card: the item content[catalogue][<value of var>] (or the content item with that id), with the variable progress against goal (a derived value or variable; default the card's quest_points)
Gridboard: {zone | var, columns}A grid of cells from a zone or a list variable, columns wide (default 3); None shows as empty
Boardboard: {geometry, ...}A board from the model's boards with pieces; see below

Every slot may have a name. Cards that are new since the previous request get a highlight, and a meter shows its change.

The smallest view, for a 3 × 3 grid kept in a zone board:

view: tictactoe
table:
  - row:
      - {board: {zone: board, columns: 3}, name: board}

Boards with geometry

A board from boards (see board geometry) is drawn with the same geometry as the engine: square with coordinates, hex with gaps drawn as walls, walls between cells as lines. Cells that changed since the previous request get a highlight (in chess: the from and to squares).

table:
  - row:
      - name: chessboard
        board:
          geometry: board                 # name in the model's boards
          pieces: {var: pieces}           # a dict cell → piece
          checkered: true
          flip: true
          names: true
          icons:
            wK: {icon: "♚", color: white}
            bK: {icon: "♚", color: black}
      - name: dungeon
        board:
          geometry: map
          pieces: {zone: figures, field: cell}           # instances with a property cell
          color: {field: side, values: {hero: "#2f6fb3", monster: "#a53a2c"}}
          value: hp                                      # number on the token
          cells:                                         # highlighted cells (with a legend)
            - {const: OBSTACLES, color: "rgba(120, 100, 70, .65)", name: obstacle}
            - {const: TERRAIN, color: "rgba(110, 160, 80, .42)", name: difficult terrain}
KeyMeaning
geometryName of the board in the model's boards. Unknown: a "board not found" notice
pieces{var}: a dict cell → piece (text, or a dict whose label or id names it). {zone, field}: the instances in a global zone, placed on the cell in their property field (default cell); fixed fields come from the content item, or from a dict with that id in constants
iconsPiece label (or id) → icon text, or {icon, color} with color: white, black or a CSS colour. Without an icon: a round token with the first letters of the label
color{field, values}: token colour from a property of the piece
valueProperty shown as a number on the token
cellsList of {const | var, color, name}: the cells in a constant or variable (a list of cell names, or a dict whose keys are cell names) get that colour; name goes into the legend
checkeredAlternate light and dark squares (square boards)
flipTurn the board around when viewing as player 1
namesShow cell names (square: a–h and 1–8 for letters boards, else numbers; hex: the cell name in each cell)

Clicking a piece or card shows its properties. Complete views, used by the player for the built-in games of the same name: chess, hex-skirmish and tictactoe.

This page as Markdown