Skip to content
battastudioPublic

About

๐ŸŽฎ Arcade of 46 two-player games โ€” play peer-to-peer with a friend (WebRTC) or solo vs a bot. Vanilla-JS PWA, no server, no sign-up.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

ย 

History

63 Commits

Folders and files

Repository files navigation

๐ŸŽฎ Arcade โ€” 2-Player Games

50 games + a toolbox. One friend. Zero servers.

Play classic board games, puzzles, and real-time arcade duels peer-to-peer with a friend over WebRTC โ€” or solo vs a bot. Plus a Tools drawer of game-night utilities and a fully synthesized soundtrack. No backend, no build step, no sign-up, no bundled assets to license. Installable as an offline PWA.

PWA WebRTC Vanilla JS i18n Games License

2 players ยท peer-to-peer ยท no sign-up


๐Ÿ‘€ Screenshots

Home โ€” game grid, Game of the Day, Tools
๐Ÿ’ก A game (Lights Out) ๐Ÿงฐ Tools drawer
Lights Out solo puzzle Dice, coin, timer, scoreboard, picker

โœจ Features

  • ๐Ÿ•น๏ธ 50 games across Classic ยท Strategy ยท Puzzle ยท Arcade ยท Luck ยท Word โ€” from Chess and Go to Tetris, 2048, and newcomers Notakto, Domineering, Lights Out, and Word Ladder.
  • ๐Ÿ‘ฅ Three ways to play โ€” P2P vs a friend (all games, over WebRTC), vs Bot (~42 games, easy/medium/hard), or Solo (2048, Tetris, Snake, Minesweeper, Sudoku, Word Race, Match3, Level-2048, Lights Out, Word Ladder).
  • ๐Ÿงฐ Tools drawer โ€” non-game utilities for game night: dice roller, coin flip, countdown timer, a persistent scoreboard, and a random name / team picker.
  • ๐ŸŒŸ Game of the Day โ€” one deterministic pick, the same for everyone, refreshed daily on the home screen.
  • ๐ŸŒ Find players online โ€” a lightweight public directory (MQTT) lets you see others, invite, and play; the match itself stays peer-to-peer.
  • ๐Ÿ”’ No server, secrets stay local โ€” for Number Duel / Battleship your hidden state never leaves your device; peers only exchange move feedback.
  • โ™ป๏ธ Resilient matches โ€” either player can Pause; a drop auto-pauses and auto-resumes on rejoin; a refresh restores your board & history (within ~30 min).
  • ๐Ÿ” Switch games without leaving the room and pick the first-move rule (coin toss / host first / loser first).
  • ๐Ÿ“– Learn any game โ€” a How to play panel with a looping CSS/JS demo of the mechanic; ? reopens it mid-game.
  • ๐ŸŒ English / ุงู„ุนุฑุจูŠุฉ (RTL), ๐Ÿ”Š fully synthesized audio โ€” Web Audio sound effects and generative ambient music, no audio files shipped โ€” plus a profile / leaderboard / loyalty system (levels, coins, rating) and 9 accent themes.
  • ๐Ÿ“ฑ Installable PWA โ€” works fully offline after first load.

๐Ÿ›  How it works

flowchart LR
    A([Player A]) <-->|WebRTC data channel ยท PeerJS| B([Player B])
    A -. presence/invites only .-> M[(Public MQTT broker)]
    B -. presence/invites only .-> M
    subgraph Engine["js/platform.js โ€” game-agnostic shell"]
      P[home โ†’ connect โ†’ lobby โ†’ toss โ†’ play โ†’ over]
    end
    A --- Engine
    B --- Engine
Loading

js/platform.js is a game-agnostic engine: it handles the connection, lobby, coin toss, turns/timer, pause-resume, and solo/bot loopback. Each game is a small module under js/games/ that plugs into a shared lifecycle API (start, onMessage, onTurn, endGame, plus botMove for bot play). Pure rules live in js/logic.js; every game is registered in js/app.js.

Tech: vanilla JS ES modules (no build) ยท Tailwind via CDN ยท PeerJS (WebRTC) ยท MQTT.js (presence) ยท Canvas for real-time games ยท service worker for offline. Deploys to GitHub Pages.


๐Ÿš€ Quick start

ES modules + WebRTC need http://localhost (not file://). From the repo root:

git clone https://github.com/hassanannajjar/dual_game.git
cd dual_game

python3 -m http.server 8000

Open http://localhost:8000/ in two browser windows to play both sides. One creates a room and shares the code (or a deep link โ€ฆ/?g=<game>&room=<CODE>); the other joins.

Run the logic self-check:

node test.mjs

