A real-time multiplayer hexagon-based strategy game built with modern web technologies.
Live at: https://romgon.net
ROMGON is a turn-based multiplayer strategy game played on a hexagonal board. Players compete by placing pieces and capturing opponent pieces through strategic positioning. The game features real-time multiplayer using WebSocket, ELO rating system, and persistent player statistics.
- Hexagon Board: 8×8 hexagonal grid using axial coordinates
- Turn-Based: White moves first, then alternates
- Piece Capture: Pieces surrounded by 3+ opponent pieces are automatically captured
- Win Conditions:
- Capture 3+ opponent pieces to win
- 100 moves with no captures = Draw
- Rating System: ELO-based ranking with 7 tiers
- ✅ Real-time multiplayer with WebSocket
- ✅ Interactive hexagon board with canvas rendering
- ✅ Automatic piece capture detection
- ✅ Turn management and game state sync
- ✅ Win/Draw detection
- ✅ Move history tracking
- ✅ User registration and authentication (JWT)
- ✅ Player profiles with statistics
- ✅ ELO rating system (7 tiers)
- ✅ Leaderboard rankings
- ✅ Game history
- ✅ Win rate tracking
- ✅ Responsive design (mobile, tablet, desktop)
- ✅ Dark mode UI
- ✅ Auto-save game progress
- ✅ Persistent database
- ✅ Auto-deploy on git push (Vercel + Railway)
- ✅ Real-time notifications
- Node.js 18+ or 22+
- npm or yarn
- Git
cd backend
npm install
npm start
# Server runs on http://localhost:3000
cd frontend
# Serve with Python
python -m http.server 8000
# Or use any local server
# Access at http://localhost:8000
# Terminal 1: Start backend
cd backend && npm start
# Terminal 2: Start frontend
cd frontend && python -m http.server 8000
# Open in two browser windows:
# Window 1: http://localhost:8000 (Player 1)
# Window 2: http://localhost:8000 (Player 2, incognito)
# Deployed at: https://romgon-api.up.railway.app
# Auto-deploys on git push to main branch
# Deployed at: https://romgon.net (via Cloudflare)
# Auto-deploys on git push to main branch
┌─────────────────────────────────────────────────────┐
│ User Browser │
└──────────────────────┬────────────────────────────────┘
│
┌──────────────┴──────────────┐
│ │
HTTP REST API WebSocket
(JSON) (Socket.io)
│ │
├──────────────┬──────────────┤
│ │ │
┌────▼──────────────▼─────────────▼────┐
│ Express.js Backend (Railway) │
│ ─────────────────────────────────── │
│ • 24 REST API endpoints │
│ • Socket.io real-time server │
│ • Game engine processing │
│ • ELO rating calculations │
└────┬──────────────────────────────────┘
│
│ Read/Write
│
┌────▼──────────────────────────────────┐
│ SQLite Database │
│ ─────────────────────────────────── │
│ • Users (authentication, stats) │
│ • Games (match records) │
│ • Ratings (ELO history) │
│ • Achievements │
│ • Friends list │
└───────────────────────────────────────┘
index.html
│
├── src/css/style.css (responsive styling)
│
├── src/api/
│ ├── client.js (REST API wrapper)
│ └── websocket.js (Socket.io client)
│
├── src/js/
│ ├── error-handler.js (global error handling)
│ ├── state.js (state management)
│ ├── ui.js (UI components & pages)
│ ├── app.js (app initialization)
│ ├── game-engine.js (game logic)
│ ├── board-renderer.js (canvas rendering)
│ ├── multiplayer-manager.js (game sync)
│ └── game-integration.js (UI-to-game bridge)
backend/
│
├── server.js (Express app, Socket.io setup)
│
├── config/
│ ├── database.js (SQLite initialization)
│ └── romgon.db (SQLite database file)
│
├── routes/
│ ├── auth.js (login, register, JWT)
│ ├── users.js (profile, stats)
│ ├── games.js (game creation, moves)
│ ├── ratings.js (leaderboard, ELO)
│ └── stats.js (statistics, achievements)
│
├── utils/
│ ├── auth.js (JWT, bcrypt)
│ └── rating.js (ELO calculations)
│
└── websocket/
└── gameSocket.js (Socket.io event handlers)
- HTML5 - Semantic markup
- CSS3 - Responsive design with CSS variables
- Vanilla JavaScript - No frameworks (lightweight)
- Canvas API - Board rendering
- Socket.io Client - Real-time communication
- LocalStorage - Token persistence
- Node.js - Runtime
- Express.js - REST API framework
- Socket.io - Real-time WebSocket server
- SQLite3 - Database
- bcryptjs - Password hashing
- jsonwebtoken - JWT authentication
- Helmet - Security headers
- Vercel - Frontend hosting (auto-deploy)
- Railway - Backend hosting (auto-deploy)
- Cloudflare - DNS & CDN
- GitHub - Version control & CI/CD
POST /api/auth/register
Content-Type: application/json
{
"username": "player1",
"email": "player@example.com",
"password": "securepassword"
}
Response: 201 Created
{
"user": { "id": 1, "username": "player1", ... },
"token": "eyJhbGc..."
}
POST /api/auth/login
Content-Type: application/json
{
"username": "player1",
"password": "securepassword"
}
Response: 200 OK
{
"user": { "id": 1, "username": "player1", ... },
"token": "eyJhbGc..."
}
POST /api/games/create
Authorization: Bearer {token}
Content-Type: application/json
{
"opponentId": 2,
"color": "white"
}
Response: 201 Created
{
"gameId": "game-123",
"status": "waiting"
}
POST /api/games/{gameId}/move
Authorization: Bearer {token}
Content-Type: application/json
{
"move": { "q": 0, "r": 0 },
"boardState": [...]
}
Response: 200 OK
{
"success": true,
"boardState": [...]
}
GET /api/ratings/leaderboard?limit=10&offset=0
Authorization: Bearer {token}
Response: 200 OK
{
"players": [
{
"rank": 1,
"username": "champion",
"rating": 2000,
"tier": "Gold",
"wins": 50,
"losses": 10
},
...
]
}
socket.emit('userConnected', userId);
socket.emit('gameMove', {
gameId: 'game-123',
move: { q: 0, r: 0, color: 'white' },
boardState: [...],
gameState: {...}
});
socket.on('gameMove', (data) => {
// Handle opponent's move
});
socket.on('gameEnded', (data) => {
console.log('Winner:', data.winner);
console.log('Reason:', data.reason);
});
Automatic Deployment:
- Every
git push
tomain
triggers auto-deploy - Deployment typically completes in 1-2 minutes
- Access at: https://romgon.net (via Cloudflare)
Manual Deployment:
vercel --prod
Automatic Deployment:
- Every
git push
tomain
triggers auto-deploy - Deployment includes npm install and start
- Access at: https://romgon-api.up.railway.app
Environment Variables:
PORT=3000
NODE_ENV=production
JWT_SECRET=your-secret-key-here
ALLOWED_ORIGINS=https://romgon.net,https://www.romgon.net
SQLite Persistent Storage:
- Database file stored on Railway
- Persists across deployments
- Tables auto-created on first run
- 7 tables: users, games, ratings, messages, achievements, friends, rating_changes
- ✅ JWT tokens (7-day expiration)
- ✅ bcryptjs password hashing
- ✅ CORS protection
- ✅ Helmet security headers
- ✅ HTTPS/TLS encryption
- ✅ SQL injection prevention (parameterized queries)
- ✅ XSS protection
- ✅ CSRF tokens
- ✅ API request rate limiting
- ✅ WebSocket connection limits
- ✅ DDoS protection (via Cloudflare)
Axial Coordinate System:
(-1,1) (0,1) (1,1)
\ | /
(-2,0)─────(0,0)─────(2,0)
/ | \
(-1,-1)(0,-1)(1,-1)
Valid Moves:
- First move must be at center (0,0)
- Subsequent moves must be adjacent to existing pieces
- Cannot place on occupied hexagon
Piece Capture Rules:
- A piece is captured when surrounded by 3+ opponent pieces
- Captures happen automatically after each move
- Multiple pieces can be captured in one move
Win Conditions:
- Victory: First player to capture 3+ opponent pieces
- Draw: 100 moves with no captures
- Resignation: Opponent resigns
ELO Calculation:
K-factor = 32 (standard)
Initial rating = 1600
Updated rating = Old rating + K × (Result - Expected)
Tiers (based on rating):
• Gold (👑): 2000+
• Pink (🏆): 1800-1999
• Red (⭐): 1600-1799
• Orange (🥇): 1400-1599
• Cyan (🥈): 1200-1399
• Green (🥉): 1000-1199
• Blue (🎯): <1000
Problem: Can't connect to WebSocket
- Check backend is running:
https://romgon-api.up.railway.app/api/health
- Check browser console for errors
- Try hard-refresh: Ctrl+Shift+R
Problem: Opponent doesn't see your moves
- Check WebSocket connection in DevTools
- Verify game ID matches both players
- Restart game if connection drops
Problem: Login fails or token invalid
- Clear localStorage:
localStorage.clear()
- Hard refresh browser
- Check backend is responding to auth requests
Problem: Game board appears blank
- Check canvas is visible in DevTools
- Verify boardSize configuration
- Clear browser cache and restart
- Core game engine
- Hexagon board rendering
- Real-time multiplayer
- User authentication
- ELO rating system
- Leaderboard
- Database persistence
- Auto-deployment
- Game chat system
- Friend system
- Achievement system
- Game replays
- Spectator mode
- Mobile app (React Native)
- AI opponent (minimax algorithm)
- Tournament mode
- Streaming integration
- Analytics dashboard
-
Clone repository:
git clone https://github.com/romgon-coder/Romgon.git cd Romgon
-
Create feature branch:
git checkout -b feature/your-feature
-
Make changes and test:
# Test locally cd backend && npm start # Terminal 1 cd frontend && python -m http.server 8000 # Terminal 2
-
Commit with descriptive messages:
git commit -m "feat: Add your feature description" git push origin feature/your-feature
-
Create Pull Request on GitHub
- JavaScript: Use modern ES6+ syntax
- Comments: Add JSDoc for functions
- Naming: camelCase for variables, PascalCase for classes
- Formatting: 2-space indentation
MIT License - See LICENSE file for details
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Contact: romgon-coder@example.com
Built with modern web technologies for fast, scalable multiplayer gaming.
Made with 💚 by ROMGON Team
Last Updated: October 2025