Hold & Win Reference Mechanic — Design

Status and scope

  • Status: DESIGN APPROVED
  • Mechanic ID: hold-and-win
  • Backend feature type: hold_and_win
  • Reference Game ID: hold-and-win-reference
  • Initial version: draft-v0.1
  • Certification status: DRAFT / NOT FOR CERTIFICATION
  • Design approval: user, 2026-08-09

Build a reusable Hold & Win mechanic in the canonical Go libs/mathengine runtime and a separate reference math pack. Do not modify the frozen classic-fruits-3x3 v1 configuration or the existing partial hold_and_spin feature and sample packs.

Player and math contract

The mechanic uses a 3-column × 5-row grid with 15 cells. Cells use reel-major order: column 0 rows 0–4, then column 1 rows 0–4, then column 2 rows 0–4. This order is normative for masks, RNG draws, persistence and replay vectors.

The base outcome triggers Hold & Win when at least six BONUS symbols are visible. A non-triggering base outcome consumes no Hold & Win RNG draws. On trigger, the initial BONUS positions are copied into locked state and assigned prizes in normative cell order.

The feature starts with three respins. Each step visits only empty cells in normative order. Every visited empty cell consumes one landing draw with a draft probability of 15%. A landed prize locks the cell. If at least one new prize lands, remaining respins reset to three. Otherwise remaining respins decrement by one. Locked cells consume no further draws.

The feature settles when remaining respins reach zero or all 15 cells are locked. It charges no additional wager.

For an ordinary settlement, the award is the sum of locked prizes, capped once at 500× total bet. A full grid instead awards exactly Grand 500×; it replaces the sum of prizes rather than adding to it.

Collectors, multipliers, feature buy and other secondary mechanics are outside v0.1.

Prize model

Regular coin values are multipliers of total bet.

ValueDraft weight
40
28
16
10
10×5
20×1

Landed prize types use this independent draft pool:

Prize typeValueDraft weight
RegularFrom regular coin table1000
Mini10×20
Minor25×5
Major100×1

Grand does not appear in the landed prize pool. It is awarded only for a full grid.

Jackpot values, the full-grid Grand rule, grid geometry, cell order, trigger boundary and three-respin reset rule are locked at the design gate. Landing probability, regular value weights, jackpot weights and base trigger weights remain open for draft tuning.

RNG contract

  1. The base evaluator produces BONUS positions.
  2. If fewer than six BONUS symbols appear, the mechanic consumes no RNG.
  3. Start visits initial locked cells in normative order. For each cell it draws prize type, then draws a regular value only when the type is Regular.
  4. Step visits empty cells in normative order. For each cell it draws land/miss. On land it draws prize type, then a regular value only for Regular.
  5. Locked cells consume no draws.
  6. Settlement consumes no draws.

The same mechanic version, initial state, step identity and RNG input must reproduce the same state and result. A repeated step returns the persisted result and must not consume RNG again.

Architecture

Add a new hold_and_win feature type rather than changing the existing partial hold_and_spin behavior.

The canonical implementation is a pure, versioned state machine in libs/mathengine:

  • StartHoldAndWin
  • StepHoldAndWin
  • SettleHoldAndWin
  • RunHoldAndWinToCompletion

HoldAndWinState persists at least mechanic version, grid dimensions, locked mask, prize per cell, respins remaining, step index, accumulated award, settlement state and replay identity.

Production executes steps and persists the state between requests. Reference simulation calls RunHoldAndWinToCompletion, which must be an adapter over the same Start and Step functions, not a second implementation.

Backend integration includes config/schema validation, JSON mapping, Math Studio domain/build mapping, feature registration, simulation metrics and persistent game-engine replay. The capability may report SupportFull only after runtime persistence, reference/runtime parity and regression evidence are complete.

Reference pack and documents

Create hold-and-win-reference as a separate reference game/pack. It uses a 3×5 base layout and base weights tuned toward a draft trigger target near 1 in 150 rounds. It does not inherit or modify Classic Fruits mathematics.

Create:

