# Fertig Classic Games A single-page collection of **77 classic games** — board games, card games, casino games, word games, and logic puzzles — all playable in the browser against local AI opponents. Built on [Phaser 3.90](https://phaser.io/). **This is a fully static site.** There is no server, no database, no accounts, no build step, and no `npm install` required to run it. The frontend uses native browser ES modules and loads Phaser from a CDN. Everything that used to be a backend round-trip — the single local player profile, casino chip balance, match history, puzzle progress, and word-game dictionaries/AI — now runs entirely in the browser against `localStorage` and the ported engines in `src/words/`. --- ## Table of contents - [Quick start](#quick-start) - [Deployment / hosting](#deployment--hosting) - [The game catalog](#the-game-catalog) - [Project layout](#project-layout) - [Architecture](#architecture) - [Scene flow](#scene-flow) - [The local "backend"](#the-local-backend) - [Word games](#word-games) - [Assets](#assets) - [Adding a new game](#adding-a-new-game) - [Developer tooling (`tools/`)](#developer-tooling-tools) - [Data files (`data/`)](#data-files-data) --- ## Quick start No dependencies to install. You just need a static file server, because ES modules can't be loaded over `file://`. ```bash git clone cd fertig-classic-games # Any static server works. A couple of one-liners: npm run serve # python3 -m http.server 8000 → http://localhost:8000 ./start_web.sh # python3 -m http.server 3000 → http://localhost:3000 npx serve . # if you prefer Node ``` Then open the printed URL in a modern browser. That's it — pick a game and play. > **Requirements:** a current browser with ES-module + importmap support > (Chrome/Edge/Firefox/Safari, ~2023+). Python 3 (or any static server) for local > hosting. Node.js 20+ is only needed for the optional dev tooling in `tools/`. --- ## Deployment / hosting **The repository root _is_ the site.** Serve it as static files from any web host, CDN, or object store (GitHub Pages, Netlify, Cloudflare Pages, S3, nginx, Apache, …). No configuration, environment variables, or runtime are needed. Because every asset path is relative and `index.html` sets ``, the site works unchanged from a domain root **or any subdirectory** (e.g. `example.com/games/`). To drop it into an existing site: ```bash cp -r index.html styles.css *.png favicon.ico assets data src \ /var/www/parent-site/games/ ``` The only files the deployed site needs are `index.html`, `styles.css`, the favicons/PWA icons in the root, and the `assets/`, `data/`, and `src/` directories. The `tools/` directory is dev-only and never shipped. Player state (profile, chips, history, puzzle progress) lives in each visitor's own browser `localStorage` under the `fcg:` prefix — nothing is stored or synced server-side, so hosting is entirely stateless. --- ## The game catalog 82 games are registered in `src/data/gamesRegistry.js` and grouped into six menu categories: | Category | Count | Examples | |----------|-------|----------| | **Tabletop** | 21 | Backgammon, Chess, Checkers, Go, Othello, Settlers of Catan, Ticket to Ride, Risk, Monopoly, Blokus, Labyrinth, Mahjong, Stratego, Battleship, Mastermind, Connect 4, Forbidden Island, Azul, Chinese Checkers, Mexican Train, Parchisi | | **Cards** | 18 | Cribbage, Gin Rummy, Rummikub, Canasta, Hearts, Uno, Phase 10, Skip-Bo, Go Fish, Old Maid, Nerts, Dominion, Splendor, Freecell, Solitaire Tour, Spire Climb, Zahtzee, Farkle | | **Casino** | 9 | Blackjack, Texas Hold 'Em, Baccarat, Pai Gow Poker, Video Poker, Craps, Roulette, Bingo, Slot Machines | | **Word** | 15 | Wordle Race, Scrabble, Boggle, Ghost, Word Ladder, Word Search, Hangman, Spelling Bee, Sudoku, Mini Crossword, Tectonic, Bookwork, Kiitos, Tri-Ominoes, Jumble | | **Logic & Puzzle** | 14 | 2048, Rush Hour, Hexsweeper, Jell-o Monsters, Shift, Mahjong Match, Jewel Quest, Zuma, Bejeweled Blitz, Mini Motorways, Dot Link, Katamino, Genius Square, Block Fighter | | **Arcade, Console & PC** | 2 | Colorado Defense, Star Control | Each game is a self-contained `Phaser.Scene` (plus its own logic/AI/data helper modules) under `src/games//`. Games are single-player against 0–7 configurable AI opponents depending on the title; several ship a video tutorial. --- ## Project layout ``` fertig-classic-games/ ├── index.html Entry point: importmap for Phaser + ├── styles.css Page chrome (canvas container + DOM overlay layer) ├── package.json "serve" script; no runtime deps ├── start_web.sh Convenience local server (python http.server) ├── favicon*/apple-touch/… Favicons and PWA icons │ ├── src/ The entire application (native ES modules) │ ├── main.js Phaser.Game config; registers every scene; DOM-overlay sync │ ├── config.js Canvas dimensions (1920×1080) and the UI color palette │ ├── data/ │ │ └── gamesRegistry.js The catalog: registerGame() for all 77 games │ ├── scenes/ Shell scenes (menu, profile, opponent select, room) │ ├── services/ api.js → localApi.js → localStore.js (the local backend) │ ├── ui/ Reusable widgets: Button, Modal, TextInput, Portrait, │ │ music/speech/tutorial/fullscreen helpers │ ├── words/ Client-side word-game engines + wordRouter dispatcher │ └── games// One folder per game (Scene + Logic + AI + Data + tutorial.md) │ ├── data/ Static JSON game data + word lists (fetched at runtime) │ ├── *.json Per-game level banks, artwork maps, opponents, music, etc. │ ├── crosswords/ Mini-crossword puzzle bank │ └── wordlists/ enable1.txt (dictionary) + common.txt │ ├── assets/ Runtime media │ ├── images/ Spritesheets, backgrounds, board art (81 files) │ ├── fonts/ Bitmap/web fonts │ ├── fx/ Sound effects (71 files) │ ├── music/ Background music tracks (21 files) │ ├── speech/ AI opponent voice clips (393 files) │ ├── videos/ In-game portrait/animation clips (90 files) │ └── tutorial-videos/ How-to-play videos (17 files) │ └── tools/ Offline dev scripts (run with node; NOT deployed) ├── gen*.js Puzzle/level-bank generators └── verify*.js Headless self-play verification harnesses ``` --- ## Architecture The frontend is deliberately buildless: `index.html` declares an `