Añadir multijugador a tu juego HTML5 con WebSockets y Node.js

Transforma cualquier juego HTML5 de un jugador en multijugador online con Cerewro: un servidor Node.js con Socket.io sincroniza el estado del juego en tiempo real entre todos los clientes conectados.

Arquitectura de un juego multijugador

ComponenteTecnologíaRol
ClienteHTML5 Canvas + Socket.io-clientRenderiza el juego, envía inputs
ServidorNode.js + Socket.ioAutoridad del estado, sincroniza
ProtocoloWebSocket (a través de Socket.io)Comunicación bidireccional en tiempo real

Prompt para añadir multijugador

Cerewro Chat
Añade modo multijugador online al juego Snake que ya tenemos. Necesito:
- Servidor Node.js + Socket.io en puerto 3001
- Sala de espera con código para invitar a amigos
- Hasta 4 jugadores simultáneos, cada uno con color diferente
- Sincronización de estado a 20 ticks por segundo
- Cuando una serpiente choca, se elimina (el resto sigue)
- Ganador: el último en sobrevivir
- Chat en tiempo real con Bootstrap
- Reconexión automática si se pierde la conexión

Servidor Node.js con Socket.io

server.js — Lógica del servidor
const express = require('express');
const http    = require('http');
const { Server } = require('socket.io');

const app    = express();
const server = http.createServer(app);
const io     = new Server(server, { cors: { origin: '*' } });

const rooms = {};    // { roomCode: { players, gameState, interval } }
const TICK  = 1000 / 20;  // 20 ticks/segundo

io.on('connection', socket => {
  console.log(`Conectado: ${socket.id}`);

  socket.on('createRoom', () => {
    const code = Math.random().toString(36).substr(2, 6).toUpperCase();
    rooms[code] = { players: {}, gameState: null, interval: null };
    socket.join(code);
    rooms[code].players[socket.id] = { id: socket.id, color: getColor(0), score: 0 };
    socket.emit('roomCreated', { code, playerId: socket.id });
  });

  socket.on('joinRoom', ({ code }) => {
    if (!rooms[code]) return socket.emit('error', 'Sala no encontrada');
    const nPlayers = Object.keys(rooms[code].players).length;
    if (nPlayers >= 4) return socket.emit('error', 'Sala llena');

    socket.join(code);
    rooms[code].players[socket.id] = { id: socket.id, color: getColor(nPlayers), score: 0 };
    io.to(code).emit('playerJoined', rooms[code].players);
  });

  socket.on('startGame', ({ code }) => {
    initGameState(code);
    rooms[code].interval = setInterval(() => {
      updateGameState(code);
      io.to(code).emit('gameState', rooms[code].gameState);
    }, TICK);
  });

  socket.on('direction', ({ code, dir }) => {
    if (rooms[code]?.gameState?.snakes?.[socket.id]) {
      rooms[code].gameState.snakes[socket.id].nextDir = dir;
    }
  });

  socket.on('disconnect', () => {
    // Limpiar sala si se vacía
    for (const [code, room] of Object.entries(rooms)) {
      delete room.players[socket.id];
      if (Object.keys(room.players).length === 0) {
        clearInterval(room.interval);
        delete rooms[code];
      }
    }
  });
});

server.listen(3001, () => console.log('Servidor en http://localhost:3001'));

const COLORS = ['#00ff64','#ff6b6b','#4ecdc4','#ffd93d'];
function getColor(i) { return COLORS[i % COLORS.length]; }
Cliente — Conectar al servidor

Desplegar en Railway o Render: El servidor Node.js necesita estar en un servidor real para que otros puedan conectarse. Railway y Render ofrecen planes gratuitos para proyectos pequeños. Pide a Cerewro: "Despliega el servidor del juego en Railway con los pasos exactos".