Split craps into an engine and a UI #27

Closed
opened 2026-08-12 17:38:08 +00:00 by rosa · 0 comments
Owner

Problem Statement

Craps is the only game at this casino where a player can lose money the table
never accounts for, and the only one whose money never reaches their record.

Three things go wrong today, all of them invisible because no test can reach the
game at all:

  • A Pass Line wager vanishes whenever a point is established. The wager
    leaves the bankroll the moment it is placed, as ADR-0001 requires, but the
    position it was placed on is dropped as soon as the come-out roll fails to
    settle it. The player never sees it win, lose or push. It is simply gone.
  • The round has no seven-out. Once a point is established, the round ends
    only when the player rolls that point. A 7 pays out Come bets and play
    continues, so a player can roll indefinitely and the house never takes the
    line.
  • Nothing craps does is recorded. Every other game contributes to the
    player's statistics. Craps has no entry, so a player's record understates
    their action and misstates their results.

Behind all three is one structural fact: settlement sits in the middle of a loop
between two prompts, so nothing can call it. The game can be played, never
tested.

Solution

Craps gets an engine, as blackjack and roulette already have — a module that
owns the point, the positions and the dice, and answers in payouts rather than
printed lines. The terminal-facing half keeps the prompts and the animation and
does nothing else.

From the player's side:

  • Every wager placed comes back as a settled position, win, lose or push. The
    line is settled by whichever event ends the round.
  • The round ends the way craps rounds end: hitting the point, or sevening out.
  • Craps appears in the player's statistics alongside the other five games.
  • Mister Green shows up on every exit from the table, not just the ones that
    were remembered.

User Stories

  1. As a player, I want my Pass Line wager to be settled when the round ends, so that money I put at risk is never silently kept.
  2. As a player, I want my Don't Pass wager settled the same way, so that backing the house is as reliable as backing the shooter.
  3. As a player, I want the round to end when I seven out, so that the game follows the rules of craps.
  4. As a player, I want hitting my point to win my Pass Line bet, so that the bet I opened with pays when it should.
  5. As a player, I want hitting my point to lose my Don't Pass bet, so that the two sides of the line remain opposites.
  6. As a player, I want sevening out to lose my Pass Line bet, so that the house has a way to win.
  7. As a player, I want sevening out to win my Don't Pass bet, so that backing the house pays when the shooter fails.
  8. As a player, I want a come-out roll of 7 or 11 to settle my Pass Line bet immediately, so that the come-out means what the table says it means.
  9. As a player, I want a come-out roll of 2, 3 or 12 to settle my line bet immediately, so that craps on the come-out ends the round.
  10. As a player, I want any other come-out roll to establish a point, so that the round moves into its second phase.
  11. As a player, I want to see what my point is while the round runs, so that I know what I am rolling for.
  12. As a player, I want to be offered only the bets that are available in the current phase, so that I am never sold a position that cannot be settled.
  13. As a player, I want to place a Field bet once a point is established, so that I can back a single roll.
  14. As a player, I want my Field bet resolved on the very next roll, so that a single-roll bet does not linger.
  15. As a player, I want a Field bet on 2 or 12 to pay at its own rate, so that the ends of the range are worth backing.
  16. As a player, I want to place Come and Don't Come bets after the point, so that I can add positions mid-round.
  17. As a player, I want each of my positions settled independently, so that I can win on one and lose on another in the same roll.
  18. As a player, I want every position still standing when the round ends to be settled rather than merely announced, so that the bankroll matches what I was told.
  19. As a player, I want to be told what each position paid and what my bankroll now holds, so that I can follow the money.
  20. As a player, I want to be told when a position loses and what it cost me, so that losses are as clear as wins.
  21. As a player, I want a push to return my wager untouched, so that a tie costs me nothing.
  22. As a player, I want to see the dice tumble and settle, so that the roll feels like a roll.
  23. As a player, I want to be shown the maximum I can wager when I am asked for an amount, so that I do not guess at what I can afford.
  24. As a player, I want a mistyped wager to be asked again rather than ending the game, so that a typo is not fatal.
  25. As a player, I want a wager I cannot afford refused with another chance to answer, so that I can correct myself.
  26. As a player, I want my craps wins recorded in my statistics, so that my record covers every game I play.
  27. As a player, I want my craps losses recorded too, so that my record is not flattering.
  28. As a player, I want my craps action counted, so that the record reflects how much I have played.
  29. As a player, I want to see a craps table in my statistics alongside the other games, so that nothing I play is missing from the report.
  30. As a player, I want Mister Green to find me after a winning round as well as a losing one, so that the table treats every exit the same.
  31. As a player, I want my bankroll saved however the round ended, so that no outcome is lost.
  32. As a developer, I want a craps round I can construct and drive from a test, so that the game's rules can be asserted at all.
  33. As a developer, I want to script the dice a round will produce, so that a test can reproduce a come-out, a point and a seven-out exactly.
  34. As a developer, I want the engine to answer in payouts rather than printed lines, so that settlement can be asserted rather than read.
  35. As a developer, I want the engine to hold no reference to the bankroll, so that testing a round costs no filesystem and no player.
  36. As a developer, I want to assert that every wager placed appears in exactly one payout, so that money cannot vanish again.
  37. As a developer, I want to assert which bets are on offer in each phase, so that the table's shape is pinned down.
  38. As a developer, I want the wording shown to the player asserted from a real settled round, so that announcements cannot drift from outcomes.
  39. As a developer, I want craps to follow the same engine/UI shape as blackjack and roulette, so that a reader who knows one knows all three.
  40. As a developer, I want the seam recorded as a decision, so that the next game built follows it deliberately rather than by imitation.
  41. As a developer, I want craps' pay table decisions written down as tests, so that a rate is a choice rather than an accident.

