# Pai Gow Poker internals Builder-facing table configuration and the published Fortune pay table live in [../building_guide/pai_gow.md](../building_guide/pai_gow.md). This page covers the engine side: hand evaluation, the house way, settlement and the Joker art. ## Hand evaluation The Joker is partially wild: an ace, or any missing card completing a straight, flush or straight flush. Five aces beats a royal flush. A2345 is the second-highest straight (and straight flush), below TJQKA but above 9TJQK, by default. `PaiGowConfig.A2345High()` reads the optional `a2345_second_highest` field (default true); the evaluator is threaded through the `...Rules` variants (`pgEvaluateRules`, `pgHouseRules`, `pgFortuneRules`, `pgBestRules`, `pgDealerPushRules`, `pgMainResultRules`, `pgPushAceClassRules`) so a table can demote the wheel to the lowest straight without changing the default wrappers the tests use. Low hands recognize only pairs and high cards. Suits do not break ties. Copies lose to the dealer. The high hand must strictly outrank the low hand. ## Betting flow Side bets (`fortune`, and `pushace` on Face Up) are placed first; the main wager commits the round. The main bet deals immediately when every active (connected) player has one, and a lone bettor is dealt at once, so a single seat never waits on a timer. With two or more active players the shared betting window (`betting_ticks`) opens and `finishBettingLocked` deals when it expires if any main wager is live, refunding side bets on seats that never placed one. `unbet main|fortune|pushace|all` returns an undealt stake through `PayCredits`, and `leave` before the deal refunds the departing seat and re-checks `allBetLocked` so the remaining bettors can be dealt. The Push Ace High cap (half the main wager) is enforced when the main wager lands, because side bets are already down by then. ## Player setting and showdown An arrangement made with `24`/`13456`/`house` is stored on the player as `pending`; it does not lock the hand or reveal the dealer. `set` moves `pending` into `split` and marks the seat ready. When `autoset` is on (the table default or a per-seat `autoset on`) a legal arrangement is committed straight to `split`. A seat's `autoset` is seeded from `PaiGowConfig.Autoset` at join. When every active seat is ready, `prepareSettlementLocked` evaluates both sides, builds a `PaiGowShowdown`, and hands it to `payLocked`. The showdown always orders `Hands` player-high, dealer-high, player-low, dealer-low. Each `PaiGowHandView` carries the label, the `pgRankName` strength, the cards, and whether that hand won its comparison. The presentation layer derives the colours (bold yellow for a winning strength, bold white for a losing one) from those flags, so the casino package stays colour-free. The `PaiGowShowdown` also carries the main result word, Fortune and Push Ace outcomes, the Envy amount (only when another active player is seated), the total stake, the payout, and the paid/pending state. The dealt seven cards are only put on the snapshot before a seat has arranged anything. A manual seat shows its `pending`/committed split as the `Preview` (high then low, gap between, position numbers); an autoset seat skips the preview and shows only the set/waiting note. `pgCardNums` maps each hand card back to its 1-7 dealt position. ## House way This is a **local, deterministic house way**, not a claim to reproduce a particular casino's proprietary chart or optimal player strategy: 1. Enumerate the 21 possible splits and discard fouls. 2. Preserve the strongest available high-hand category. 3. With two pair or a full house available, also allow splits leaving at least a pair high and a pair low. 4. Maximize the low hand among these options, then the high hand. The dealer and automatic player setting use precisely the same algorithm. Published main-game house-edge estimates using other house ways do not necessarily apply to this implementation. ## Fortune / Envy mathematics Of the eight published fixed tables compared on the Wizard of Odds page, table 8 (the one configured here) has the lowest house edge: 4.4292% before Envy, about 0.08% with six players each betting five. With Envy disabled, quads improve from 25:1 to 30:1, a custom local schedule lowering the published no-Envy edge by about 0.9974 percentage points to 3.4318%. These are published theoretical side-bet figures, not a simulation of this server; Envy value depends on occupancy and wager size. ## Face Up mechanics The dealer sets and reveals before players act; the automatic ace-high push is checked against the dealer's best five-card hand (`pgDealerPush`), so ace pairs and ace-headed flushes do not trigger it. Push Ace High classes are resolved by `pgPushAceClass`: a Joker in the dealer's seven cards pays the Joker rate (a natural ace plus the Joker makes a pair of aces, which is NOT ace-high); otherwise 40:1 when the player is also ace-high, else the plain rate. ## Settlement Main, Fortune, Envy and Push Ace High settle in a single wallet transaction per player. Failed settlements freeze the result and block the next deal; `settle` or the table tick retries payment, never redraws. Successful recipients are not paid twice. Shutdown uses the existing durable stake-refund mechanism. ## Joker art The shared Joker is rank `JK`, suit `joker`. `data/cards.yaml` supplies `JK` artwork at sizes 1/5/7/9; `internal/game/render_joker.go` also has ASCII and no-store fallbacks, including dark/light styles. Existing Joker Poker video poker uses the same art.