Virtue-Slots/README.md

149 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.