Last updated: 2026-05-29
SnapOut turns pre-trade discipline into a short arcade loop. The player practices interrupting impulsive trades by making fast decisions under pressure, with the game rewarding avoided losses and punishing chased trades.
- Retail trader tempted by FOMO, meme stocks, crypto, options, or high-volatility trades.
- User does not need portfolio analysis; they need immediate behavioral rehearsal.
- The MVP is a standalone browser game, not a brokerage-connected guardrail.
- Player starts an eight-card FOMO Defense run.
- Each round presents an impulse card with ticker, trade size, drawdown risk, bait, headline, and note.
- Player chooses
Snap Outbefore the timer expires to bank the projected avoided loss. - Player can choose
Take Trade, which subtracts the projected loss from cash and raises heat. - Letting the timer expire records a frozen decision and raises heat without changing cash.
- The run ends in a win after eight rounds, or a loss when cash hits zero or heat reaches 100.
ready
-> playing start run
playing
-> playing snap / yolo / timeout while status remains playable
-> finished round cap reached, cash wiped, or heat maxed
finished
-> playing play again / restart
Rules live in src/gameLogic.js and are covered by src/gameLogic.test.js.
- Starting cash:
$10,000. - Starting heat:
30. - Max heat:
100. - Max rounds:
8. - Potential loss:
Math.round(card.amount * card.drawdown). snap: preserves cash, adds avoided loss tosaved, lowers heat, increases streak and score, logssaved.yolo: subtracts potential loss from cash, raises heat, resets streak, increments misses, logslost.timeout: leaves cash unchanged, raises heat, resets streak, increments misses, logsfroze.
Game state is plain React state backed by deterministic helpers.
cash: remaining player cash.saved: cumulative avoided loss.heat: impulse pressure meter.streak: consecutive snap decisions.score: run score.misses: chased or frozen decisions.round: completed rounds.ledger: latest run decisions.IMPULSE_DECK: static card deck with ticker, amount, drawdown, bait, headline, and note.
- Primary app:
src/SnapOutApp.jsx - Game rules:
src/gameLogic.js - Rule tests:
src/gameLogic.test.js - Entry wrapper:
src/App.jsx - Mount point:
src/main.jsx - Styling: Tailwind classes plus
src/index.css - HTML shell:
index.html - Player-facing app copy, card prompts, feedback, and HTML metadata are currently localized to Simplified Chinese.
- Replaced stale Vite page title/favicon with SnapOut game metadata.
- Replaced the old non-persistent "Log Action to Phantom Ledger" button with an actual in-session ledger.
- Added deterministic game logic tests.
- Fixed action-button text clipping found during browser verification.
- The loss estimate is a hard-coded gameplay heuristic, not financial advice or a validated risk model.
- The game loop may train hesitation, but it does not prevent real trades.
- Ledger entries are in-memory only and disappear on refresh.
- Difficulty tuning is unvalidated.
- Any future real-money, brokerage, or user-account feature needs a compliance and safety review.
- Add local persistent ledger and best-run history.
- Add difficulty settings for timer length, heat penalties, and deck composition.
- Add a short post-run summary with the player’s most costly avoided impulse.
- Add sound and reduced-motion preferences.
- Add browser-level end-to-end tests for the start, snap, yolo, timeout, and restart paths.