Skip to content

Latest commit

 

History

224 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ShapeKeeper

Game Version

A modern, browser-based implementation of the classic Dots and Boxes game (reimagined as ShapeKeeper) with adaptive landscape layouts, smooth animations, and touch support.

License Deployment

🌐 Live Demo

Play Now: https://shape-keeper.vercel.app

🎮 Features

Core Gameplay

  • Classic Dots and Boxes mechanics - Connect dots to create boxes and score points
  • Diagonal Lines - Connect dots diagonally for alternative paths
  • Two-player turn-based gameplay - Players alternate turns, with bonus turns for completing shapes
  • Turn-Based Online Multiplayer - Chess-like communication with Convex backend
  • Live Lobby + Invite Link - Real-time waiting room with a shareable ?join=…&passcode=… URL and a one-tap copy button
  • Silly [Adjective][Animal] passcodes - Lobby auth codes like EasterPig and SillyRabbit, dynamically generated per room (no env, no random letters, no numbers)
  • Opponent Tap Mechanic (multiplayer) - Tap an opponent's completed box to drop its multiplier from 2x → 0.5x before they reveal. Real-time hand-eye coordination layer on top of turn-based play.
  • Smart turn logic - Complete a square, keep your turn!
  • Real-time score tracking - Live updates for both players
  • Party Mode 🎉 - ALL squares have tile effects (dares, hypotheticals, powerups, traps)

Visual Enhancements

Screenshot from 2026-08-18 20-00-38 Screenshot from 2026-08-18 17-04-04

  • Adaptive Landscape Layout - Automatically optimizes grid for landscape displays (e.g., 30x30 becomes ~50×18)
  • Miniaturized Design - Dots are 5× smaller than traditional implementations for more gameplay area
  • Smooth Animations - Particle effects and shape completion animations
  • Pulsating Lines - Visual feedback for newly drawn lines
  • Touch Visuals - Ripple effects for touch interactions
  • Color Customization - Choose your own player colors
  • Motion Trails - Particles leave fading trails for persistence of vision
  • Ambient Particles - Floating background particles create atmosphere
  • Dynamic Background - Gradient shifts based on game state
  • Screen Shake - Feedback on multi-shape completions
  • Combo System - Visual escalation for consecutive shape completions
  • Victory Fireworks - Celebratory effects when game ends
  • Dark Mode - Toggle between light and dark themes
Screenshot from 2026-08-21 15-54-29 Screenshot from 2026-08-21 15-55-06

Audio Features

  • Procedural Sound Effects - Web Audio API generates all sounds (no audio files)
  • Line Draw Sounds - Ascending tones when connecting dots
  • Square Completion Chords - Harmonious feedback on scoring
  • Combo Arpeggios - Musical escalation for streaks
  • Victory Fanfare - Celebratory melody at game end
  • Sound Toggle - Enable/disable audio with persistent preference

Technical Features

  • Convex Backend - Real-time multiplayer with ACID transactions
  • Vercel Deployment - Edge network for low latency globally
  • Pure Vanilla JavaScript - No frontend frameworks
  • HTML5 Canvas Rendering - Smooth, hardware-accelerated graphics
  • Multi-touch Support - Native touch handling for tablets and phones
  • Responsive Design - Adapts to any screen size
  • Fullscreen Mode - Immersive gameplay experience
  • Landscape Optimization - Best experience in landscape orientation

🚀 Quick Start

Option 1: Local Web Server (Recommended)

# Using Python 3
python -m http.server 8000

# Using Node.js (with http-server)
npx http-server

# Using PHP
php -S localhost:8000

Then visit http://localhost:8000 in your browser.

game.js and welcome.js are loaded as browser ES modules, so opening index.html directly with file:// is no longer a supported startup path.

Option 2: Live Deployment

Visit https://shape-keeper.vercel.app.

🚀 Deployment

Important: All commands must run from the ShapeKeeper/ directory (where package.json and convex/ live), not the repo root. Running vercel or convex from the root fails or deploys the wrong folder.

Prerequisites

  • A linked Vercel project (shape-keeper) and Convex project (shapekeeper).
  • Local .env.local with CONVEX_DEPLOYMENT / CONVEX_DEPLOY_KEY for the dev backend (oceanic-antelope-781) — used for local development only.
  • Production frontend is wired to the prod Convex backend (precise-ladybug-504.convex.cloud) via config.js (no build step). Override window.CONVEX_URL in a separate script BEFORE config.js to point at a different deployment.

