A multiplayer artillery game inspired by Worms, where players answer math questions to determine turn order and then battle it out in physics-based combat!
This is a web-based multiplayer game built with:
- Frontend: Phaser.js 3.70 (game engine) with Matter.js physics
- Backend: Node.js with Express and Socket.IO
- Database: Supabase (PostgreSQL)
- Deployment: GitHub Pages (frontend) + Render.com (backend)
worms-math-game/
├── client/ # Frontend (Phaser.js game)
│ ├── index.html # Main HTML file
│ ├── src/
│ │ ├── main.js # Phaser game entry point
│ │ ├── scenes/ # Game scenes (menu, gameplay, etc.)
│ │ ├── entities/ # Player, projectile classes
│ │ └── utils/ # Helper functions
│ ├── assets/ # Images, sounds, sprites
│ └── package.json
│
├── server/ # Backend (Node.js)
│ ├── index.js # Express + Socket.IO entry point
│ ├── routes/ # REST API routes
│ ├── socket/ # WebSocket event handlers
│ ├── services/ # Business logic (matchmaking, rating, etc.)
│ └── package.json
│
├── shared/ # Shared code between client/server
│ └── constants.js # Game constants, match types, colors
│
└── README.md
- Node.js 16+ and npm installed
- Git (optional)
cd client
npm installcd ../server
npm installCreate a .env file in the server/ directory for Supabase credentials:
SUPABASE_URL=your_supabase_project_url SUPABASE_KEY=your_supabase_anon_key PORT=3000
The server will run without Supabase if credentials are not provided.
cd server
npm startThe server will start on http://localhost:3000
You should see:
=================================
Worms Math Game Server
=================================
Server running on port 3000
Health check: http://localhost:3000/health
WebSocket: ws://localhost:3000
=================================
In a new terminal:
cd client
npm startThis will start a local web server on http://localhost:8080 and open the game in your browser.
You should see the Phaser game window with a "Loading..." or "Connected to Server!" message.
Open your browser or use curl:
curl http://localhost:3000/health
Expected response:
{
"status": "ok",
"timestamp": "2026年04月23日T...",
"supabase": "not configured"
}- Open
http://localhost:8080in your browser - Open browser console (F12)
- You should see:
- "Preloading assets..."
- "Game created!"
- "Connected to server: [socket-id]" (if server is running)
In the browser console, try:
socket.emit('join_matchmaking', { playerName: 'Test' });
You should see a response in the server console.
cd client npm run dev # Starts server without auto-opening browser
cd server npm run dev # Uses Node.js --watch flag for auto-restart
- Turn-Based Artillery Combat - Worms-style physics-based battles
- Math Quiz Integration - Answer math questions to determine turn order
- Real-time Multiplayer - Socket.io powered synchronization
- Destructible Terrain - Dynamic terrain destruction with explosions
- Matter.js Physics - Realistic projectile trajectories
- 1v1 Duel - Head-to-head battles
- Free-For-All (FFA) - Up to 8 players compete
- Team Battles - 2v2, 3v3, 4v4 team modes
- ELO Rating System - Competitive ranking (starts at 0, can go negative)
- Leaderboard - Top 20 players with W-L records and K/D ratios
- Match Statistics - Damage dealt, accuracy, kills, deaths tracked
- Teacher Dashboard - Track student progress and quiz performance
- 100+ Math Questions - Addition, subtraction, multiplication, division
- Difficulty Levels - Easy, medium, hard questions
- Performance Tracking - Teachers can monitor quiz accuracy by topic
- Login or register
- View leaderboard (top 20 players)
- Click "Find Match" and select mode (1v1, FFA, Teams)
- Answer math questions quickly and correctly
- Better performance = earlier turn order in game
- See who's finished in real-time
- Aim: Use mouse to aim your shot
- Power: Hold SPACE to charge power (0-100%)
- Fire: Release SPACE to launch projectile
- Strategy: Account for wind, terrain, and distance
- Last worm/team standing wins
- View match statistics and rating changes
- Check updated leaderboard placement
- Deployment Guide - How to deploy to production
- Integration Testing - Test scenarios and execution
- Production Checklist - Pre-launch checklist
- User Manual - Player and teacher guides
- Database Design - Schema documentation
- API Documentation - REST and WebSocket endpoints
- Login with teacher account
- View student list and performance
- Track quiz accuracy by topic
- Monitor match history and combat stats
Teachers must be granted access by updating the database:
UPDATE users SET role = 'teacher' WHERE username = 'teacher_username';
| Component | Technology | Version |
|---|---|---|
| Game Engine | Phaser.js | 3.70.0 |
| Physics | Matter.js | (bundled with Phaser) |
| Frontend Server | http-server | 14.1.1 |
| Backend Server | Express | 4.18.0 |
| WebSocket | Socket.IO | 4.7.0 |
| Database | Supabase | 2.39.0 |
| Language | JavaScript | ES6+ |
Frontend (GitHub Pages - Free):
cd client
npm install gh-pages --save-dev
npm run deployBackend (Render.com - Free Tier):
- Connect GitHub repository to Render
- Set environment variables:
SUPABASE_URL,SUPABASE_KEY,CLIENT_URL - Deploy automatically from
mainbranch
Full deployment guide: DEPLOYMENT_GUIDE.md
POST /api/auth/register
{
"username": "player1",
"password": "password123"
}POST /api/auth/login
{
"username": "player1",
"password": "password123"
}Returns: { success: true, userId, username, rating }
GET /api/quiz/random?difficulty=easy&limit=5
Returns 5 random math questions of specified difficulty.
POST /api/matches
{
"type": "ffa",
"participants": [...],
"duration": 180
}Returns rating changes for all participants.
GET /api/leaderboard?limit=20
Returns top 20 players with stats (rank, username, matches, W-L, K/D).
GET /api/leaderboard/profile/:userId
Returns specific player's detailed stats.
Client → Server:
join_matchmaking- Join matchmaking queueleave_matchmaking- Leave queueready- Mark ready in waiting roomquiz:answer- Submit quiz answergame:action- Fire weapon (angle, power)
Server → Client:
matchmaking:matched- Match foundquiz:start- Quiz beginsgame:turn_start- Player's turn beginsgame:projectile_fired- Projectile launchedgame:damage_dealt- Damage appliedgame:match_end- Game over
- Check port 3000 is not in use:
lsof -i :3000(Mac/Linux) ornetstat -ano | findstr :3000(Windows) - Verify Node.js version:
node --version(need v16+) - Check
.envfile exists and has correct Supabase credentials
- Verify server is running:
curl http://localhost:3000/health - Check
SERVER_URLinclient/src/utils/networkManager.js - Open browser console (F12) and look for WebSocket errors
- Ensure CORS is enabled on server
- Both players must select same game mode
- Check server logs for matchmaking events
- Verify WebSocket connection established
- Try refreshing both browser tabs
- Check browser console for
game:projectile_firedevents - Verify both clients connected to same room
- Check server logs for game state updates
- Ensure both players' browsers support WebSocket
- Verify Supabase project is active (not paused)
- Check
SUPABASE_URLandSUPABASE_KEYin.env - Test connection: Run server and check logs
- Ensure schema is loaded:
SELECT * FROM users LIMIT 1;
Contributions welcome! Please follow these steps:
- Fork the repository
- Create feature branch (
git checkout -b feature/AmazingFeature) - Commit changes (
git commit -m 'Add AmazingFeature') - Push to branch (
git push origin feature/AmazingFeature) - Open Pull Request
- Use camelCase for variables
- Comment complex logic
- Test locally before submitting
- Follow existing patterns
- Power-ups (shields, double damage, healing)
- More worm characters and customization
- Replay system for matches
- Achievements and badges
- Tournament mode
- AI opponents for practice
- Map editor for custom terrains
- Voice chat integration
MIT License - See LICENSE for details
Documentation:
Contact:
- GitHub Issues: Report Bug
- Email: support@example.com
Last Updated: 2026年04月23日 | Version: 1.0.0 | Status: Production Ready