Implementation Decisions

Module split. craps becomes a module declaring a game half and a UI half,
mirroring how roulette is laid out — declarations and re-exports in the
module's own file, engine and terminal code beside it. There is no layout
analogue: craps' bets are an enum, not a table of pockets.

Engine interface. A Craps round exposes, in the order a caller uses them:

  • a constructor taking nothing — the round begins with an empty table
  • a second constructor taking a scripted sequence of dice pairs, as the
    determinism seam
  • the bets currently on offer, which are the line bets during the come-out and
    the remaining bets once a point stands
  • placing a bet with a wager already taken from the bankroll
  • rolling, which advances the round and hands back the roll
  • settling, which reports what the most recent roll resolved
  • the point, if one stands
  • whether the round is finished

The line bet is an ordinary position. There is no separate line-bet path; it
is placed through the same call as everything else. This is what fixes the
vanishing wager — there is no second code path left to forget.

The engine owns the point and the phase. The phase itself stays private; the
UI is given the point and a finished flag, not a state to branch on. The missing
seven-out exists precisely because the round's shape lived in the UI's control
flow, and moving that shape inward is the fix.

Randomness lives in the engine, injected through the scripted-dice
constructor, following Roulette::with_wheel rather than the architecture
review's suggestion that the UI supply dice. A scripted sequence that runs out
panics: a test that rolls past its script is broken, not a game state.

Dice are scripted as pairs, not totals. Only totals matter to today's bets,
but hardways and the prop bets named in the module's rules comment need both
dice, and widening later would change the signature.

A roll is a named type holding two dice, exposing their total and both dice
individually, so bets can ask it questions beyond the total as more bets arrive.

Settling is per roll, and pure. Rolling mutates; settling reads back what
that roll decided and can be called without changing anything. The name matches
roulette's and means the same thing — what the dice just decided you are owed —
called once per roll rather than once per round.

A payout carries the bet it settled, not a position index. This departs from
the architecture review's suggestion of an indexed position: blackjack needs
indices because its hands are indistinguishable, but craps positions name
themselves, and the announcements name the bet anyway.

Outcomes include a push from the start, even though nothing pushes yet.
A payout has to be able to express a returned wager equal to the wager before
bar-12 can become one.

Round-end leftovers are settled, not announced. The line is settled by
whichever event ended the round — the point wins Pass and loses Don't Pass,
sevening out does the reverse. Every other surviving position resolves as a
loss, which is today's printed behaviour, but it comes back as payouts so the
bankroll and the announcement cannot disagree.

Placement cannot fail. The engine only offers bets that can be settled in
the current phase, and the UI only offers money it has already taken from the
bankroll, so there is no error left for placement to report.

Animation is entirely the UI's. The tumbling dice are a screen effect with
no claim on the outcome — unlike roulette's ball path, which genuinely crosses
the pockets it reports — so the UI generates its own frames and the frame rate
constant lives with the UI.

Wager prompting is aligned with roulette's, including showing the player
their maximum, so that the eventual collapse of the six copies into one is a
deduplication rather than an adjudication between six behaviours.

