A sleek, single-page PWA arcade with four classic games, wrapped in a cyberpunk "strictly red" neon aesthetic.
Memory Card · Rock Paper Scissors · Snake · Tic Tac Toe · installable as an app · no build step, no frameworks, no backend.
- ✨ Features
- 🕹️ Games included
- ⌨️ Keyboard shortcuts
- 🛠️ Tech stack
- 🚀 Installation and usage
- 📂 Code structure
- 🛡️ Security and reliability notes
- 🎨 Customization
🎮 4 classic games. Memory Card, Rock Paper Scissors, Snake, and Tic Tac Toe, all in one page.
📱 Fully responsive. Mobile-first design with touch controls and dynamic layouts that adapt to any screen size.
📴 PWA support. Installable on desktop and mobile. Includes a real,
versioned service worker (sw.js) for offline caching and dynamically
generates app icons via Canvas.
🔊 Web Audio API sound engine. Generates retro 8-bit sound effects dynamically — no external audio files needed.
📊 Local stats tracking. Saves total games played, win counts, Snake high
scores, and Memory best times using localStorage.
✨ Rich animations. Animated aurora background, floating glowing orbs, twinkling starfields, confetti on wins, and smooth page transitions.
♿ Accessible. Full keyboard navigation (including Tab/Enter/Space through Memory and Tic Tac Toe grid cells, not just global shortcuts), visible focus indicators, ARIA labels for screen readers, and pinch-to-zoom left enabled for low-vision users.
🔒 Hardened by default. A restrictive Content-Security-Policy meta tag
ships in <head>, and offline support runs through a real, versioned service
worker file rather than a runtime-generated one.
Match pairs of emojis before the clock runs out.
- Difficulties: Easy (4×4), Medium (6×4), Hard (6×6).
- Mechanics: Cards are revealed for a set "peek" time before flipping back. Tracks moves, pairs, and completion time.
Test your instincts against a randomized AI.
- Mechanics: Animated shaking hands, dynamic win/lose glow effects, and streak tracking (with bonus confetti for 3+ win streaks).
The classic grid game with modern twists.
- Game modes:
- Classic: Hit a wall and you die.
- No Walls: Wrap around to the opposite side of the screen.
- Obstacles: Navigate around randomly generated red blocks.
- Timed: Race against a 60-second countdown.
- Mechanics: Dynamic speed scaling (gets faster as you eat), pulsing food, and a gradient-colored snake.
Classic 3×3 grid strategy.
- Modes: Play vs AI or 2-player local.
- AI difficulties: Easy (random), Medium (mix of random and optimal), Hard (unbeatable Minimax algorithm).
| Key | Action |
|---|---|
1, 2, 3, 4 | Select games from the homepage |
Esc | Close modal or return to homepage |
WASD / Arrow keys | Move snake |
Space | Pause/resume Snake |
Enter | Start Snake game |
- HTML5: Semantic structure, Canvas API for Snake rendering, inline SVGs for crisp game icons.
- CSS3: CSS custom properties for theming, CSS Grid/Flexbox for layouts, 3D transforms for card flips, and keyframe animations for ambient effects.
- JavaScript (ES6+):
- Web Audio API for procedural sound generation.
- Minimax algorithm for the Tic Tac Toe AI.
- Blob URLs for dynamic manifest generation.
- Fonts: Google Fonts (
Space Grotesk,JetBrains Mono) and a custom-loaded pixel font (PixelPurl.woff2) for the hero title.
The app is a single HTML file, but it needs its sw.js, favicon assets, and font file kept in the same folder:
- Download
index.html,sw.js, thefavicon/folder, andPixelPurl.woff2. - Serve them from the same directory. Opening
index.htmldirectly viafile://(double-click) still works for gameplay, but offline caching won't activate — service workers require a secure context (https://, orhttp://localhostduring local development).
Push index.html, sw.js, favicon/, and PixelPurl.woff2 to the repo root (or /docs) and enable Pages in the repo settings — no build step needed. Once served over HTTPS, the service worker, install prompt, and offline caching all work as expected.
| Platform | Steps |
|---|---|
| Desktop (Chrome/Edge) | Click the install icon (⊕) in the address bar, or click Install App in the nav bar |
| Mobile (Safari/iOS) | Tap Share, scroll down, tap Add to Home Screen |
| Mobile (Chrome/Android) | Tap the three-dot menu, select Add to Home screen |
Once installed, the game works offline, and your stats are saved locally on your device.
The application is a single HTML document plus three small supporting files that must sit alongside it:
| File | What it does |
|---|---|
sw.js | The offline-caching service worker. Must be a real file served from the same origin/path as index.html; browsers reject service worker registration from blob/inline sources, so this can't be generated at runtime. |
PixelPurl.woff2 | Adds a nostalgic pixel-font feel to the "Four Game" title on the main page. |
favicon/ | Icons used for browser tabs, bookmarks, and home screens. |
Inside index.html:
<style>— All CSS variables (the "Strictly Red" theme), layout rules, animations, and responsive media queries.<body>— The HTML structure for all 5 "pages" (Home, Memory, RPS, Snake, Tic Tac Toe), toggled via a.activeclass.<script>— All JavaScript logic, organized into clear sections:- SVG icon injection
- PWA setup (manifest, icons, service worker registration)
- Web Audio sound engine
- Game configurations &
localStoragestat management - UI routing (modals, toasts, page switching)
- Individual game logic modules (Memory, RPS, Snake, Tic Tac Toe)
This app has no backend and no user-generated text input, so there's no meaningful XSS/injection surface — but a review turned up a few real bugs and gaps, since fixed:
- 📴 Offline caching now actually works. The service worker used to be generated at runtime from a
BlobURL, which Chrome and Firefox both silently reject per spec — offline support never activated despite the install prompt working fine. It's now a realsw.jsfile with proper cache versioning/cleanup on activate. - 🔒 Content-Security-Policy meta tag added, restricting
object-src,base-uri,form-action,frame-ancestors, and remote fetch targets. (script-src/style-srcstill need'unsafe-inline'since this is intentionally a single self-contained file.) - ⌨️ Keyboard accessibility fixed for Memory and Tic Tac Toe: grid cells are now focusable (
tabindex,role="button",aria-label) and operable with Enter/Space, with visible focus outlines. Pinch-to-zoom is no longer disabled. - 🐛 Gameplay bugs fixed: Tic Tac Toe no longer lets a player sneak in a second move during the AI's "thinking" delay; Rock Paper Scissors no longer double-counts rounds from rapid clicking; Snake no longer falsely ends the game when the head moves into the cell its own tail is vacating that same tick.
Want to change the theme? All primary colors are defined as CSS variables at the top of the <style> block under :root.
:root {
--red:#ff0033;
--crimson:#dc143c;
--dark-red:#8b0000;
--green:#34d399; /* Used for success/win states *//* ...other variables */
}