Security headers (vercel.json)

The deployment ships strict response headers via vercel.json:

  • Content-Security-Policy: default-src 'self'; script-src 'self' https://unpkg.com; connect-src restricted to the Convex deployment; frame-ancestors 'none'; object-src 'none'. No unsafe-inline for script-src.
  • Subresource Integrity: the Convex browser bundle is loaded from unpkg.com/convex@1.42.3 with an integrity="sha384-..." attribute. If unpkg is compromised or the package bytes change, the browser refuses to load the script. Bump the hash in index.html when changing the version: curl -sSL https://unpkg.com/convex@<ver>/dist/browser.bundle.js | openssl dgst -sha384 -binary | openssl base64 -A.
  • HSTS, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, X-Frame-Options all set.
  • HTML files are served with Cache-Control: public, max-age=0, must-revalidate so deploys are picked up immediately; config.js is cached 5 minutes.
Screenshot from 2026-08-21 15-57-47

Commands

cd ShapeKeeper

# 1. Deploy backend functions to the PROD Convex deployment
npx convex deploy --yes

# 2. Deploy the static frontend to Vercel (no build step; serves index.html as-is)
vercel --prod

# Local development (uses dev Convex backend via .env.local)
npx convex dev
npm run serve   # python -m http.server 8000

If you push main to GitHub, Vercel auto-deploys the frontend from this directory. Backend changes still require npx convex deploy --yes.

📐 Grid Sizes

The game offers four preset grid sizes that automatically adapt to your display:

Selection Square Mode Landscape Mode* Total Squares
5×5 5×5 grid ~7×4 grid 16 squares
10×10 10×10 grid ~16×7 grid 81 squares
20×20 20×20 grid ~33×14 grid 361 squares
30×30 30×30 grid ~50×18 grid 841 squares

*Landscape mode activates when aspect ratio > 1.5

🎯 How to Play

Game Rules

  1. Objective: Complete more squares than your opponent
  2. Turns: Players alternate drawing lines between adjacent dots
  3. Scoring: Complete a square by drawing its fourth side to earn a point
  4. Bonus Turn: Complete a square to earn another turn immediately
  5. Multipliers: Tap completed squares to reveal score multipliers
  6. Winning: Player with the most points when the grid is full wins

Controls

  • Mouse: Click dots to select and connect them
  • Touch: Tap dots on touchscreen devices
  • Selection: Click a dot, then click an adjacent dot to draw a line
  • Visual Feedback: Selected dot shows a colored ring
  • Multipliers: Click/tap completed squares to reveal and apply multipliers

Strategy Tips

  • Plan ahead to avoid giving opponents easy squares
  • Try to complete multiple squares in one turn
  • Control the endgame by managing available moves
  • Watch for "double-cross" patterns

🏗️ Project Structure

ShapeKeeper/
├── index.html              # Main HTML structure (3-screen layout)
├── styles.css              # Styling and responsive design
├── game.js                 # Browser module entry for the game runtime
├── welcome.js              # Browser module entry for lobby/UI bootstrapping
├── dots-and-boxes-game.js  # Main DotsAndBoxesGame class and orchestrator
├── convex-client.js        # Convex browser API wrapper (~450 lines)
├── src/                    # Shared ES6 modules used by the current runtime
│   ├── core/               # Constants, utilities
│   ├── game/               # Game state, input, multipliers
│   ├── effects/            # Particles, tile effects
│   ├── animations/         # Kiss emojis, square animations
│   ├── sound/              # Web Audio API SoundManager
│   └── ui/                 # Theme manager
├── convex/                 # Convex backend
│   ├── schema.ts           # Database schema (rooms, players, lines, squares)
│   ├── rooms.ts            # Room management functions
│   └── games.ts            # Game state functions
├── docs/                   # Documentation
│   ├── development/        # QUICKSTART, CODE_AUDIT, MERGE_CONFLICT_GUIDE
│   ├── planning/           # JOBCARD, CounterPlan, MULTIPLAYER_PLANNING, REFACTORING_PLAN
│   ├── history/            # DEPLOYMENT_STATUS
│   └── technical/          # BENQ_FIX, FEATURE_SUMMARY, PERFORMANCE_IMPROVEMENTS
├── Triangle/               # Triangle feature planning
│   └── canvasBonusFeature.md
├── vercel.json             # Vercel deployment config
└── .github/
    └── copilot-instructions.md  # Development guidelines

