Antes de tener un juego multijugador necesitas dos programas que puedan hablar entre sí de forma confiable. Hoy aprendemos el lenguaje común de toda red: los sockets.
En la lección anterior nuestros enemigos ya "pensaban" localmente, dentro de un único proceso. Un juego multijugador rompe esa suposición: ahora hay dos (o más) programas corriendo, posiblemente en computadoras distintas, que necesitan compartir el mismo estado del mundo. La pieza fundamental que permite esto es el socket: un punto de conexión que permite enviar y recibir datos por red, identificado por una dirección IP y un puerto.
Vamos a trabajar con sockets Berkeley (BSD sockets), el estándar POSIX que usan Linux y macOS de forma nativa. En Windows, la API se llama WinSock y es casi idéntica en su uso — la diferencia principal es la inicialización con `WSAStartup` y que hay que enlazar la librería `ws2_32`.
TCP garantiza entrega ordenada y confiable de datos, pero tiene más latencia. UDP es más rápido pero no garantiza que los paquetes lleguen, ni en qué orden. Para esta lección y la siguiente vamos a usar TCP porque es más simple de razonar mientras aprendes los fundamentos; en un juego de acción en tiempo real con muchos jugadores, la industria suele preferir UDP con su propia capa de confiabilidad, pero eso queda fuera del alcance de un curso introductorio.
Un servidor TCP sigue siempre la misma secuencia: crear el socket, asociarlo a una dirección y puerto (`bind`), ponerlo a escuchar conexiones (`listen`), y aceptar clientes (`accept`).
`htons` convierte el número de puerto al orden de bytes de red (big-endian), independientemente de si tu computadora usa little-endian o big-endian internamente. Este detalle — que existe precisamente porque distintas arquitecturas de CPU representan números de forma diferente — es un ejemplo perfecto de algo que vale la pena pedirle a tu asistente de IA que te explique con un diagrama de bytes si no te queda claro de inmediato.
El cliente es más simple: crea el socket y se conecta directamente a una dirección y puerto conocidos con `connect`.
Deberías ver "Cliente conectado!" y el mensaje intercambiado en ambas terminales. Esto, aunque parezca poco, es la base completa de todo juego multijugador: dos programas independientes, comunicándose por red con un protocolo que tú defines.
Un error muy común de principiante es asumir que un `recv()` recibe exactamente lo que un `send()` envió del otro lado. TCP es un flujo de bytes continuo (un "stream"), no un sistema de mensajes discretos — puede fragmentar un mensaje grande en varias llamadas a `recv()`, o juntar varios mensajes pequeños en una sola. Para un protocolo de juego real necesitas definir tu propio "framing" (por ejemplo, enviar primero el tamaño del mensaje en 4 bytes, y luego el contenido). Vamos a resolver esto formalmente en la próxima lección, donde ya no solo intercambiamos un mensaje de saludo, sino el estado continuo de un juego multijugador real.
En la próxima lección tomamos exactamente estos sockets y construimos un juego multijugador funcional, sincronizando la posición de los jugadores entre cliente y servidor en tiempo real.
Carlos Montiel es arquitecto de soluciones IA empresarial. Implementa LLMs, Agentes, RAG y orquestadores en empresas de Guatemala y Latinoamérica. Contáctalo para una consultoría.
Contactar a Carlos Montiel