Walkthrough: Go Fish
Build a playable Go Fish without writing code. You'll type a few short formulas (like spreadsheet formulas); the builder autocompletes them and flags mistakes as you type. It takes about twenty minutes.
TIP
Go Fish is also a built-in game: open it with Open in builder to compare with yours.
1. Create the game
- Card Stacks sidebar → Blob's Card Engine → Games tab → New game.
- Name it
Go Fish, pick Standard 52-card deck, press Create and open the builder.
2. Info
- Players: 2 to 6. Default rules level: Strict.
- How to play: a few lines for your players, e.g.
Collect books: all four cards of one rank. On your turn press Ask: pick a player and a rank you hold. If they have any, they hand them all over and you go again. If not: Go fish!
3. Zones
- Click Deck, rename it to
Pond. - Click Discard → Remove zone (Go Fish has no discard).
- Under Each player's area press Add, then set: Name
Books, Idbooks, Who sees the cards Everyone, Layout Row, Cards put here are turned face up.
4. Variables
- Under Player values, press Add: Name
Books, Idbooks(starts at 0).
5. Rules → Setup
- Open the Deal step, set Cards each to
seats <= 3 ? 7 : 5.
6. Rules → Formulas
Add three formulas (Name, Inputs, =):
| Name | Inputs | = |
|---|---|---|
askable | s | s != self && count(zone.hand[s]) > 0 |
myRanks | distinct(pluck(cards(hand), 'rank')) | |
booksOf | s | var[s].books |
7. Rules → Actions
Delete the template's Draw / Play / Pass, then add three actions (all The player whose turn it is).
Ask (Id ask). Only if: count(hand) > 0 && len(filter(seatIds, 'askable')) > 0. What it does:
- Ask a player to choose: Question
Who do you ask?, Choose A player, Fromfilter(seatIds, 'askable'), Call the answertarget. - Ask a player to choose: Question
Which rank?, Choose One of these options, OptionsmyRanks(), Option namesmap(myRanks(), 'rankLabel'), Call the answerrank. - If ... then ... otherwise: If
countWhere(cards(zone.hand[target]), 'rank', rank) > 0- Then: Move cards: Cards
filterBy(cards(zone.hand[target]), 'rank', rank), From —, How many empty, To Hand (of the player acting). - Otherwise: If ... then ... otherwise: If
count(deck) > 0- Then: For each ...: For each item in
[top(deck)], Call itdrawn; Do:- Move cards: Cards
drawn, From —, To Hand. - If ... then ...: If
drawn.rank != rank, Then End the turn.
- Move cards: Cards
- Otherwise: End the turn.
- Then: For each ...: For each item in
- Then: Move cards: Cards
Draw (Id fish). Only if: (count(hand) == 0 || len(filter(seatIds, 'askable')) == 0) && count(deck) > 0. What it does: Draw cards (1).
Pass (Id pass). Only if: (count(hand) == 0 || len(filter(seatIds, 'askable')) == 0) && count(deck) == 0. What it does: End the turn.
8. Rules → When this happens
Add a rule: When A card moves to another zone; If card.zone == 'hand' && countWhere(cards(zone.hand[card.seat]), 'rank', card.rank) == 4; Then:
- Move cards: Cards
filterBy(cards(zone.hand[card.seat]), 'rank', card.rank), From —, To Books of player...card.seat, Side Face up. - Add to a value: Variable Books (player named in "For player"), For player
card.seat, Add1.
9. Rules → Winning
Add a way to win: The game ends when sum(seatVars('books')) == 13; open End the game and set Winner(s) to argmaxBy(seatIds, 'booksOf').
10. Flow
Open the Play phase and set Sits out if to count(zone.hand[seat]) == 0 && count(deck) == 0.
11. Check and play
- Publish should say No problems found (fix anything listed; the links jump to the field).
- Test Play → Run 100 random games: expect 100 of 100 finished.
- Test Play → Start a test match (3 players): you play every seat in turn. Ask, take cards, go fish, and watch books form.
- Happy? Games tab → Start a match for your group.
