hanabi: card art, black-suit fix, and the spikes answer #3

Merged
joeyr merged 1 commit from hanabi/art-and-black-suit into main 2026-08-16 17:19:59 -05:00
Owner

The hidden-hand question is answered — TTS can do it

Run against a live table. setHiddenFrom exists, hides only from the colours named, and is per-colour rather than global — cards hidden from an unoccupied seat colour stayed fully readable to the player holding them, in the same hand. A hidden card leaves a placeholder occupying its slot rather than vanishing, which the game requires: clues are given as positions, so a player who cannot see how many cards they hold cannot be told anything. setInvisibleTo removes the object and is the wrong tool for that reason.

The same run was the first proof make bundle works against real TTS — require("log") resolved in-game.

Spike rewritten for solo

The old version demanded two seated players, which is useless on a single-player table. The solo test hides two cards from the player and two from a colour nobody occupies, in one hand. The empty-seat pair is the control, and it settles the per-colour question with one person in the room — more sharply too, since both groups sit under identical conditions instead of being compared across a reload.

Black is no longer clueable by colour

rules.ttslua had black as an ordinary sixth colour while the README described the standard variant, where only a number clue touches a black card. The README was right. Rejected outright rather than allowed through to fail as an empty clue, so the error names the real problem. blackCluable restores the old behaviour.

Card art

Generated by tools/make_cards.py, not sourced. The 6×5 grid is an interface — column is suit index, row is rank−1 — so suit order must match rules.ttslua or every card silently becomes a different card. Each suit carries a distinct pip shape as well as a colour; a game built on saying "these two are red" is unplayable for a colourblind player if two suits look alike.

Committed rather than hosted elsewhere. The repo is public, so Forgejo raw is already a stable direct-image URL — verified unauthenticated: 200, image/png, byte-identical to the local file. This removes the third-party hosting step entirely, and ties the art lifetime to the repo, which matters because the URL is baked permanently into any save built on it.

Also

Chat matching now tolerates surrounding whitespace — the anchored pattern meant one trailing space made a command silently do nothing. Found by typing exactly that during the live run.

Rules verified at 945 assertions including 200 randomised four-player games.

### The hidden-hand question is answered — TTS can do it Run against a live table. `setHiddenFrom` exists, hides only from the colours named, and is **per-colour rather than global** — cards hidden from an unoccupied seat colour stayed fully readable to the player holding them, in the same hand. A hidden card leaves a placeholder occupying its slot rather than vanishing, which the game requires: clues are given as positions, so a player who cannot see how many cards they hold cannot be told anything. `setInvisibleTo` removes the object and is the wrong tool for that reason. The same run was the first proof `make bundle` works against real TTS — `require("log")` resolved in-game. ### Spike rewritten for solo The old version demanded two seated players, which is useless on a single-player table. The solo test hides two cards from the player and two from a colour nobody occupies, in one hand. The empty-seat pair is the control, and it settles the per-colour question with one person in the room — more sharply too, since both groups sit under identical conditions instead of being compared across a reload. ### Black is no longer clueable by colour `rules.ttslua` had black as an ordinary sixth colour while the README described the standard variant, where only a number clue touches a black card. The README was right. Rejected outright rather than allowed through to fail as an empty clue, so the error names the real problem. `blackCluable` restores the old behaviour. ### Card art Generated by `tools/make_cards.py`, not sourced. The 6×5 grid is an interface — column is suit index, row is rank−1 — so suit order must match `rules.ttslua` or every card silently becomes a different card. Each suit carries a distinct pip **shape** as well as a colour; a game built on saying "these two are red" is unplayable for a colourblind player if two suits look alike. Committed rather than hosted elsewhere. The repo is public, so Forgejo raw is already a stable direct-image URL — verified unauthenticated: `200`, `image/png`, byte-identical to the local file. **This removes the third-party hosting step entirely**, and ties the art lifetime to the repo, which matters because the URL is baked permanently into any save built on it. ### Also Chat matching now tolerates surrounding whitespace — the anchored pattern meant one trailing space made a command silently do nothing. Found by typing exactly that during the live run. Rules verified at 945 assertions including 200 randomised four-player games.
hanabi: card art, black-suit fix, and the spike's answer
All checks were successful
lint / lua (pull_request) Successful in 20s
1ac314566a
The hidden-hand question is answered, and the answer is yes. Run against a live
table, setHiddenFrom exists, hides only from the colours named, and is
per-colour rather than global -- cards hidden from an unoccupied seat colour
stayed fully readable to the player holding them in the same hand. A hidden card
leaves a placeholder occupying its slot instead of vanishing, which the game
requires: clues are given as positions, so a player who cannot see how many
cards they hold cannot be told anything. setInvisibleTo removes the object and
is the wrong tool for that reason. The same run was the first proof that
make bundle works against real TTS.

Getting that answer needed a rewrite. The old spike demanded two seated players
and refused to run otherwise, which is useless on a single-player table. The
solo test hides two cards from the player's own colour and two from a colour
nobody occupies, in one hand: the empty-seat pair is the control, and it settles
the per-colour question without a second person in the room. It is also a
sharper experiment, since both groups sit under identical conditions rather than
being compared across a reload.

Black is no longer clueable by colour. rules.ttslua had it as an ordinary sixth
colour while this game's README described the standard variant, where only a
number clue ever touches a black card and the table has to deduce the suit from
what is missing. The README was right. The clue is rejected outright rather than
allowed through to fail as an empty clue, so the error names the real problem
instead of sending the player hunting for a card that is sitting right there.
blackCluable restores the old behaviour for anyone who prefers it.

Card art is generated rather than sourced, and committed rather than hosted
elsewhere. The 6x5 grid is an interface: column is suit index, row is rank - 1,
and the Global script will derive TTS card ids from that, so suit order has to
match rules.ttslua or every card silently becomes a different card. Each suit
carries a distinct pip shape as well as a colour -- a game built on saying
"these two are red" is unplayable for a colourblind player if two suits look
alike. The black column is generated even for base games so the sixth-suit
toggle stays a script setting rather than a second asset to keep in sync.

Committing the art means Forgejo's raw endpoint is already a stable direct-image
URL, since this repo is public. That ties the asset's lifetime to the repo's,
which matters because the URL is baked permanently into any save built on it.

Also fixes chat command matching to tolerate surrounding whitespace: the
anchored pattern meant one trailing space made a command silently do nothing,
which is indistinguishable from a broken script. Found by typing exactly that
during the live run.

Rules verified at 945 assertions, including 200 randomised four-player games.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
joeyr merged commit 375317341b into main 2026-08-16 17:19:59 -05:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
joeyr/tts-games!3
No description provided.