Add performance improvements documentation and game-logic enhancements
- Add IMPROVEMENTS.md with detailed analysis of performance issues and bugs - Update CLAUDE.md with negative Y overflow explanation - Update README.md with socket events documentation - Enhance game-logic.js with improved comments and validation - Improve server/index.js with better documentation and edge case handling
This commit is contained in:
+67
-3
@@ -1,3 +1,12 @@
|
||||
/**
|
||||
* Tetris Battle Royale Server
|
||||
*
|
||||
* Express + Socket.io server that handles all game logic authoritatively.
|
||||
* Manages a single global lobby with 2-8 players competing in real-time.
|
||||
*
|
||||
* @module server
|
||||
*/
|
||||
|
||||
const express = require('express');
|
||||
const http = require('http');
|
||||
const { Server } = require('socket.io');
|
||||
@@ -29,7 +38,42 @@ const io = new Server(server);
|
||||
// Serve static files
|
||||
app.use(express.static(path.join(__dirname, '../public')));
|
||||
|
||||
// Single global lobby
|
||||
/**
|
||||
* @typedef {Object} Player
|
||||
* @property {string} id - Socket.io connection ID
|
||||
* @property {string} name - Player's display name
|
||||
* @property {number} score - Current score
|
||||
* @property {number} lines - Total lines cleared
|
||||
* @property {number} level - Current level (affects drop speed)
|
||||
* @property {number[][]} board - 20x10 game board
|
||||
* @property {object|null} currentPiece - Currently falling piece
|
||||
* @property {object|null} nextPiece - Next piece to spawn
|
||||
* @property {object|null} holdPiece - Held piece (for hold mechanic)
|
||||
* @property {boolean} canHold - Whether hold is available this turn
|
||||
* @property {boolean} eliminated - Whether player has been eliminated
|
||||
* @property {boolean} ready - Whether player is ready to start
|
||||
* @property {number} dropCounter - Frame counter for auto-drop
|
||||
* @property {number} dropInterval - Milliseconds between auto-drops
|
||||
* @property {object[]} garbageReceived - History of garbage received
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Spectator
|
||||
* @property {string} id - Socket.io connection ID
|
||||
* @property {string} name - Spectator's display name
|
||||
*/
|
||||
|
||||
/**
|
||||
* Global lobby state - holds all game state server-side
|
||||
*
|
||||
* @type {Object}
|
||||
* @property {Map<string, Player>} players - Active players (socketId -> Player)
|
||||
* @property {Map<string, Spectator>} spectators - Spectators (socketId -> Spectator)
|
||||
* @property {boolean} gameStarted - Whether game is currently running
|
||||
* @property {NodeJS.Timeout|null} gameInterval - setInterval reference for game tick
|
||||
* @property {string[]} pieceQueue - Shared piece queue (7-bag system)
|
||||
* @property {Map<string, number>} playerSequenceIndex - Each player's position in piece queue
|
||||
*/
|
||||
const lobby = {
|
||||
players: new Map(),
|
||||
spectators: new Map(),
|
||||
@@ -45,7 +89,12 @@ const LOBBY_ROOM = 'global-lobby';
|
||||
io.on('connection', (socket) => {
|
||||
console.log('Player connected:', socket.id);
|
||||
|
||||
// Join global lobby
|
||||
/**
|
||||
* Handle player joining the lobby
|
||||
* @event join-lobby
|
||||
* @param {object} data - Event data
|
||||
* @param {string} data.playerName - Name of the player joining
|
||||
*/
|
||||
socket.on('join-lobby', ({ playerName }) => {
|
||||
// Add socket to lobby room so they receive lobby events
|
||||
socket.join(LOBBY_ROOM);
|
||||
@@ -103,6 +152,10 @@ io.on('connection', (socket) => {
|
||||
console.log(`${playerName} joined global lobby (${lobby.players.size} players)`);
|
||||
});
|
||||
|
||||
/**
|
||||
* Handle player marking themselves as ready
|
||||
* @event ready
|
||||
*/
|
||||
socket.on('ready', () => {
|
||||
const player = lobby.players.get(socket.id);
|
||||
if (!player) return;
|
||||
@@ -124,6 +177,10 @@ io.on('connection', (socket) => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Handle player marking themselves as not ready
|
||||
* @event unready
|
||||
*/
|
||||
socket.on('unready', () => {
|
||||
const player = lobby.players.get(socket.id);
|
||||
if (!player) return;
|
||||
@@ -137,6 +194,13 @@ io.on('connection', (socket) => {
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Handle player moving piece left or right
|
||||
* @event player-move
|
||||
* @param {object} data - Event data
|
||||
* @param {string} data.playerId - ID of the player
|
||||
* @param {'left'|'right'} data.direction - Direction to move
|
||||
*/
|
||||
socket.on('player-move', ({ playerId, direction }) => {
|
||||
if (!lobby.gameStarted) return;
|
||||
|
||||
@@ -590,4 +654,4 @@ function checkGameOver() {
|
||||
server.listen(PORT, () => {
|
||||
console.log(`Tetris Battle Royale server running on port ${PORT}`);
|
||||
console.log(`Open http://localhost:${PORT} in 2-8 browser tabs to play!`);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user