One exit from the table. Mister Green and the save happen once, at the end,
reachable from every outcome.

Statistics record off the payout alone, mirroring the roulette statistics
shape. No per-bet breakdown: that would make the statistics module import craps'
bet type, deepening the cycle a later refactor exists to break. This adds a
craps field to the statistics record and a sixth table to the report — the
known "three files per game" leakage, accepted so that the eventual fix faces
six symmetric cases instead of five and a hole.

Delivery order. The seam and the round's termination land together, since
neither can be written coherently without the other. Statistics follow. The pay
table follows that. The architectural decision record is written last, once
three games share the shape.

Pay table corrections are separate and deliberate. The Field's rate on 12
contradicts the module's own rules comment, and Don't Pass currently wins on 12
where the comment calls it a push. Both are rules choices rather than bugs, and
each lands with a test that names the choice.

A new architectural decision record captures the engine/UI seam: games
separate a value-returning engine from a terminal-driving UI, with the
scripted-input constructor as the determinism seam. Three games now share it and
poker is next in line.

No new glossary entries. The domain glossary deliberately lets each game
keep its own jargon, so come-out, point and seven-out are explained in doc
comments where a reader meets them.

Testing Decisions

A good test here asserts what the table does with the player's money, not how
the engine arranged itself to do it. It drives a whole round through the public
entry points and asserts on the payouts that come back — never on the phase, the
position list, or whether a particular bet matched a particular roll. A test
that would still pass after the internals were rewritten, and fail if a player
were shorted, is the one worth having.

Two seams, both at the highest point available.

The round itself, constructed with a scripted sequence of dice. One entry
point covers come-out resolution, point establishment, sevening out, per-roll
settlement and round-end leftovers. Direct prior art: the roulette round
constructed with a fixed wheel, at the foot of the roulette engine.

The announcement, taking one settled payout and the bankroll and returning the
line the player reads. Wording only. Exact prior art in roulette's UI, which
drives it through a genuinely settled round rather than a hand-built payout —
craps follows that, so the wording cannot drift from an outcome that could never
occur.

Both live at the foot of their own file, as baccarat and roulette do.

What the round's tests must cover:

  • a come-out roll that wins the line, one that loses it, and one that
    establishes a point
  • sevening out, settling both sides of the line correctly
  • hitting the point, settling both sides correctly
  • a Field bet that pays and one that loses
  • positions still standing when the round ends resolving as losses
  • the bets on offer differing between the come-out and the point phase
  • every wager placed appearing in exactly one payout

That last one is load-bearing. It is the assertion that would have caught the
vanishing line bet, and it stays meaningful as bets and pay tables change
underneath it.

No seam for the statistics. The statistics module has no tests today, and
craps' recording is a pass-through of the payout, so a test there would assert
the delegation rather than any behaviour.

Manual verification covers what no test reaches — the animation and the
prompt flow. Four rounds played at the terminal: a come-out win, a come-out
loss, a point sevened out, and a point hit with a live Field bet. Those walk
every path the work rewrites.

Out of Scope

Travelling Come bets. A real Come bet establishes its own point on the
following roll and travels with it. Today a Come bet is a permanent copy of the
Pass Line, winning on every 7 or 11 for as long as it stands. That
simplification is preserved deliberately, not overlooked, and is tracked in #28
— it is much easier to write once the engine exists.

The unimplemented bets named in the module's rules comment: free odds, place
and buy bets, Big Six/Eight, hardways, and the single-roll props. They remain the
comment they already are.

The shared round. Craps continues to load the casino from the filesystem in
its own UI, as every other game does, until the separate work that gives the
table ownership of the round lands. Aligning the wager prompt with roulette's is
groundwork for that, not a start on it.

Unifying payout types across games. Each game keeps its own, as blackjack and
roulette do today. Collapsing them is its own piece of work.

Changing the mid-round prompt flow. The UI keeps offering one bet per
iteration before each roll. The split leaves the door open to loosen it later
without the engine changing, and changing it in the same commit that moves every
line of the file would obscure the diff.

Further Notes

This comes out of the architecture review of 12 August 2026, as its second
candidate — the hardest and most valuable of the three strong ones. The review
proposed the UI supply dice to the engine and a payout carry an indexed
position; both are departed from above, in each case toward what roulette
already does.

