Files
tts-workshop/games/poker/poker.md
T
hyper 8eff44712f feat(tabletop): add free-interaction layer (layer 3)
Add the interaction half of the sandbox: a held part and dialog stack as
UI state outside the game store, with pure helpers (interactionsFor,
dropPaths, pickPath, partFacings, nextFacing). PartPlacement is now
interactive (pick up, drag to move, click to cycle facing), and a drop on
a path with a stack-dialog interaction opens the deck dialog instead of
moving directly. DialogLayer renders the stack-inspector dialog whose
insert button issues a move. Add the dialog role, Setup.interactions, and
Package.dialogs to @tts/bgm, and declare the deck insert dialog in
games/poker.
2026-08-18 10:20:22 +08:00

4.2 KiB
Raw Blame History

Poker

A standard 52-card poker deck, laid out on a table with a draw pile and community-card slots. Exercises the bgm loader's $variants expansion to generate a full deck from a single part definition.

id: poker
title: Poker
designer: Public Domain
players: 9
language: en
include: ['./**/*.yaml']

Parts

A single card part expanded into 52 cards by the $variants CSV. Each row picks a cell from the 13×4 face sheet (cards-13x4.jpg) — 13 ranks across, 4 suits down. All cards share the same back from the 4×1 back sheet (back-4x1.png).

face: ./cards-13x4.jpg
back: ./back-4x1.png
size: [63, 88, 0.3]
fillet: 2
$variants: ./cards.csv
id,rank,suit,faceCrop,backCrop
string,string,string,[number;number;number;number],[number;number;number;number]
2s,2,spades,[0;0;13;4],[0;0;4;1]
3s,3,spades,[1;0;13;4],[0;0;4;1]
4s,4,spades,[2;0;13;4],[0;0;4;1]
5s,5,spades,[3;0;13;4],[0;0;4;1]
6s,6,spades,[4;0;13;4],[0;0;4;1]
7s,7,spades,[5;0;13;4],[0;0;4;1]
8s,8,spades,[6;0;13;4],[0;0;4;1]
9s,9,spades,[7;0;13;4],[0;0;4;1]
10s,10,spades,[8;0;13;4],[0;0;4;1]
js,J,spades,[9;0;13;4],[0;0;4;1]
qs,Q,spades,[10;0;13;4],[0;0;4;1]
ks,K,spades,[11;0;13;4],[0;0;4;1]
as,A,spades,[12;0;13;4],[0;0;4;1]
2h,2,hearts,[0;1;13;4],[0;0;4;1]
3h,3,hearts,[1;1;13;4],[0;0;4;1]
4h,4,hearts,[2;1;13;4],[0;0;4;1]
5h,5,hearts,[3;1;13;4],[0;0;4;1]
6h,6,hearts,[4;1;13;4],[0;0;4;1]
7h,7,hearts,[5;1;13;4],[0;0;4;1]
8h,8,hearts,[6;1;13;4],[0;0;4;1]
9h,9,hearts,[7;1;13;4],[0;0;4;1]
10h,10,hearts,[8;1;13;4],[0;0;4;1]
jh,J,hearts,[9;1;13;4],[0;0;4;1]
qh,Q,hearts,[10;1;13;4],[0;0;4;1]
kh,K,hearts,[11;1;13;4],[0;0;4;1]
ah,A,hearts,[12;1;13;4],[0;0;4;1]
2d,2,diamonds,[0;2;13;4],[0;0;4;1]
3d,3,diamonds,[1;2;13;4],[0;0;4;1]
4d,4,diamonds,[2;2;13;4],[0;0;4;1]
5d,5,diamonds,[3;2;13;4],[0;0;4;1]
6d,6,diamonds,[4;2;13;4],[0;0;4;1]
7d,7,diamonds,[5;2;13;4],[0;0;4;1]
8d,8,diamonds,[6;2;13;4],[0;0;4;1]
9d,9,diamonds,[7;2;13;4],[0;0;4;1]
10d,10,diamonds,[8;2;13;4],[0;0;4;1]
jd,J,diamonds,[9;2;13;4],[0;0;4;1]
qd,Q,diamonds,[10;2;13;4],[0;0;4;1]
kd,K,diamonds,[11;2;13;4],[0;0;4;1]
ad,A,diamonds,[12;2;13;4],[0;0;4;1]
2c,2,clubs,[0;3;13;4],[0;0;4;1]
3c,3,clubs,[1;3;13;4],[0;0;4;1]
4c,4,clubs,[2;3;13;4],[0;0;4;1]
5c,5,clubs,[3;3;13;4],[0;0;4;1]
6c,6,clubs,[4;3;13;4],[0;0;4;1]
7c,7,clubs,[5;3;13;4],[0;0;4;1]
8c,8,clubs,[6;3;13;4],[0;0;4;1]
9c,9,clubs,[7;3;13;4],[0;0;4;1]
10c,10,clubs,[8;3;13;4],[0;0;4;1]
jc,J,clubs,[9;3;13;4],[0;0;4;1]
qc,Q,clubs,[10;3;13;4],[0;0;4;1]
kc,K,clubs,[11;3;13;4],[0;0;4;1]
ac,A,clubs,[12;3;13;4],[0;0;4;1]

Board

A table with a draw pile on the left and five community-card slots across the middle. The deck pile fans its stacked cards along a curve.

id: poker
size: [600, 400]
layout:
  - route: /deck
    x: -250
    y: 0
    rotation: 0
    stacking:
      align: center
      zStart: 0
      #zEnd: 100
      curve: M -50 -200 C 50 -150 450 -150 550 -200
  - route: /community/:slot
    candidates:
      $variants: ./community.csv
slot,x,y,rotation
string,number,number,number
0,-100,0,0
1,-50,0,0
2,0,0,0
3,50,0,0
4,100,0,0

Setup

Deal the whole deck facedown onto the draw pile (poker:card expands to every card of that type, facing: back), then flip a flop onto the community slots and stand a couple of drawn cards on their bottom edge.

id: main
setup:
  - path: /deck
    parts: poker:card
    facing: back
  - path: /community/0
    parts: poker:card#as
  - path: /community/1
    parts: poker:card#kh
  - path: /community/2
    parts: poker:card#7d
  - path: /community/3
    parts: poker:card#jc
    facing: standing
  - path: /community/4
    parts: poker:card#2h
    facing: standing
interactions:
  - dialog: prompt#insert
    on: [/deck]

Dialog

Inserting a card into the middle of the deck is a compound interaction: the deck is lifted into a stack-inspector dialog with an insertion cursor. The cursor is the index — move(id, /deck, index) is discovered by scrolling, not typed.

id: insert
title: Insert into deck
body: Scroll to the insertion point, then insert the held card.
widget: stack