Building Yahtzee: Zilch Edition
How a house-rules variant became a fully standalone TNT app —
the design reasoning, every architecture decision explained.
This log documents the design conversation that led to the Yahtzee: Zilch Edition. Unlike a simple “build this” request, this session required the AI to reason about game design, probability, software architecture, and the tradeoffs of variant features before writing a single line of code.
Watch for the prompt critiques (violet boxes) and design decision boxes (teal) — the reasoning behind each choice is as instructive as the code itself.
It’s not standard Yahtzee play, but I’ve thought about integrating another roll category: ‘Zilch’ defined as a scenario where all dice values are different (no repeats) but it cannot be classified as anything else. I see two options for incorporating it: a completely different Yahtzee game, perhaps with a different name, or incorporated as a feature in our current Yahtzee game but when activated, those stats would not be incorporated into the stats record. Those stats are only for standard play. What is your view of this incorporation? Worthwhile? If so, how to incorporate it? If it is its own app, we’d need another card for it in our cover page.
This is a strong design consultation prompt. The user:
- Defines the feature in their own words (“all different, cannot be classified as anything else”)
- Presents two concrete architectural options, not just an open-ended “what should I do?”
- Identifies the stats integrity concern proactively — a real constraint, not an afterthought
- Asks for the AI’s opinion, which invites pushback
The one precision gap: “all different but cannot be classified as anything else” is almost right but needs a correction — which the AI provided immediately. This is a case where the user’s intuition was correct but the definition was slightly loose, and a well-framed question gave the AI room to tighten it.
There is a mathematical precision point worth surfacing before we decide architecture: “all dice different” does NOT always mean “can’t be classified.”
With 5 dice drawn from 1–6, there are exactly 6 possible all-different hands. Four of them are straights:
- {1,2,3,4,5} and {2,3,4,5,6} → Large Straight
- {1,2,3,4,6} and {1,3,4,5,6} → Small Straight
- {1,2,3,5,6} and {1,2,4,5,6} → True Zilch — no run of 4
So the correct definition is: all 5 dice different AND no run of 4 consecutive values. Only 2 of 6 all-different hands qualify. Probability of rolling one: ~3.1% per throw — rare but real.
My recommendation: separate standalone app. Stats integrity is your own stated concern. A mode flag and a shared localStorage key is a data quality problem waiting to bite. Scorecard structure changes require a 14th category. It’s genuinely a different game.
The first thing Copilot did was fix the feature definition before discussing architecture. This is correct AI agent behavior: if the specification is wrong, any implementation of it is wrong, no matter how cleanly written.
The user’s intuition (“all different but not classifiable”) was right in spirit. The AI tightened it to a mathematically precise condition: “all 5 different AND no run of 4.” Only 2 hands out of 6 possible all-different hands satisfy this. Naming the valid hands explicitly ({1,2,3,5,6} and {1,2,4,5,6}) also gives the test suite its regression cases before a line of code is written.
Let’s make a standalone version, with its own chatlog, including our first inquiry about it and subsequent entries. Do you have a good variant name, and since it’s a low chance of rolling a Zilch, what value should it have? I like the idea of it being in its own folder, all the code separate. I’m thinking a different color scheme too, to call out that it’s a different app.
This is a clean example of a decision-made prompt: the user considered the AI’s analysis, accepted the recommendation, and moved directly to specification. Notice what is included:
- Delegates three open questions to the AI (name, scoring value, color scheme) while indicating direction (“different color to call out a different app”)
- States one hard constraint (“own folder, all code separate”) which propagates through every subsequent architecture decision
- Bundles the documentation request (“own chatlog”) — the same good habit established in the SPARK edition
The AI responded with a question form to confirm the three open choices (name, score, color) before building — the same “ask before assuming” discipline from the SPARK edition applied consistently.
Recommended choices (all confirmed by the user):
- Name: “Yahtzee: Zilch Edition” — keeps brand continuity, names the variant
- Scoring: 45 points — between Large Straight (40) and Yahtzee (50). Zilch is as rare as a Large Straight on a single roll but harder to chase strategically, justifying the premium over 40.
- Color: Violet / purple — distinct from amber (SPARK) and teal (2026 refactor); the colour carries a faint “chaos / wild card” association
- Folder:
YahtzeeZilch2026-06-14/
Three factors drove the standalone decision:
- Stats integrity. Mixed stats are meaningless stats.
Even a mode flag leaves a shared
localStoragekey as a fragility. Separate key ("zilchScores") in a separate file is the only clean solution. - Scorecard structure. Adding a 14th category requires modifying
the game engine’s loop bounds, trial count, and function index references.
These changes belong in a derived copy (
zilchGameScripts.js), not in an in-app toggle. - It is a different game. Standard Yahtzee has 13 categories. Adding a 14th is a house rules variant. Treating it as a patch rather than a variant would misrepresent what it is to the player.
The “all code separate” constraint also resolved the image path problem:
the dice SVGs live in the Yahtzee folder and are referenced with a relative path
(../YahtzeeJS2026-06-12/images/) rather than being duplicated.
Shared assets are referenced; app-specific logic is duplicated.
This is the right line to draw.
Five new files in YahtzeeZilch2026-06-14/, no files in any other
folder modified except the hub pages:
scripts/zilchGameScripts.js— derived fromyahtzee_game_scripts.js; 7 changes: image path constant, “of 14”, loop bounds, Chance index, Zilch function, localStorage keyscripts/zilchScripts.js— init, widget setup (addszilch/zilchTd), 8-slot score arrays, guards, all-frozen guard, sortstyles/zilchStyles.css— violet design tokens, otherwise same structure as SPARKzilchIndex.html— 14-category scorecard (Zilch row highlighted violet)zilchAbout.html— includes Zilch math explanation and valid-hand tablezilchChatlog.html— this page
Hub pages updated: yahtzeeCover.html (new violet card),
explore.html (Games offcanvas), js_apps.html (new figure).
- Define the feature mathematically before designing the code. “All different but not a straight” sounds clear until you realize four of the six all-different hands ARE straights. A one-sentence precise definition ({1,2,3,5,6} or {1,2,4,5,6}) saves a potential rework.
- Stats integrity is an architecture decision, not a detail.
Deciding to use a separate
localStoragekey before writing any code prevented a future data-mixing bug that would have been invisible until someone noticed their averages looked wrong. - Reference shared assets; duplicate only what diverges. The dice SVGs are shared (referenced by path). The game engine is divergent (copied and modified). Drawing this line explicitly keeps the folder self-contained without needlessly duplicating assets that never change between variants.