🔧 Technical Architecture

Core Components

index.html is the browser entrypoint. convex-client.js is loaded as a classic script so it can expose window.ShapeKeeperConvex, while game.js and welcome.js are loaded as ES modules and serve as the authoritative runtime entry scripts for the competition branch.

DotsAndBoxesGame Class (dots-and-boxes-game.js)

  • State Management: Lines (Set), Squares (Object), Scores (Object)
  • Rendering Engine: HTML5 Canvas with 60fps animation loop
  • Event Handling: Mouse, touch, and resize events
  • Game Logic: Square detection, turn management, win conditions

Key Methods

setupCanvas(); // Adaptive layout calculation
getNearestDot(); // Collision detection for dot selection
checkForSquares(); // Square completion detection
draw(); // Main rendering loop
animate(); // Animation frame management

Data Structures

Line Keys (Normalized)

'1,2-1,3'; // Horizontal line from (1,2) to (1,3)
'1,2-2,2'; // Vertical line from (1,2) to (2,2)
'1,1-2,2'; // Diagonal line from (1,1) to (2,2)

Always sorted to prevent duplicates.

Square Keys

'5,10'; // Square at row 5, column 10

Coordinate System

screenX = offsetX + col × cellSize
screenY = offsetY + row × cellSize
  • Origin: Top-left corner
  • Grid: 0-indexed rows and columns

🎨 Customization

Changing Grid Sizes

Edit index.html to add new grid size buttons:

<button class="grid-btn" data-size="40">40×40</button>

Adjusting Visual Properties

In game.js constructor:

this.dotRadius = 1.6; // Dot size
this.lineWidth = 2; // Line thickness
this.cellSize = 8 - 40; // Cell size range (calculated)

Color Schemes

Default colors can be changed in index.html:

<input type="color" id="player1Color" value="#FF0000" />
<input type="color" id="player2Color" value="#0000FF" />

📱 Browser Compatibility

Browser Version Status
Chrome 90+ ✅ Full Support
Firefox 88+ ✅ Full Support
Safari 14+ ✅ Full Support
Edge 90+ ✅ Full Support
Opera 76+ ✅ Full Support

Requirements:

  • ES6+ JavaScript support
  • HTML5 Canvas API
  • CSS3 (Flexbox, Grid)

🐛 Known Issues & Limitations

  • Opening index.html directly via file:// is not supported because the app boots with browser ES modules
  • Parsing error in VSCode is cosmetic (ESLint configuration)
  • Portrait mode shows rotation prompt (landscape recommended)
  • Very large grids (50×50+) may impact performance on older devices

🔮 Future Enhancements

  • Multiplayer mode planning (see MULTIPLAYER_PLANNING.md)
  • Online multiplayer with Convex + Vercel ✅
  • Lobby system with room codes ✅
  • Sound effects (procedural Web Audio API) ✅
  • Dark/light theme toggle ✅
  • Visual effects overhaul (CounterPlan complete) ✅
  • Diagonal lines support ✅
  • AI opponent with difficulty levels
  • Game replay and save/load functionality
  • Achievement system
  • Custom grid size input
  • Undo/redo moves
  • Tutorial mode for new players

📄 License

MIT License - feel free to use, modify, and distribute.

👨‍💻 Author

Teacher Evan

Created as an educational project demonstrating:

  • Canvas API manipulation
  • Game state management
  • Responsive design patterns
  • Touch event handling
  • Animation techniques

🤝 Contributing

Contributions welcome! Feel free to:

  • Report bugs via Issues
  • Submit pull requests
  • Suggest new features
  • Improve documentation

📝 Version History

