# Stonks Casino Game Factory — Model Handoff

Version: 1.0  
Last verified: 2026-08-07  
Audience: coding models and engineers creating additional Stonks Casino games  
Reference implementation: Equity Bros  
Submission target: Ape Church

## 0. Mission

Create original, high-stakes casino games from recognizable finance memes,
controversies, inside jokes, public scrutiny, and market spectacle.

Every game must preserve this simple product promise:

> Players put in APE on ApeChain. Winning players receive stock tokens on
> Robinhood Chain.

Every individual game must still satisfy Ape Church's standard game contract:

```text
input: wager amount + protocol-supplied round data/randomness
output: payout multiplier, including 0x for a loss
```

The game must not implement or invent the cross-chain stock settlement layer.
It returns a multiplier. The Stonks Casino host and the Ape Church-approved
protocol layer are responsible for converting that multiplier into a stock-token
payout.

## 1. Authority order

Before changing code, read the current versions of these sources completely:

1. [Ape Church Build a Game](https://docs.ape.church/building/build-a-game)
2. [Official game template README](https://github.com/ape-church/ape-church-game-template)
3. `SKILL.md` in the current official template
4. [Submissions repository README](https://github.com/ape-church/ape-church-game-submissions)
5. This handoff
6. The approved concept brief for the new game

If this handoff conflicts with a newer official Ape Church requirement, follow
the official requirement and document the difference.

Do not guess an undocumented contract, callback, randomness interface, bridge,
liquidity API, or settlement ABI. Stop at a typed adapter boundary and mark the
integration as blocked until Ape Church supplies the authoritative interface.

## 2. Repository rules

### Development repository

Create a new repository from the official template with:

```text
Use this template → Create a new repository
```

Do not fork the template. Do not build the submission inside the Trade Bangers
monorepo.

Keep all authored game work inside:

```text
components/my-game/
public/my-game/
metadata.json
```

Treat the template's `app/`, `lib/`, shared components, configuration, and
entrypoint as platform-owned unless the current template explicitly says
otherwise.

### Submission repository

Fork `ape-church/ape-church-game-submissions`. Submit one game per pull request
and add exactly:

```text
components/games/<game-slug>/
public/submissions/<game-slug>/
submissions/<team-slug>/<game-slug>/metadata.json
```

Do not submit:

```text
package.json
package-lock.json
next.config.ts
next.config.js
tsconfig.json
app/**
lib/**
components/games/shared/**
*.wav
```

## 3. Required concept brief

Do not implement until the following brief is complete:

```yaml
displayTitle: ""
gameSlug: ""                  # kebab-case
teamSlug: ""                  # kebab-case
financeSource:
  eventOrMeme: ""
  whyPeopleRecognizeIt: ""
  originalSatiricalAngle: ""
playerFantasy: ""
oneSentenceRule: ""
gameType: ""                  # progressive, instant, card, wheel, slots, etc.
wagerAsset: "APE"
houseEdge:
  default: 0.05
  minimum: null               # supplied/approved by Ape Church
  maximum: null               # supplied/approved by Ape Church
maxMultiplier: null
liquidityBehavior: ""
randomnessInputs: []          # only protocol-supplied values
outcomes: []
cashOutPoints: []
autoExitRules: []
failureStates: []
layout: "full-size"           # or two-column
artDirection: ""
audioDirection: ""
consumerCopy:
  betVerb: ""
  winVerb: ""
  lossCopy: ""
  cashOutCopy: ""
assetBudgetBytes: 10000000
category: ""                  # arcade, card, puzzle, strategy, other
tags: []
authors: []
revenueShare: []
```

Reject or revise a concept if it cannot be reduced to:

- one wager amount;
- one deterministic protocol result;
- one final payout multiplier;
- a finite maximum payout;
- disclosed rules a retail player can understand before betting.

## 4. Game-math contract

### Global requirements

For every game:

- `houseEdge` must be supplied or approved by Ape Church and locked for the round.
- All displayed probabilities must match the implementation.
- The maximum multiplier must be explicit and liquidity-bounded.
- A loss returns `0`.
- A win returns one declared multiplier.
- Expected return must equal `1 − houseEdge`, unless Ape Church explicitly
  approves another model.
- Rounding must never create a payout above the disclosed maximum.
- No flavor event, animation, audio cue, or apparent near miss may change odds.

### Discrete outcome games

For mutually exclusive outcomes with probability `pᵢ` and multiplier `mᵢ`:

```text
Σ(pᵢ × mᵢ) = 1 − houseEdge
Σpᵢ = 1
mᵢ ≥ 0
```

Store the payout table in one typed configuration object. Tests must calculate
the expected multiplier directly from that object.

### Progressive or cash-out games

For a strictly increasing ladder `m₁ ... mₙ`:

```text
P(reach rung 1) = (1 − h) / m₁
P(pass rung k | reached k−1) = mₖ₋₁ / mₖ
P(reach rung k) = (1 − h) / mₖ
P(reach rung k) × mₖ = 1 − h
```

This makes every valid cash-out point carry the same expected return.

If the game has mandatory early rounds, the UI must disclose:

- how many rounds are mandatory;
- the chance of reaching the first available cash out;
- the chance to survive the next step;
- the amount currently at risk;
- the next payout multiplier.

### Math approval checklist

Before UI work, produce:

1. the exact payout table or multiplier ladder;
2. theoretical reach and conditional probabilities;
3. maximum multiplier;
4. default house edge;
5. expected multiplier at every selectable exit;
6. a large deterministic simulation agreeing with theory;
7. written confirmation that the math uses no browser randomness.

Do not make a game feel harder by silently increasing the edge. Increase
volatility through fewer wins and larger disclosed prizes while preserving the
approved expected return.

## 5. Randomness and determinism

The chain or Ape Church protocol supplies payout-affecting randomness. The game
consumes it and never generates it.

Forbidden in any payout-affecting path:

```ts
Math.random()
crypto.getRandomValues()
crypto.randomUUID()
Date.now()
performance.now()
untrusted animation timing
network response order
localStorage values
```

Use a deterministic, reviewed mapping from the supplied seed to outcomes. Each
independent use must have a stable domain:

```text
<game-slug>:v<rules-version>:outcome
<game-slug>:v<rules-version>:stage:<index>
<game-slug>:v<rules-version>:presentation:<index>
<game-slug>:v<rules-version>:payout-ticker
```

The payout-ticker domain is only for a host-supplied Stonks Casino presentation
or approved settlement flow. It must not alter the multiplier.

The same locked round inputs must always reproduce:

- the same outcome;
- the same path through the game;
- the same payout multiplier;
- the same presentation events;
- the same completed replay.

Version every stored replay:

```ts
const RULES_VERSION = 1;
const STORAGE_KEY = "<team>:<game-slug>:last-round:v1";
```

Reject a stored replay if its rules version, seed shape, mode, ladder, or result
schema does not match the current game.

## 6. Stonks Casino separation of concerns

### Game layer

The game owns:

- wager entry;
- game-specific choices;
- deterministic outcome mapping;
- multiplier calculation;
- reveal sequence;
- cash-out decisions;
- replay data;
- retail rules and probability displays.

### Ape Church host layer

The host owns:

- wallet and account state;
- wager transaction;
- approved house-edge bounds;
- chain randomness;
- house-pool liquidity and maximum wager;
- payout settlement;
- results modal and platform navigation;
- any standard PnL or sharing surface.

### Stonks settlement layer

The future approved Stonks integration owns:

- locking APE/USD and stock-token/USD prices;
- selecting the stock ticker from an independent randomness domain;
- reserving per-ticker liquidity;
- calculating stock-token units;
- authenticating the cross-chain message;
- paying the player's Robinhood Chain address;
- retries, nonces, finality, and replay protection.

The normalized stock payout is:

```text
stockUnits =
  wagerAPE × lockedAPEUSD × multiplier
  ÷ corporateActionAdjustedLockedStockTokenUSD
```

Until Ape Church approves this layer, label stock settlement as a preview and
do not send a real wager or pretend a stock payout occurred.

## 7. Required component architecture

Use the component names expected by the current template. A full-size game will
normally contain:

```text
components/my-game/
  MyGame.tsx
  MyGameWindow.tsx
  MyGameSetupCard.tsx
  MyGameInGameOverlay.tsx
  myGameConfig.ts
  my-game.styles.css
  gameMath.ts
  gameTypes.ts
  useGameAudio.ts
```

Use fewer files when the game is simple. Do not create abstractions without a
consumer.

Strongly type one consolidated round state:

```ts
type GameView = 0 | 1 | 2;
type GamePhase =
  | "setup"
  | "submitting"
  | "playing"
  | "awaiting-choice"
  | "settling"
  | "won"
  | "lost"
  | "rewatching";

interface RoundSnapshot {
  rulesVersion: number;
  roundId: string;
  wager: string;
  houseEdge: number;
  seed: string;
  mode: string;
  choices: readonly string[];
  terminalStep: number;
  multiplier: number;
  result: "won" | "lost";
}

interface GameState {
  currentView: GameView;
  phase: GamePhase;
  wagerInput: string;
  lockedWager: string | null;
  round: RoundSnapshot | null;
  currentStep: number;
  isBusy: boolean;
  error: string | null;
}
```

Use exact decimal/base-unit utilities supplied by the host for money. Do not
use floating-point arithmetic to create a transaction amount.

## 8. Required lifecycle behavior

Implement the current template lifecycle exactly.

### `playGame()`

Must:

1. reject duplicate invocation while busy;
2. validate wager and game choices;
3. ask the host for a wager/round transaction;
4. lock round inputs and rules version;
5. consume the returned chain result;
6. initialize deterministic game state;
7. surface failures without inventing a result.

### `handleStateAdvance()`

For multi-step games:

1. reject calls outside the valid phase;
2. lock the action immediately;
3. advance exactly one step;
4. resolve from already locked round data;
5. settle at most once;
6. unlock only after the state transition is complete.

### `handleCashOut()`

For cash-out games:

1. allow only at a disclosed cash-out point;
2. reject duplicate or late clicks;
3. settle the current declared multiplier;
4. never calculate a new random result;
5. persist the final exit step.

### `handleReset()`

Must restore byte-for-byte initial behavior:

- reset consolidated state;
- clear errors and busy flags;
- cancel timeouts and intervals;
- cancel animation frames;
- stop and release audio;
- remove event listeners;
- dispose WebGL resources;
- clear stale refs;
- leave no prior-round artwork or result visible.

### `handlePlayAgain()`

Call reset, then create a fresh round with fresh protocol identifiers and a new
wager transaction.

### `handleRewatch()`

Call reset, then replay the stored completed round:

- no wallet prompt;
- no network request for new randomness;
- no new transaction;
- no payout call;
- exact same result and presentation.

## 9. Concurrency and cleanup

Use both a state phase check and an immediate mutable lock for actions that can
be double-clicked before React renders:

```ts
if (actionLock.current || state.phase !== "awaiting-choice") return;
actionLock.current = true;
```

Centralize cleanup:

```ts
const timers = useRef<Set<number>>(new Set());
const frames = useRef<Set<number>>(new Set());
const sounds = useRef<Set<HTMLAudioElement>>(new Set());

function clearRuntimeResources() {
  timers.current.forEach(window.clearTimeout);
  frames.current.forEach(cancelAnimationFrame);
  sounds.current.forEach((sound) => {
    sound.pause();
    sound.currentTime = 0;
  });
  timers.current.clear();
  frames.current.clear();
  sounds.current.clear();
}
```

Call cleanup during reset and unmount. If using Three.js, also dispose geometry,
materials, textures, renderer, loaders/listeners, and detach the canvas.

## 10. Retail experience requirements

The primary game surface is for players, not integrators.

Above the first action, state in plain language:

- what the player bets;
- what the player can win;
- the maximum multiplier;
- the house advantage;
- mandatory steps;
- the chance to reach the first choice;
- whether the build is a free preview.

During play, always show:

- current payout;
- current amount at risk;
- chance to survive the next action;
- chance to lose the full wager;
- cash-out availability;
- the next payout.

On completion, show:

- win or loss;
- final multiplier;
- payout value;
- play again;
- rewatch;
- reset/change bet;
- a collapsed round-proof section.

Use theme vocabulary as secondary flavor. Controls must use familiar retail
language such as `Place Bet`, `Cash Out`, `Keep Going`, `Play Again`, and
`Watch Again`.

Do not use:

- fake near misses;
- undisclosed odds;
- countdowns that prevent an informed choice;
- copy implying guaranteed profit;
- hidden auto-play;
- irreversible audio;
- celebratory effects on a loss;
- deceptive wallet prompts.

Include a visible responsible-gaming statement. Respect reduced motion and
provide a persistent mute control.

## 11. Art, audio, and intellectual property

Use original artwork and original character designs.

Do not copy:

- real financial-firm logos;
- Robinhood branding;
- Ape Church platform assets outside the permitted shared folder;
- public figures or creator likenesses without permission;
- another NFT collection's protected visual identity;
- creator catchphrases or meme artwork verbatim.

Required assets:

```text
public/my-game/card.png       # 1:1, recommended 512 × 512
public/my-game/banner.png     # 2:1, recommended 1024 × 512
```

Other requirements:

- WebP preferred; PNG accepted.
- MP3 or OGG audio only.
- No WAV.
- Total game assets below 10 MB.
- Use absolute public paths: `/my-game/background.webp`.
- Compress images and audio before final validation.
- Provide useful alt text for meaningful images.

For the submission repository, rewrite every asset URL:

```text
/my-game/... → /submissions/<game-slug>/...
```

No `/my-game/` URL may remain in submitted components.

## 12. Metadata

Every required field must be real, final, and internally consistent:

```json
{
  "team": "<team-slug>",
  "gameName": "<game-slug>",
  "displayTitle": "<Game Title>",
  "description": "<Three sentences maximum.>",
  "authors": [
    {
      "name": "<author-name>",
      "telegram": "sixtheplug"
    }
  ],
  "revenueShare": [
    {
      "name": "<recipient-name>",
      "telegram": "sixtheplug",
      "address": "0x191f77208F6EaB1ab223EE402DC32863AC212ACE",
      "share": 100
    }
  ],
  "status": "pending",
  "category": "arcade",
  "tags": ["finance", "<game-tag>"],
  "thumbnail": "/<game-slug>/card.png",
  "banner": "/<game-slug>/banner.png",
  "mainComponent": "<GameName>.tsx",
  "windowComponent": "<GameName>Window.tsx",
  "setupComponent": "<GameName>SetupCard.tsx",
  "configFile": "<gameName>Config.ts",
  "version": "1.0.0",
  "submittedAt": "YYYY-MM-DD"
}
```

Rules:

- Confirm the author name and revenue address before every submission.
- `team` and `gameName` must be kebab-case and match folder names exactly.
- `status` must be `pending`.
- `category` must be `arcade`, `card`, `puzzle`, `strategy`, or `other`.
- Omit `configFile` only if no config file exists.
- Revenue shares must total exactly 100.
- Every revenue address must be a valid EVM address capable of receiving ERC-20
  APE.
- Set `submittedAt` to the actual submission date.
- Re-check the current official schema before committing.

## 13. Exact testing standard

Create automated tests before considering the game complete.

### Configuration tests

Assert:

- exact house edge;
- exact modes and payout table/ladder;
- strictly increasing progressive ladders;
- maximum multiplier;
- mandatory-step count;
- no undeclared outcome;
- payout multipliers never exceed the maximum.

### Expected-return tests

For every selectable exit or result:

```text
theoretical probability × multiplier = 1 − houseEdge
```

Use a tight tolerance for direct formulas.

### Determinism tests

For a large range of seeds:

- resolving twice returns the same outcome;
- every result is within declared bounds;
- every replay produces the same path;
- ticker/presentation derivations do not affect the multiplier;
- invalid stored versions are rejected.

### Statistical tests

Use at least 100,000 deterministic seeds per mode unless runtime makes that
impractical. Compare observed frequencies with theory using a stated tolerance.
The Equity Bros reference uses `0.006` for rung reach rates and `0.01` for a
uniform five-way ticker sample.

Statistical tests supplement exact tests; they do not replace them.

### Source guards

Tests must scan authored game code and fail if payout paths contain:

```text
Math.random(
crypto.getRandomValues(
crypto.randomUUID(
```

Also assert:

- rules version appears in replay storage;
- action-lock guards exist;
- asset version/query strings were bumped after material releases;
- required five stock symbols are present only if the host exposes that feature;
- no development asset path remains in submission files.

### Lifecycle tests

Cover:

- invalid wager;
- protocol rejection;
- first-step loss;
- every win tier;
- manual cash out;
- automatic cash out;
- final-step completion;
- double-click advance;
- double-click settlement;
- reset from every phase;
- play again creates a new round;
- rewatch sends no transaction;
- unmount cleanup;
- stale replay rejection.

### Layout and accessibility tests

Verify:

- desktop;
- tablet;
- narrow mobile;
- keyboard-only operation;
- visible focus;
- touch targets;
- reduced motion;
- muted audio;
- long translated or dynamic values;
- no horizontal overflow;
- no browser console errors.

### Required commands

Run from the official template repository:

```bash
npx tsc --noEmit
npm run lint
npm run build
```

Run the template's current automated test command if one exists. Do not claim
success for a skipped command. Record the exact result of every check.

## 14. Submission transformation

After the development build passes:

1. Clone or update your fork of `ape-church-game-submissions`.
2. Create a clean branch.
3. Copy components:

   ```text
   components/my-game/
   → components/games/<game-slug>/
   ```

4. Copy assets:

   ```text
   public/my-game/
   → public/submissions/<game-slug>/
   ```

5. Copy metadata:

   ```text
   metadata.json
   → submissions/<team-slug>/<game-slug>/metadata.json
   ```

6. Rewrite all asset paths to `/submissions/<game-slug>/...`.
7. Confirm only the three allowed trees changed.
8. Re-run type checking, lint, build, and submission-repository checks.
9. Inspect the final diff for secrets, unrelated files, and generated junk.
10. Open one pull request.

PR title:

```text
[Team Name] Game Name
```

Do not include multiple games in one PR. A merged submission creates a preview;
it does not guarantee production launch. Ape Church manually reviews and
integrates approved games.

## 15. Required final report from the implementing model

The implementing model must return:

```markdown
# <Game Title> delivery report

## Game
- One-sentence rule:
- Game type:
- House edge:
- Maximum multiplier:
- First player decision:
- Loss condition:

## Math
- Exact payout table or ladder:
- Expected multiplier:
- Simulation sample size:
- Largest observed deviation:

## Randomness
- Protocol input consumed:
- Outcome domain:
- Presentation domains:
- Proof no browser randomness affects payout:

## Files
- Development components:
- Development assets:
- Metadata:
- Submission component path:
- Submission asset path:
- Submission metadata path:

## Verification
- TypeScript:
- Lint:
- Build:
- Automated tests:
- Asset total:
- Desktop/tablet/mobile:
- Reduced motion:
- Audio mute:
- Console:

## Submission
- Branch:
- PR:
- CI:
- Reviewer blockers:

## Explicitly not live
- Any unapproved protocol, bridge, stock settlement, or mainnet feature:
```

Never write “submission ready” if any required check is unrun, failing, or
blocked.

## 16. Copy-paste instruction for another model

Use this prompt after filling in the concept brief:

```text
You are implementing one new Stonks Casino game for Ape Church.

Authority order:
1. Read the latest official Ape Church Build a Game documentation.
2. Read the official game-template README and SKILL.md completely.
3. Read the submissions-repository README completely.
4. Read STONKS_CASINO_GAME_FACTORY_HANDOFF.md completely.
5. Read the approved concept brief below.

Do not begin implementation until you can restate the wager input, payout
multiplier output, house edge, maximum multiplier, randomness input, outcome
mapping, and repository boundaries.

Use a new repository created from the official Ape Church template. Do not
implement the submission in the Trade Bangers monorepo. Keep authored work under
components/my-game/, public/my-game/, and metadata.json.

The individual game accepts a wager and returns a multiplier, including 0x.
Consume only Ape Church-supplied randomness. Never generate payout randomness in
the browser. Lock the house edge and rules for the round. Bound the wager and
maximum payout by host liquidity. Keep stock-token conversion and cross-chain
settlement outside the game component.

Implement typed consolidated state and the required playGame, handleReset,
handlePlayAgain, handleRewatch, and, when applicable, handleStateAdvance and
handleCashOut functions. Rewatch must send no transaction. Reset and unmount must
clean every timer, interval, animation frame, listener, sound, and WebGL resource.
Guard every action and settlement against double clicks.

Show retail players the bet, maximum payout, house advantage, mandatory actions,
next-step survival chance, full-loss chance, current cash-out value, and preview
status in plain language. Flavor never changes odds. Do not fabricate near
misses. Support mobile, keyboard, reduced motion, and mute.

Create exact math tests, deterministic replay tests, large-seed simulations,
source guards against browser randomness, lifecycle tests, double-click tests,
cleanup tests, and asset/metadata checks. Run npx tsc --noEmit, npm run lint,
npm run build, and the repository's current test command. Fix all failures.

Then transform only:
components/my-game/ → components/games/<game-slug>/
public/my-game/ → public/submissions/<game-slug>/
metadata.json → submissions/<team-slug>/<game-slug>/metadata.json

Rewrite asset URLs to /submissions/<game-slug>/..., include no forbidden files,
open one PR, and return the delivery report required by the handoff. Do not claim
submission readiness while any verification step or required integration is
blocked.

Approved concept brief:
[PASTE COMPLETED BRIEF HERE]
```

## 17. Definition of done

A new game is complete only when:

- its rules are understandable before the wager;
- exact math matches the approved edge;
- only protocol randomness affects payouts;
- results and replays are deterministic;
- the maximum payout is explicit and bounded;
- all lifecycle actions are idempotent;
- reset exactly restores first-load state;
- every runtime resource is cleaned up;
- the consumer UI is usable on desktop and mobile;
- reduced motion and mute work;
- required art and metadata are complete;
- assets are below 10 MB with no WAV files;
- type checking, lint, build, and tests pass;
- the submission diff contains only allowed paths;
- the PR follows the current Ape Church submission rules;
- unapproved stock settlement and bridge behavior remain outside the game.

