Skip to content
S
ES/EN
← Volver a todos los proyectos
20262 min de lecturaDesarrollador

Pictobattle

Un juego multijugador de Pictionary en tiempo real con dibujo en canvas, adivinanzas en vivo y escalado horizontal — construido como monorepo con pnpm.

Gradiente rosa que sugiere un lienzo de dibujo creativo

Problema

Un juego de adivinar un dibujo por turnos (tipo pictionary) suena sencillo, pero lo más difícil no es dibujar en pantalla, sino mantener a cada jugador sincronizado en tiempo real. Los trazos, las respuestas, los puntos y el estado del turno deben mantenerse consistentes entre clientes, y una sola conexión que se cae puede romper el juego si los estados solo existen en memoria.

Solución

  • Estructuré el proyecto como un monorepo con pnpm y tres paquetes: un frontend en React, un backend en Node.js/Express y un paquete de tipos compartidos. Esto mantuvo el contrato de la API entre cliente y servidor sincronizado sin realizar una sincronizacion manual, se genera un tipo una sola vez, y ambos frontend y serber lo toman.
  • Elegí utilizar websockers con Socket.io para la capa de tiempo real. Cada sala de juego corre como un game loop basado en eventos donde los trazos, las respuestas y los puntos fluyen por el mismo canal. El timer por turno y la estructura de rondas se fuerzan del lado del servidor, así que los clientes no pueden desincronizarse.
  • El lienzo de dibujo utilaza Canvas de HTML5 con un batching ligero de eventos. Cada trazo se transmite a los demás jugadores como una secuencia de coordenadas, no como una imagen completa, esto mantiene una latencia baja y el ancho de banda mínimo incluso con varios usuarios jugando a la vez.
  • Añadí una estrategia de reconexión: cuando un jugador se cae por x motivo o recarga la pagina, el servidor repite el estado actual del juego para que se reincorpore a mitad de la ronda sin perder contexto. Nadie queda fuera por una conexión inestable.
  • Agregué Redis Pub/Sub para escalado horizontal lo cual permite que los eventos de sala se distribuyen entre instancias, así que el juego puede ejecutarse más allá de un único proceso cuando lo necesita.

Resultado

  • Multijugador fluido sin lag perceptible en trazos o respuestas, incluso con la sala llena.
  • El patrón de monorepo hizo mucho mas simple el manejar las dependencias entre cliente y servidor a integrar los tipos definidos desde un solo lugar.
  • Tanto el cliente como el servidor se encuentran disponibles como containers de Docker para un deploy mas simple y prolijo

Contacto

Trabajemos juntos

¿Tienes un proyecto en mente? Escríbeme y te responderé pronto.