Rollos de dados del lado del cliente en el juego por turnos

Me gustaría crear un juego multijugador por turnos en Android. Estoy pensando en utilizar Google Play Game Services y deshacerme de cualquier otro service web para crear y alojar juegos.

El problema es que el juego implica tiradas de dados. No creo que GPGS ofrezca la posibilidad de tiradas de dados de terceros, así que mi primer pensamiento fue integrarlos en la aplicación, sin embargo, esto brinda una gran oportunidad para hacer trampa.

He leído las respuestas dadas en esta pregunta: repartir los dados en la networking sin terceros de confianza , pero requieren que todos los jugadores participen en la tirada, lo que no es posible si no todos están en la aplicación al mismo time. .

¿Hay alguna solución alternativa? ¿O tengo que usar un tercero para esto?

No estoy familiarizado con los services de juegos de Google Play, sin embargo, podría valer la pena analizar cómo los juegos de console antiguos tenían aleatoriedad. A menudo, se tomaron semillas de numbers aleatorios de estados ocultos pero no aleatorios dentro del juego y luego los numbers salen de una list oculta o calculadora.

  • ¿Qué marco del menu de inicio del juego 'inicio' fue golpeado.
  • Qué enemigos fueron asesinados en la sala anterior.
  • ¿Qué marco de animation era el objective de un ataque?
  • Las coorderadas X * Y del jugador o enemigos.

Si bien estos trucos no se aplican directamente a su caso, todavía puede aprender del pasado aquí.

Una opción podría ser generar un valor inicial que todos los jugadores conozcan desde el inicio del juego. Este valor inicial determina el punto de partida en una list conocida o representa el primer valor en un método conocido para generar numbers pseudoaleatorios. Como todos los jugadores saben cuál es el valor inicial y cuántos numbers aleatorios se han seleccionado para las acciones seguras, todos saben exactamente cuál será el próximo valor.

Otra podría consistir en codificar toda la información relevante específica sobre el estado del juego para crear una key (más una key del juego para garantizar que cada juego sea único) que pueda usarse para generar un número pseudoaleatorio en ambos extremos que esté garantizado como el mismo número dado el mismo estado del juego. Los numbers serán diferentes solo si los juegos no son exactamente iguales en ambos lados.

Existe un concepto llamado " networking sincrónica ", lo que significa que todas las acciones en el juego son deterministas y, por lo tanto, devolverán el mismo resultado en todos los dispositivos. Si eso es un hecho, entonces simplemente ejecuta todas las acciones en todos los dispositivos en el mismo order y terminará en el mismo estado.

onMovePlayerLeft(player): player.X += 1 

Ahora, en lugar de enviar el resultado de onMovePlayerLeft, solo envía el hecho de que se ejecutó "onMovePlayerLeft". Al recibir el post, puede ejecutar exactamente el mismo código y ambos juegos están en el mismo estado nuevamente.

Casi todos los cálculos son deterministas, siempre y cuando no dependan del hardware o el sistema operativo. (Desafortunadamente, tendrá que evitar el uso de flotadores ya que diferentes CPU implementan flotadores de forma diferente).


Pero Bestia, ¿cómo ayuda eso? ¡Una tirada de dados no es determinista!

No, eso está mal. Los numbers aleatorios tal como los usamos en los juegos no son en realidad aleatorios, son pseudoaleatorios. Si el estado del RNG es el mismo, el resultado también será el mismo.

Entonces, si su juego es sincrónico, solo necesita asegurarse de que ambos clientes utilicen exactamente la misma semilla al inicio de la session.


Edit: ¡ Pero Bestia, no quiero que el jugador sepa el resultado del lanzamiento antes de la mano!

En ese caso, tendrá que negociar un secreto cada vez que quiera realizar un lanzamiento.

Esto podría verse así.

Peer A : Quiero lanzar un dado para Acción y necesito una Semilla RNG para eso.
Peer A : La sum de control de mi parte de la semilla será 459023.
Peer B : La sum de comprobación de mi parte de la semilla será 390564.
Peer A : Mi parte de la semilla es 38000.
Peer B : Mi parte de la semilla es 76000.

La sum de comprobación es necesaria para hacer cumplir que la semilla se genera antes de que el par haya recibido la otra semilla.

Ahora puede generar el valor real de la semilla negociada haciendo algunos cálculos simples, como (38000 + 76000) / 2.