# Virtue Slots A browser-based slot machine game with a Christian religious theme, built with Phaser 3 and vanilla JavaScript. May Fortune Favor the Faithful. ![Game preview: three spinning reels with religious symbols, gold UI, and animated win effects](assets/symbol_sprites.png) --- ## Features - **10 holy symbols** — from Dove to Holy Grail, each with unique payout values scaled by holiness - **Animated reels** — smooth spin, decelerate, and snap-to-symbol with sprite overlays - **Win sequence** — "MATCH: 3×" banner punches in with elastic animation, sparkles, and shaking; followed by arcing coin animations splitting 60% to the player and 40% to The Lord - **Loss sequence** — a devil carries the spent money up to the Sin box with a wobble animation - **Split labels** — on a win, animated callouts show "YOUR WINNINGS 60%" and "THE LORD'S TITHE 40%" so the player always understands where the money goes - **The Reckoning** — two filling vials on the right track cumulative funds for "The Lord" and "Sin"; whichever reaches $2,000 first wins; vials shake progressively harder as they approach the limit - **Living background** — stars drift, twinkle, and pulse independently for an ambient celestial feel --- ## Tech Stack | Thing | Choice | |---|---| | Game engine | [Phaser 3](https://phaser.io/) via CDN | | Language | Vanilla JavaScript — ES6 modules | | Bundler | **None** — files are served directly | | Canvas | 1600 × 900, FIT + CENTER scale mode | --- ## Running Locally Browsers block ES6 module imports from `file://`, so serve over HTTP: ```bash # Python (built-in) python3 -m http.server 8080 # Node (npx) npx serve . ``` Then open **http://localhost:8080** in any modern browser. --- ## Controls | Action | Input | |---|---| | Spin | Click the **SPIN** button | | Spin | Press **Space Bar** | --- ## Game Economy | Setting | Value | |---|---| | Starting funds | $1,000 | | Cost per spin | $50 | | Win rate | ~1 in 15 spins | | Win split | 60% to player · 40% to The Lord | | Loss result | $50 added to the Sin total | --- ## Symbols & Payouts Symbols are ordered by holiness. A three-of-a-kind match pays the symbol's full payout value. | Symbol | Holiness | Payout | |---|---|---| | Dove | 1 | $200 | | Joel Osteen | 2 | $300 | | Holy Bible | 3 | $400 | | Lamb of God | 4 | $500 | | Crown of Thorns | 5 | $600 | | Halo | 6 | $700 | | The Cross | 7 | $900 | | Jesus on Cross | 8 | $1,100 | | Baby Jesus | 9 | $1,300 | | Holy Grail | 10 | $1,500 | --- ## Project Structure ``` index.html Loads Phaser 3 (CDN) and main.js as type="module" main.js Phaser.Game config — registers all three scenes state/ GameState.js Singleton: playerFunds, lordFunds, sinTotal, spinning flag utils/ RNG.js shouldWin() (~1/15), pickResults() for reel targets objects/ Symbol.js SYMBOLS array — id, label, holiness, payout, color Reel.js Single reel: virtual infinite strip, pooled cells, sprite overlay SlotMachine.js Orchestrates 3 reels; manages spin timing and result callback WinAnimation.js Match banner → gold flash → arcing coin animation → split labels LossAnimation.js Devil graphic rises to the Sin box MatchBanner.js Full-screen "MATCH: 3× {label}" overlay with particle burst VialDisplay.js Filling vial with shake escalation and winner detection scenes/ BootScene.js Preloads assets (symbol spritesheet), then starts game GameScene.js Background, stars, slot machine, vials, input handling UIScene.js Overlay HUD: fund boxes (top), message + SPIN button (bottom) assets/ symbol_sprites.png 200×100 px spritesheet — 10 frames, one per symbol in order ``` --- ## Scene Communication Scenes communicate exclusively through the global Phaser event bus (`this.game.events`): | Emitter | Event | Payload | |---|---|---| | UIScene | `spin` | — | | GameScene | `win` | `{ playerGain, lordGain, symbol }` | | GameScene | `loss` | `{ sinAdded }` | | GameScene | `funds-updated` | — | | GameScene | `spin-complete` | — | | GameScene | `insufficient-funds` | — | | VialDisplay | `vial-winner` | `{ winner }` | --- ## Sprite Sheet `assets/symbol_sprites.png` must be a horizontal sprite sheet: - **Frame size:** 200 × 100 px - **Frame count:** 10 (one per symbol) - **Frame order:** must match the `SYMBOLS` array order in `objects/Symbol.js` (Dove at index 0, Holy Grail at index 9) --- ## License Do whatever you want with it. Probably don't build a real gambling site.