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.
4.2 KiB
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