ELK GAMEVERSE
Empezar

Por qué repetimos cada partida en nuestros servidores

Una clasificación solo vale si nadie puede escribir en ella directamente. Esto es lo que cuesta y lo que aporta.

La forma obvia de construir un juego es dejar que decida el teléfono. El jugador termina, la aplicación calcula la puntuación y le cuenta al servidor lo que pasó. Es rápido, es simple, y el servidor no tiene opinión alguna.

También significa que la puntuación es lo que diga la aplicación. Y una aplicación es un programa en el ordenador de otra persona, que esa persona puede cambiar.

Qué hacemos en su lugar

Cada juego registra las jugadas que hiciste; no el resultado, las jugadas. Al terminar, esa lista viaja a nuestros servidores, y el servidor juega la misma partida desde la misma posición inicial, aplicando las mismas reglas a las mismas jugadas.

Si llega a tu resultado, la partida se acepta y cualquier recompensa se calcula desde la copia del servidor. Si no, se rechaza y no se acredita nada.

El motor es el mismo código en ambos sitios, y es determinista: con la misma semilla y las mismas jugadas debe producir el mismo tablero. Ese requisito moldea una parte sorprendente del diseño. Todo lo aleatorio debe venir de una semilla que el servidor también tenga. Todo lo que lea el reloj debe leer un tiempo en el que ambos lados coincidan. Una regla que se comporta distinto en un dispositivo rápido que en uno lento no es una regla que podamos tener.

Qué cuesta

Unos milisegundos por partida terminada y una restricción real sobre cómo se escriben los juegos. También encuentra nuestros propios fallos, lo cual es menos cómodo de lo que suena.

Un ejemplo, porque es del tipo honesto. Una cosecha se repartía recorriendo las claves de un objeto JSON. Dos copias del mismo contenido —una cargada de un archivo, otra de la base de datos— devolvían esas claves en distinto orden, y el almacén se llenaba a mitad de camino. Mismas reglas, mismas jugadas, distinto resultado. A jugadores honestos se les rechazaban partidas con un mensaje sobre un asentamiento con 590 cargas en vez de 591. Nada parecía mal en el juego; la repetición sencillamente no coincidía consigo misma.

Ese fallo era invisible para cualquier prueba unitaria, porque cada mitad pasaba por su cuenta. Hizo falta que los dos lados se alimentaran por rutas distintas para exponerlo.

Qué aporta

Una clasificación en la que nadie puede escribir directamente y una recompensa que no puede inventarse. Son la misma propiedad dicha dos veces: ganas lo que dice la repetición.

También nos permite ser concretos cuando algo falla. Una partida rechazada no es una acusación vaga: es una discrepancia en un punto conocido y, casi siempre, una conexión caída a media partida y no algo que hiciera el jugador.