Deploy: push to GitHub Pages (root, main) โ€” .nojekyll is included so js/ is served as-is. Live pattern: https://hassanannajjar.github.io/dual_game/. Before a deploy, bump the cache-buster + service-worker version:

./bump-version.sh 49     # rewrites ?v= tags and the SW cache name (currently v48)

๐ŸŽฏ The 50 games

Show all 50 โ€” Classic ยท Strategy ยท Puzzle ยท Arcade ยท Luck ยท Word

Number Duel ยท Tic-Tac-Toe ยท Connect Four ยท Rock Paper Scissors ยท Battleship ยท Gomoku ยท Reversi ยท Checkers ยท Dots & Boxes ยท Ultimate TTT ยท Mancala ยท Memory ยท Nine Men's Morris ยท Chess ยท Hangman ยท Snakes & Ladders ยท Pig ยท Go ยท Order & Chaos ยท Nim ยท Yahtzee ยท Hex ยท Ludo ยท Backgammon ยท Chinese Checkers ยท 2048 ยท Tetris ยท Air Hockey ยท Tron ยท Minesweeper ยท Snake ยท Sudoku ยท Sim ยท Wordle Duel ยท Farkle ยท Quarto ยท Mastermind ยท Dominoes ยท Word Race ยท Match3 ยท Pentago ยท Breakthrough ยท Lines of Action ยท Onitama ยท Quoridor ยท Level 2048 ยท Notakto ยท Domineering ยท Lights Out ยท Word Ladder

(bold = real-time arcade duels; italic = added in the latest update; the canonical list + categories live in js/app.js)


๐Ÿ“ Project structure

dual_game/
โ”œโ”€โ”€ index.html            # app shell: home grid, lobby/connect/play screens, CDN deps
โ”œโ”€โ”€ app.css               # neon theme layered on Tailwind CDN
โ”œโ”€โ”€ js/
โ”‚   โ”œโ”€โ”€ app.js            # entry โ€” registers all 50 games + categories, boots the app
โ”‚   โ”œโ”€โ”€ platform.js       # engine โ€” connection, lobby, toss, turns, pause/resume, bot/solo, Game of the Day
โ”‚   โ”œโ”€โ”€ logic.js          # pure game rules (shared, unit-tested)
โ”‚   โ”œโ”€โ”€ games/*.js        # one module per game
โ”‚   โ”œโ”€โ”€ tools.js          # non-game utilities (Tools screen)
โ”‚   โ”œโ”€โ”€ presence.js       # MQTT online directory + leaderboard
โ”‚   โ”œโ”€โ”€ i18n.js ยท sound.js ยท profile.js ยท loyalty.js ยท demos.js  # subsystems (sound.js = SFX + generative music)
โ”œโ”€โ”€ sw.js                 # service worker โ€” offline app shell
โ”œโ”€โ”€ manifest.webmanifest  # PWA install metadata + icons
โ”œโ”€โ”€ bump-version.sh       # release: bump ?v= tags + SW cache
โ”œโ”€โ”€ test.mjs              # Node self-check (logic + EN/AR i18n parity)
โ”œโ”€โ”€ CONTRIBUTING.md ยท CLAUDE.md   # the golden rules
โ””โ”€โ”€ .github/workflows/ci.yml      # CI: runs node test.mjs

New game? The whole recipe is in docs/ADDING_A_GAME.md.


๐Ÿค” Honest limitations

  • Strict NATs may fail. PeerJS uses free public signaling with no TURN relay, so some corporate/mobile networks can't establish the P2P link.
  • Trust-based. There's no server referee โ€” peers exchange moves directly, so it assumes a friendly opponent.
  • Resume window. Refresh-resume works per-browser for ~30 minutes.
  • Online presence isn't private. The public MQTT "circle" is best-effort and visible to anyone on that broker โ€” use a non-obvious circle name for a private group.
  • Music is generative, not curated. The default soundtrack is synthesized ambient (no files). Prefer your own tracks? Drop rights-cleared MP3s in audio/ and list them in audio/tracks.json.

๐Ÿ“„ License

MIT ยฉ 2026 Hassan Al-Najjar. No third-party assets are bundled โ€” all sound and music are synthesized at runtime โ€” so the repo is clean to fork, host, and redistribute. Contributions welcome: see CONTRIBUTING.md.

โš ๏ธ Disclaimer

A personal, for-fun project. Peer-to-peer play is unmoderated and trust-based (no server referee).

About

๐ŸŽฎ Arcade of 46 two-player games โ€” play peer-to-peer with a friend (WebRTC) or solo vs a bot. Vanilla-JS PWA, no server, no sign-up.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages