Commit Graph

15 Commits

Author SHA1 Message Date
jozamudi 1b11a60acc Remove client-side game over check to prevent premature game end
The client was checking activePlayers.length <= 1 and calling endGame()
prematurely, before the server's authoritative game-over event.

Now the client only ends the game when the server explicitly sends the
'game-over' event.

Added server-side logging to track active player count and winner.
2026-03-21 03:13:08 +00:00
jozamudi e3f594e44e Show garbage received on player elimination
- Add garbageReceived array to player objects
- Track garbage in addGarbageToPlayer() with sender name
- Include garbageReceived in getStates() output
- Update endGame() to pass garbage stats to UI
- Update showGameOver() to display garbage count per player
- Add CSS styling for eliminated players and garbage column
- Bump CSS version for cache refresh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 02:44:39 +00:00
jozamudi a1cbd27a71 Add server logging for eliminations and garbage transfers
- Log elimination reason: board full, garbage collision, garbage overflow, disconnect
- Log garbage transfers: who cleared rows, how many, and recipients
- Log when no opponents available to send garbage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 01:49:52 +00:00
jozamudi 372a340024 Fix initial pieces to use shared queue in startGame
All players now receive the same first two pieces from the shared
piece queue, with sequence index starting at 2.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 01:41:13 +00:00
jozamudi 634c6e8eab Implement shared 7-bag piece sequence
- Add generatePieceBag() and createPieceQueue() for 7-bag system
- Add pieceQueue and playerSequenceIndex to lobby state
- Modify spawnPiece() to consume from shared queue per player
- Update player-hold handler to manage sequence index on hold
- Add sequenceIndex to state updates for tracking
- Update client loadState() to receive sequenceIndex

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 01:37:55 +00:00
jozamudi bdeb6c8849 Fix garbage elimination bug and align board with header
- Change y-- instead of y++ when pushing piece up on garbage
- Add y < 0 check to properly detect piece pushed off top
- Remove margin-top from battle grid to align with header

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 01:07:21 +00:00
jozamudi 27b0adcc90 Fix garbage row visibility by pushing current piece up
When garbage rows are added to a player's board, the current falling
piece was not being adjusted, causing it to appear stuck while the
board shifted. This fix increments the piece's Y position when garbage
is received and eliminates the player if the piece is pushed above
the visible board.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 21:35:51 +00:00
jozamudi 6f24cfad30 Add unready toggle in lobby
- Server: Handle unready event to set player ready state to false
- Client: Ready button toggles between READY and UNREADY
- Client: Unready sends unready socket event to server

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 18:38:33 +00:00
jozamudi a0ab4ff5cd Add spectator mode for late-joining players
- Server: Late joiners are added as spectators instead of players
- Server: Send forced-spectator event only to joining spectator (not broadcast)
- Server: Track spectators separately and move them to players after game ends
- Client: Handle forced-spectator event to show all player boards
- Client: Spectators see all boards equally without main/spectator highlighting
- Client: Mobile view shows scrollable vertical list of all boards for spectators
- Fix: All cleared lines are sent as garbage to each opponent (not randomized)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 18:26:48 +00:00
jozamudi 164ed790ed Add ghost piece preview showing where block will land
- Add getGhostY() method to TetrisGame class (game.js)
- Add ghostY to getState() output
- Add getGhostY() helper to server (server/index.js)
- Include ghostY in getStates() broadcast
- Add drawGhostPiece() and drawGhostCell() methods (renderer.js)
- Ghost renders as semi-transparent outline at landing position
2026-03-20 09:37:41 -07:00
jozamudi 4a49c76cdc Add hold piece feature
- Added holdPiece and canHold state to TetrisGame class
- Implemented hold() method to swap current piece with held piece
- Added player-hold socket event on server
- Added HOLD preview canvas showing held piece (grayed when unavailable)
- Added C key keyboard shortcut and touch button for hold
- Fixed canHold reset on piece spawn for proper swap functionality

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 08:50:52 -07:00
jozamudi f9cafe630c Fix game over condition and garbage row placement
- Remove premature elimination in addGarbageToPlayer (top rows check)
- Remove redundant y < 0 elimination check in lockPiece
- Players are only eliminated when spawnPiece fails (board full)
- Garbage rows now added to bottom of board, pushing blocks up
2026-03-20 07:53:08 -07:00
jozamudi 833256d18f Fix lobby: only show players who have joined
Changes:
- Added socket.join(LOBBY_ROOM) when player joins lobby
- Changed io.emit() to io.to(LOBBY_ROOM).emit() for all lobby events
- Players only see lobby events after they click JOIN LOBBY
- Fixed player list to update correctly when players join/ready
- Game now starts properly when all players are ready

Files modified:
- server/index.js: Use Socket.io rooms for lobby scoping
- public/js/app.js: Show lobby screen on player-joined event
- public/js/ui.js: Removed duplicate listener override
2026-03-20 07:30:42 -07:00
jozamudi e7917a338e Refactor to single global lobby
Changes:
- Removed room-based architecture, now using single global lobby
- Players only need to enter their name to join
- Game starts when all players in lobby are ready (min 2, max 8)
- Simplified UI - no room name field, shows "Global Lobby" header
- Updated all server events to use io.emit instead of io.to(roomName)

Files modified:
- server/index.js: Replaced rooms Map with single lobby object
- public/index.html: Removed room name input, updated button text
- public/js/network.js: Renamed joinRoom/leaveRoom to joinLobby/leaveLobby
- public/js/ui.js: Simplified join flow, removed room name validation
- public/js/app.js: Updated game header to show "GLOBAL LOBBY"
- PLAN.md: Marked all phases as complete
2026-03-20 07:09:51 -07:00
jozamudi 5da6033704 Initial commit: Tetris Battle Royale multiplayer game
Features:
- 2-8 player multiplayer via Socket.io WebSocket
- Real-time board synchronization - all players see all boards
- Battle royale mechanic: clearing rows sends garbage to opponents
- Classic Tetris gameplay with all 7 tetrominoes
- Retro visual styling with CRT scanlines and pixel font
- Automatic level progression and speed increase
- Player elimination and winner announcement

Files:
- server/index.js: Node.js + Socket.io game server
- public/js/: Frontend game logic, rendering, network, and UI
- public/css/style.css: Retro Tetris styling
- README.md: Setup and usage instructions
- PLAN.md: Implementation plan with all phases completed
2026-03-20 00:34:06 -07:00