The review described this as extracting an engine from working code. Reading the
module says otherwise: the round does not finish, and a wager goes missing on
the most ordinary path through the game. The seam is not just untested — it is
load-bearing, and it has been holding nothing.

Done when the test suite passes, the linter is clean, and the four manual rounds
above have been played.

## Problem Statement Craps is the only game at this casino where a player can lose money the table never accounts for, and the only one whose money never reaches their record. Three things go wrong today, all of them invisible because no test can reach the game at all: - **A Pass Line wager vanishes whenever a point is established.** The wager leaves the bankroll the moment it is placed, as ADR-0001 requires, but the position it was placed on is dropped as soon as the come-out roll fails to settle it. The player never sees it win, lose or push. It is simply gone. - **The round has no seven-out.** Once a point is established, the round ends only when the player rolls that point. A 7 pays out Come bets and play continues, so a player can roll indefinitely and the house never takes the line. - **Nothing craps does is recorded.** Every other game contributes to the player's statistics. Craps has no entry, so a player's record understates their action and misstates their results. Behind all three is one structural fact: settlement sits in the middle of a loop between two prompts, so nothing can call it. The game can be played, never tested. ## Solution Craps gets an engine, as blackjack and roulette already have — a module that owns the point, the positions and the dice, and answers in payouts rather than printed lines. The terminal-facing half keeps the prompts and the animation and does nothing else. From the player's side: - Every wager placed comes back as a settled position, win, lose or push. The line is settled by whichever event ends the round. - The round ends the way craps rounds end: hitting the point, or sevening out. - Craps appears in the player's statistics alongside the other five games. - Mister Green shows up on every exit from the table, not just the ones that were remembered. ## User Stories 1. As a player, I want my Pass Line wager to be settled when the round ends, so that money I put at risk is never silently kept. 2. As a player, I want my Don't Pass wager settled the same way, so that backing the house is as reliable as backing the shooter. 3. As a player, I want the round to end when I seven out, so that the game follows the rules of craps. 4. As a player, I want hitting my point to win my Pass Line bet, so that the bet I opened with pays when it should. 5. As a player, I want hitting my point to lose my Don't Pass bet, so that the two sides of the line remain opposites. 6. As a player, I want sevening out to lose my Pass Line bet, so that the house has a way to win. 7. As a player, I want sevening out to win my Don't Pass bet, so that backing the house pays when the shooter fails. 8. As a player, I want a come-out roll of 7 or 11 to settle my Pass Line bet immediately, so that the come-out means what the table says it means. 9. As a player, I want a come-out roll of 2, 3 or 12 to settle my line bet immediately, so that craps on the come-out ends the round. 10. As a player, I want any other come-out roll to establish a point, so that the round moves into its second phase. 11. As a player, I want to see what my point is while the round runs, so that I know what I am rolling for. 12. As a player, I want to be offered only the bets that are available in the current phase, so that I am never sold a position that cannot be settled. 13. As a player, I want to place a Field bet once a point is established, so that I can back a single roll. 14. As a player, I want my Field bet resolved on the very next roll, so that a single-roll bet does not linger. 15. As a player, I want a Field bet on 2 or 12 to pay at its own rate, so that the ends of the range are worth backing. 16. As a player, I want to place Come and Don't Come bets after the point, so that I can add positions mid-round. 17. As a player, I want each of my positions settled independently, so that I can win on one and lose on another in the same roll. 18. As a player, I want every position still standing when the round ends to be settled rather than merely announced, so that the bankroll matches what I was told. 19. As a player, I want to be told what each position paid and what my bankroll now holds, so that I can follow the money. 20. As a player, I want to be told when a position loses and what it cost me, so that losses are as clear as wins. 21. As a player, I want a push to return my wager untouched, so that a tie costs me nothing. 22. As a player, I want to see the dice tumble and settle, so that the roll feels like a roll. 23. As a player, I want to be shown the maximum I can wager when I am asked for an amount, so that I do not guess at what I can afford. 24. As a player, I want a mistyped wager to be asked again rather than ending the game, so that a typo is not fatal. 25. As a player, I want a wager I cannot afford refused with another chance to answer, so that I can correct myself. 26. As a player, I want my craps wins recorded in my statistics, so that my record covers every game I play. 27. As a player, I want my craps losses recorded too, so that my record is not flattering. 28. As a player, I want my craps action counted, so that the record reflects how much I have played. 29. As a player, I want to see a craps table in my statistics alongside the other games, so that nothing I play is missing from the report. 30. As a player, I want Mister Green to find me after a winning round as well as a losing one, so that the table treats every exit the same. 31. As a player, I want my bankroll saved however the round ended, so that no outcome is lost. 32. As a developer, I want a craps round I can construct and drive from a test, so that the game's rules can be asserted at all. 33. As a developer, I want to script the dice a round will produce, so that a test can reproduce a come-out, a point and a seven-out exactly. 34. As a developer, I want the engine to answer in payouts rather than printed lines, so that settlement can be asserted rather than read. 35. As a developer, I want the engine to hold no reference to the bankroll, so that testing a round costs no filesystem and no player. 36. As a developer, I want to assert that every wager placed appears in exactly one payout, so that money cannot vanish again. 37. As a developer, I want to assert which bets are on offer in each phase, so that the table's shape is pinned down. 38. As a developer, I want the wording shown to the player asserted from a real settled round, so that announcements cannot drift from outcomes. 39. As a developer, I want craps to follow the same engine/UI shape as blackjack and roulette, so that a reader who knows one knows all three. 40. As a developer, I want the seam recorded as a decision, so that the next game built follows it deliberately rather than by imitation. 41. As a developer, I want craps' pay table decisions written down as tests, so that a rate is a choice rather than an accident. ## Implementation Decisions **Module split.** `craps` becomes a module declaring a game half and a UI half, mirroring how `roulette` is laid out — declarations and re-exports in the module's own file, engine and terminal code beside it. There is no layout analogue: craps' bets are an enum, not a table of pockets. **Engine interface.** A `Craps` round exposes, in the order a caller uses them: - a constructor taking nothing — the round begins with an empty table - a second constructor taking a scripted sequence of dice pairs, as the determinism seam - the bets currently on offer, which are the line bets during the come-out and the remaining bets once a point stands - placing a bet with a wager already taken from the bankroll - rolling, which advances the round and hands back the roll - settling, which reports what the most recent roll resolved - the point, if one stands - whether the round is finished **The line bet is an ordinary position.** There is no separate line-bet path; it is placed through the same call as everything else. This is what fixes the vanishing wager — there is no second code path left to forget. **The engine owns the point and the phase.** The phase itself stays private; the UI is given the point and a finished flag, not a state to branch on. The missing seven-out exists precisely because the round's shape lived in the UI's control flow, and moving that shape inward is the fix. **Randomness lives in the engine**, injected through the scripted-dice constructor, following `Roulette::with_wheel` rather than the architecture review's suggestion that the UI supply dice. A scripted sequence that runs out panics: a test that rolls past its script is broken, not a game state. **Dice are scripted as pairs, not totals.** Only totals matter to today's bets, but hardways and the prop bets named in the module's rules comment need both dice, and widening later would change the signature. **A roll is a named type** holding two dice, exposing their total and both dice individually, so bets can ask it questions beyond the total as more bets arrive. **Settling is per roll, and pure.** Rolling mutates; settling reads back what that roll decided and can be called without changing anything. The name matches roulette's and means the same thing — what the dice just decided you are owed — called once per roll rather than once per round. **A payout carries the bet it settled**, not a position index. This departs from the architecture review's suggestion of an indexed position: blackjack needs indices because its hands are indistinguishable, but craps positions name themselves, and the announcements name the bet anyway. **Outcomes include a push from the start**, even though nothing pushes yet. A payout has to be able to express a returned wager equal to the wager before bar-12 can become one. **Round-end leftovers are settled, not announced.** The line is settled by whichever event ended the round — the point wins Pass and loses Don't Pass, sevening out does the reverse. Every other surviving position resolves as a loss, which is today's printed behaviour, but it comes back as payouts so the bankroll and the announcement cannot disagree. **Placement cannot fail.** The engine only offers bets that can be settled in the current phase, and the UI only offers money it has already taken from the bankroll, so there is no error left for placement to report. **Animation is entirely the UI's.** The tumbling dice are a screen effect with no claim on the outcome — unlike roulette's ball path, which genuinely crosses the pockets it reports — so the UI generates its own frames and the frame rate constant lives with the UI. **Wager prompting is aligned with roulette's**, including showing the player their maximum, so that the eventual collapse of the six copies into one is a deduplication rather than an adjudication between six behaviours. **One exit from the table.** Mister Green and the save happen once, at the end, reachable from every outcome. **Statistics record off the payout alone**, mirroring the roulette statistics shape. No per-bet breakdown: that would make the statistics module import craps' bet type, deepening the cycle a later refactor exists to break. This adds a craps field to the statistics record and a sixth table to the report — the known "three files per game" leakage, accepted so that the eventual fix faces six symmetric cases instead of five and a hole. **Delivery order.** The seam and the round's termination land together, since neither can be written coherently without the other. Statistics follow. The pay table follows that. The architectural decision record is written last, once three games share the shape. **Pay table corrections are separate and deliberate.** The Field's rate on 12 contradicts the module's own rules comment, and Don't Pass currently wins on 12 where the comment calls it a push. Both are rules choices rather than bugs, and each lands with a test that names the choice. **A new architectural decision record** captures the engine/UI seam: games separate a value-returning engine from a terminal-driving UI, with the scripted-input constructor as the determinism seam. Three games now share it and poker is next in line. **No new glossary entries.** The domain glossary deliberately lets each game keep its own jargon, so *come-out*, *point* and *seven-out* are explained in doc comments where a reader meets them. ## Testing Decisions A good test here asserts what the table does with the player's money, not how the engine arranged itself to do it. It drives a whole round through the public entry points and asserts on the payouts that come back — never on the phase, the position list, or whether a particular bet matched a particular roll. A test that would still pass after the internals were rewritten, and fail if a player were shorted, is the one worth having. **Two seams, both at the highest point available.** *The round itself*, constructed with a scripted sequence of dice. One entry point covers come-out resolution, point establishment, sevening out, per-roll settlement and round-end leftovers. Direct prior art: the roulette round constructed with a fixed wheel, at the foot of the roulette engine. *The announcement*, taking one settled payout and the bankroll and returning the line the player reads. Wording only. Exact prior art in roulette's UI, which drives it through a genuinely settled round rather than a hand-built payout — craps follows that, so the wording cannot drift from an outcome that could never occur. Both live at the foot of their own file, as baccarat and roulette do. **What the round's tests must cover:** - a come-out roll that wins the line, one that loses it, and one that establishes a point - sevening out, settling both sides of the line correctly - hitting the point, settling both sides correctly - a Field bet that pays and one that loses - positions still standing when the round ends resolving as losses - the bets on offer differing between the come-out and the point phase - **every wager placed appearing in exactly one payout** That last one is load-bearing. It is the assertion that would have caught the vanishing line bet, and it stays meaningful as bets and pay tables change underneath it. **No seam for the statistics.** The statistics module has no tests today, and craps' recording is a pass-through of the payout, so a test there would assert the delegation rather than any behaviour. **Manual verification** covers what no test reaches — the animation and the prompt flow. Four rounds played at the terminal: a come-out win, a come-out loss, a point sevened out, and a point hit with a live Field bet. Those walk every path the work rewrites. ## Out of Scope **Travelling Come bets.** A real Come bet establishes its own point on the following roll and travels with it. Today a Come bet is a permanent copy of the Pass Line, winning on every 7 or 11 for as long as it stands. That simplification is preserved deliberately, not overlooked, and is tracked in #28 — it is much easier to write once the engine exists. **The unimplemented bets** named in the module's rules comment: free odds, place and buy bets, Big Six/Eight, hardways, and the single-roll props. They remain the comment they already are. **The shared round.** Craps continues to load the casino from the filesystem in its own UI, as every other game does, until the separate work that gives the table ownership of the round lands. Aligning the wager prompt with roulette's is groundwork for that, not a start on it. **Unifying payout types across games.** Each game keeps its own, as blackjack and roulette do today. Collapsing them is its own piece of work. **Changing the mid-round prompt flow.** The UI keeps offering one bet per iteration before each roll. The split leaves the door open to loosen it later without the engine changing, and changing it in the same commit that moves every line of the file would obscure the diff. ## Further Notes This comes out of the architecture review of 12 August 2026, as its second candidate — the hardest and most valuable of the three strong ones. The review proposed the UI supply dice to the engine and a payout carry an indexed position; both are departed from above, in each case toward what roulette already does. The review described this as extracting an engine from working code. Reading the module says otherwise: the round does not finish, and a wager goes missing on the most ordinary path through the game. The seam is not just untested — it is load-bearing, and it has been holding nothing. Done when the test suite passes, the linter is clean, and the four manual rounds above have been played.
rosa closed this issue 2026-08-14 21:02:37 +00:00
Sign in to join this conversation.
No milestone
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
rosa/casino#27
No description provided.