v4.5.0 (Opponent Tap Mechanic)

  • Tap-to-collapse (multiplayer) - An opponent can now tap a completed box to drop its effective multiplier from the raw value (typically 2x) down to 0.5x before the owner reveals. The owner races to reveal; the opponent races to tap. Hand-eye coordination. See docs/feature-opponent-tap.md.
  • Schema additions - squares.taps (counter) and squares.effectiveMultiplier (cached post-tap value). Old rows default to 0 / original multiplier.
  • Server validation - tapSquare rejects self-taps, taps on truthOrDare squares, taps during the lobby, and taps on already-revealed squares.
  • Visual feedback - Red ✋ overlay on tapped squares (both players see it; disappears on reveal).
  • Local hot-seat support - The tap is applied locally so the mechanic is testable without a backend.

v4.4.0 (Live Lobby + Silly Passcode)

  • Silly [Adjective][Animal] passcodes - Lobby auth codes like EasterPig and SillyRabbit, dynamically generated per room. Replaces the static-env and 6-letter-random-letter approaches. No numbers, no human names, no real places — see convex/rooms/shared.ts for the word lists and the invariants in convex/rooms/shared.test.js.
  • Live waiting room - New LiveLobbyManager (src/ui/LiveLobbyManager.js) subscribes to Convex and renders the player list in realtime. Players see each other join without refreshing.
  • Invite link - New 🔗 Copy Invite Link button on the lobby screen. Writes a ${origin}/?join=ROOMCODE&passcode=PASSCODE URL to the clipboard. Falls back to a hidden readonly <input> + document.execCommand for insecure contexts.
  • URL pre-fill - Loading the app with ?join=…&passcode=… jumps the user to the join screen with both inputs pre-filled. Documented in docs/feature-multiplayer-lobby.md.
  • Backwards compat - Legacy rooms (no passcode field) still allow code-only joining. The passcode column is v.optional(v.string()) so the schema change is non-breaking.
  • AGENTS.md - New file documenting the passcode rules + live-lobby invariants + repo conventions for future agents.

v4.3.0 (Previous)

  • Party Mode 🎉 - Renamed "Hypotheticals" to "Party Mode" - ALL squares have tile effects
  • Turn-Based Multiplayer Optimization - Chess-like communication prevents glitches
  • State Change Detection - Only updates UI when meaningful state changes occur
  • Debounced Updates - Prevents rapid-fire updates from causing issues
  • Documentation Index - Added docs/README.md for easy navigation
  • Copilot Instructions Index - Table of contents for quick reference
  • Squares-Only Gameplay - Triangle mechanics (added in v4.1.0) were removed; game is squares-only since v4.3.0

v4.1.0

  • Diagonal Lines - Players can connect dots diagonally at 45° angles
  • Triangle Detection - Complete triangles by drawing 2 orthogonal + 1 diagonal line
  • Dark Mode Canvas Fix - Canvas backgrounds now properly read theme state
  • Triangle Scoring - Triangles worth 0.5 points (squares = 1 point)
  • Triangle Visuals - Striped fill pattern distinguishes triangles from squares
  • ES6 Module Structure - Partial refactoring to modular architecture

v4.0.0

  • Complete Visual Overhaul - All CounterPlan phases implemented
  • Procedural Sound Design - Web Audio API sounds (no audio files)
  • Dark Mode - Toggle theme with localStorage persistence
  • Motion Trails - Particle persistence of vision effects
  • Ambient Atmosphere - Floating particles, dynamic gradients
  • Combo System - Visual escalation for consecutive squares
  • Victory Fireworks - Celebratory particle effects
  • Multiplayer Sync Fix - Multipliers synced from server
  • Accessibility - ARIA labels, semantic improvements

v3.0.0

  • Online Multiplayer with Convex backend
  • Lobby System with room codes for joining
  • Vercel Deployment at shape-keeper.vercel.app
  • CounterPlan visual evolution roadmap
  • Real-time game state synchronization

v2.1.0

  • Removed zoom controls for simplified UI
  • Added comprehensive multiplayer planning documentation
  • Score multiplier system for completed squares
  • Improved touch handling

v2.0.0

  • 5× smaller dots for better screen utilization
  • Adaptive landscape layout optimization
  • Enhanced touch support with visual feedback
  • Improved animation system
  • Performance optimizations

v1.0.0

  • Initial release
  • Basic game mechanics
  • Square grid layouts
  • Mouse and touch support

Enjoy the game! 🎮✨

For questions or feedback, please open an issue on GitHub.

About

Resources

Contributing

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages