Tutorial: build a game in the workshop
In half an hour you turn the workshop's small starting game into a game of your own, check it, play it, let the computer play it a thousand times and share it by link. You need no code: the rules are written as data, and the workshop's tabs let you edit the cards, the flow and the table as tables, trees and chips. Where a line of text is needed, this page gives it.
The workshop keeps your games in your own browser; nothing is uploaded until you share a link or a package yourself.
1. Start from Fifteen
Open the workshop. The first visit shows Fifteen, a complete two-player card game: play a number card from your hand onto your pile and draw one; reach exactly 15 to win, go over and you lose. The left side holds the game in tabs, the right side looks at it:
| Left: the game | Right: what the workshop makes of it |
|---|---|
| Model – the rules, as YAML text | Check – errors, warnings, how much of the model the engine can run, 20 random test games |
| View – how the table looks (optional) | Rules – the rules as a track, as people read them |
| Tactic – how the computer plays (optional) | Table – the table, in 2D or 3D, with a slider through a computer game |
| Flow, Cards, Layout – the flow, the content and the table layout as a tree, tables and chips | Play – play it yourself |
| Images – your own pictures | Simulate – many games at once, and experiments |
Press Check: No errors, 100% executable, 20/20 test games end. Press Play and play a round against the computer to see the game. Then New › A small card game to change (Fifteen), name it Twenty-one, Create. We make three changes: a higher target, a new card and a new choice.
2. A constant: the target
Open the Model tab. Near the top:
constants:
TARGET: 15
HAND: 3
Change 15 into 21. The three green badges stay green: every rule that mentions the target
(total[current] == TARGET) follows. Texts for people do not: the summary and the end conditions
still say 15; change the summary a few lines above (summary:) and the two end conditions at
the bottom (if: "the current player has exactly 15") to 21. The Rules pane shows the words
you write there.
3. A card: the Cards tab
Open Cards. The group cards shows the seven number cards as a table: id, label, value,
suit, status. Press + card: a new row appears with a placeholder id and label. Make it id eight, label
Eight, value 8, suit sun, status verified. Every cell you leave goes straight into the model text
(look at the Model tab: the new line is there, in the same style as the others). Add a nine the
same way.
The deck is built from the cards (init_x: "[c for c in content['cards'] for i in range(2)]":
two copies of each), so the new cards are in the game at once. Table shows them on the table;
Check still says 20/20.
4. A choice: the Flow tab
In Fifteen a turn is one step, Play a card. We add a second thing a player may do: stand,
play nothing and keep the total. Open Flow: the game as a tree (Deal, then the loop Turns
with the step Play a card). Tap Play a card. Under What can be done the model's actions
are listed with a checkbox, deal and play_card; type stand in the field + new action…
and press Enter. Two things happen: the step now offers play_card and stand (the player
chooses between them), and an action stand is created in the model with an empty effect.
Open Model and find it at the end of actions::
stand:
label: stand
effect: []
Give it a meaning: standing ends your part of the game. Replace it with
stand:
label: Stand
pre: you have at least 16
pre_x: "total[actor] >= 16"
effect:
- {op: set, var: "standing[actor]", value: true}
pre_x says when the action is legal: below 16 you must play. The variable does not exist yet:
Check says so (the test games stop with name 'standing' is not defined). Add it under
state.vars, next to total:
standing: {scope: player, type: bool, init: false}
Now stop a standing player from playing: give play_card the extra condition
pre_x: "len(hand[actor]) > 0 and not standing[actor]", and end the game when both stand. Add
to end:, before cards_out:
- id: both_stand
if: both players stand: the one closest to 21 wins
if_x: "all(standing[p] for p in players)"
result: score
returns_x: "[0, 0] if abs(TARGET - total[0]) == abs(TARGET - total[1]) else [1, -1] if abs(TARGET - total[0]) < abs(TARGET - total[1]) else [-1, 1]"
A line ending in _x is an expression the engine runs; the line before it without _x is the
same thing in words for people. Put the cursor in an _x and the panel under the text reads it
out, shows its value on the table and, for a condition, lets you Build it from rows
(Rules in words). The quick reference lists the
operations (set, add, move, draw, choose, if…) and the names you can use.
Check is green again? Press Play: at 16 or more you get the choice Play a card or Stand. A player who has no legal action is skipped, so a standing player's turns pass by themselves.
5. The table: the Layout tab
Open Table: the deck on the table, per player a dial for total, the hand and the pile; that
comes from Fifteen's small view (the View tab). To arrange it yourself, open Layout: the
rows of the table as chips. Drag deck into a row of each player and back, move the dial to
the right of the hand; tap a chip for its options: a name, wide, small cards, the maximum of
a dial. The dial still runs to 15: tap total, set Max to 21. The Table pane follows every
change, and the View tab shows the text it writes. (A game without a view gets an automatic
layout; the Layout tab then offers to start from it.)
The palette Not placed yet lists what the model has that is not on the table yet. Numbers
become dials; standing is a yes/no and gets no chip: the options a player has (Play a card or
Stand, or nothing) tell the story, and the Details view of the player shows every value.
6. Let the computer play it: Simulate
Open Simulate: 1000 games with random players, in a few seconds. The result: how often each
player wins, with a 95% interval, how the games ended (both_stand, bust, cards_out…) and a
histogram of the game length. Does player 1 win too often? Tick Experiment: vary a constant,
choose TARGET, from 15 to 25, step 2: a chart of the win rates and the game length for every
target. That is where you balance a rule: pick the value that gives both players a fair chance
and games that last the length you like.
The computer players so far move at random. Tactic gives them rules of thumb: which card to play, when to stand; see tactics. With a tactic, Compare with other players plays the same games (same seeds) with and without it, so the difference is the tactic, not luck.
7. Share it
Share link puts the whole game into a link: whoever opens it gets a copy in their own workshop and can play it in the player. Download package gives a zip with the model, the view, the tactic and your images, for a backup or for a repository; Import reads one back. Your game also appears in the player's Game box, for playing against the computer, in 3D, with the rules in words.
Where to go from here
- The guide builds a game from a rulebook step by step and has the patterns for everything Fifteen does not need: dice, boards, triggers, modifiers, hidden information, campaigns.
- The reference has every key; the quick reference fits on one page.
- Views for your own card art, backs, boards and pieces, also in 3D.
- Authoring with an AI agent when you would rather have a rulebook turned into a model for you.