games/hold-and-win-reference/
├── README.md
├── gdd/hold-and-win-reference-gdd.md
├── math/hold-and-win-reference-math-spec.md
├── math/mechanics/hold-and-win/
│   ├── hold-and-win-math-draft-v0.1.md
│   ├── hold-and-win-math-changelog.md
│   └── hold-and-win-math-handoff-v0.1.md
├── evidence/
├── test-vectors/
└── changelog.md

Canonical executable parameters remain in the Go backend. Workspace documents record the backend config path, SHA-256, Git SHA, mechanic/RNG versions and evidence identities without maintaining an uncontrolled duplicate config.

Draft math targets

These are design targets, not calculated results:

  • Mechanic RTP contribution: approximately 20% of total bet.
  • Trigger frequency: approximately 1 in 150 base rounds.
  • Conditional feature mean: approximately 30× total bet.
  • Maximum feature award: 500× total bet.

Exact enumeration is optional only if a correct tractable state-space method is demonstrated. Otherwise the authoritative draft evidence is a seeded backend simulation, clearly labelled estimated, reporting total/base/feature RTP with confidence intervals, trigger frequency, conditional mean/median/percentiles, duration, reset rate, full-grid probability, prize/jackpot frequencies, standard deviation, observed maximum and validated bound.

Error, recovery and compatibility rules

  • Reject invalid grid dimensions, trigger count, respin count, probabilities, prize weights, jackpot tiers and cap.
  • Never silently fall back to hold_and_spin behavior.
  • Never edit frozen game versions in place.
  • Persisted state includes a mechanic version; incompatible state fails closed or follows an explicit migration/version-routing rule.
  • Retry and reconnect resume the same step without new RNG or wager.
  • Full-grid Grand and the 500× cap apply exactly once at settlement.
  • Existing games without hold_and_win must remain byte-for-byte and behaviorally unchanged in golden/parity evidence.

Backend response contract and documentation gate

Runtime routing and its real serialized response are required deliverables, not optional follow-up work. The canonical response contract is the implemented game-engine handler/domain types plus apps/game-engine/api/openapi.yaml; design examples are never treated as proof of the wire format.

Every trigger, respin, reconnect/replay and settlement response must provide enough authoritative state for a client to reconstruct the 3×5 feature without local outcome inference. The contract must expose a complete ordered snapshot of all 15 cells and a per-step delta of newly landed prizes. Each cell identifies its stable index, column, row, locked/empty state and prize when locked. The response also carries mechanic version, feature status, current and expected step index, respins remaining, locked count, accumulated award and settlement/Grand/cap fields when applicable.

After the runtime response exists and integration tests capture its serialized form, create games/hold-and-win-reference/gdd/hold-and-win-backend-response.md. Derive this document from the actual backend response and OpenAPI schema. Include trigger, ordinary respin, duplicate-step replay, reconnect and settlement examples taken from deterministic test fixtures. Link it from the game README, GDD, Math Spec and handoff protocol.

Any backend response-field change invalidates the response examples and runtime parity evidence. Regenerate and review the documentation before FREEZE & HANDOFF.

Required verification

  • Trigger boundary at five and six BONUS symbols.
  • Initial lock import and prize assignment order.
  • Empty-cell-only redraw.
  • Landing resets respins; miss-only step decrements.
  • Zero-respin and full-grid termination.
  • Mini, Minor, Major and full-grid Grand semantics.
  • Ordinary sum and single 500× cap.
  • Stable draw order and same seed/state/step identity reproduction.
  • Interrupted-state replay and duplicate-step idempotency.
  • Step execution equals RunToCompletion.
  • JSON/domain/engine round trip and invalid-config rejection.
  • Reference pack → engine → seeded batch simulation parity.
  • Serialized backend responses contain a complete 15-cell snapshot plus the exact newly-landed delta and match OpenAPI/documented deterministic fixtures.
  • Regression proving existing games and the partial hold_and_spin feature are unchanged.

Approval gates

  1. AWAITING_USER_APPROVAL — DESIGN: approve this contract and the initial Draft documents before production code.
  2. AWAITING_USER_APPROVAL — DRAFT MATH: approve observed behavior and tuning direction before tuning.
  3. AWAITING_USER_APPROVAL — FREEZE & HANDOFF: approve the reconciled Final and protocol hashes before declaring developer-ready.

No internal test, simulation or handoff approval is external certification.