Mafia on Go, Vanila JS y WebSocket'ah



Se tratará de la implementación web del popular juego de cartas " Mafia ". Fue escrito por diversión y experiencia en el desarrollo de juegos. La primera versión fue escrita en dos semanas de tiempo libre del trabajo y al mismo tiempo fue reescrita a la segunda versión. La ventaja de este juego es la ausencia de un host.

Basado en los objetivos de desarrollo, decidí la implementación / no implementación de características.
Qué es exactamente lo que hay que hacer:

  • Juego mínimo que repite las reglas del juego clásico.
  • Voz de comandos del líder en dispositivos cliente
  • Continuación del juego incluso después de reiniciar la pestaña del navegador

Lo que no fue planeado o podría posponerse:

  • Registro de juego
  • Interfaz de administración
  • Almacenamiento permanente de datos del juego en una base de datos.
  • Sincronización horaria entre dispositivos.

Backend


https://github.com/mrsuh/mafia-backend
Escrito en Go. Almacena el estado del juego y es responsable de su lógica.

Durante el juego, puedes contactar al servidor para obtener la información completa:

curl 'http://127.0.0.1:8000/info?game=23' | python -m json.tool 

Pantalla de información del juego
{
"event": "greet_mafia",
"event_status": 2,
"id": 23,
"is_over": false,
"iter": 1,
"players": [
{
"addr": "172.18.0.1:51438",
"createdAt": "2018-09-23T14:39:29.631475779Z",
"id": 33309,
"name": "Anton",
"role": 4
},
{
"addr": "172.18.0.1:51440",
"createdAt": "2018-09-23T14:39:32.867080927Z",
"id": 5457,
"name": "username:0",
"role": 2
},
{
"addr": "172.18.0.1:51442",
"createdAt": "2018-09-23T14:39:32.882463945Z",
"id": 14214,
"name": "username:2",
"role": 1
},
{
"addr": "172.18.0.1:51444",
"createdAt": "2018-09-23T14:39:32.895209072Z",
"id": 63759,
"name": "username:1",
"role": 3
}
],
"win": 0
}


O averigüe el estado del servidor:

 curl 'http://127.0.0.1:8000/health' | python -m json.tool 

Mostrar información del estado del servidor
{
"runtime.MemStats.Alloc": 764752,
"runtime.MemStats.NumGC": 0,
"runtime.MemStats.Sys": 4165632,
"runtime.MemStats.TotalAlloc": 764752,
"runtime.NumGoroutine": 14
}


Para determinar si el jugador aún está activo, el backend envía un latido. Si un jugador no responde después de un cierto intervalo, entonces es eliminado del juego. Al mismo tiempo, si un jugador se vuelve a conectar antes del final del intervalo (la red ha desaparecido), puede continuar el juego.

Para una operación estable, el backend estaba cubierto por pruebas unitarias con la biblioteca Go estándar, donde se verifican los escenarios de operación principales.

 go test mafia-backend/src -cover ok mafia-backend/src 1.315s coverage: 70.7% of statements 

Frontend


https://github.com/mrsuh/mafia-frontend
Está escrito en JS puro y construido con Grunt .
No lleva ninguna lógica.

Cuando ocurre un evento con el back-end, muestra la página deseada, muestra los datos que se le enviaron y reproduce el sonido del nuevo evento.

Frontend almacena el juego y los identificadores de jugador en LocalStorage o en la cadena de consulta del navegador (si necesita ejecutar varias pestañas en un navegador para diferentes jugadores). La completa falta de lógica, así como el almacenamiento de los parámetros básicos del juego lo hacen posible incluso después de volver a cargar la página para restaurar el estado del juego.

El navegador prohíbe la reproducción automática de sonidos sin intervención del usuario (por ejemplo, presionar un botón). Para reproducir sonidos para cada evento que viene con el backend, solo se creó 1 objeto de audio JavaScript. Cada jugador debe presionar un botón para iniciar el juego y en ese momento el objeto Audio se activa (disponible para reproducción), y luego puede cambiar el parámetro src para reproducir diferentes sonidos sin intervención del usuario.

Además, para probar el juego, se escribió un "bot" que puede jugar consigo mismo.
Simplemente abra la pestaña del navegador, donde los parámetros indican que desea ejecutar la prueba

 http://127.0.0.1?master=1&test=1&sound=0&testUsersCount=5 

y permitir abrir nuevas pestañas de JavaScript para este dominio.
Después del comienzo del juego, se abrirán 5 pestañas más con los jugadores y comenzarán a jugar entre ellos.

Protocolo de interacción


Se eligió el protocolo WebSocket debido a la necesidad de un intercambio de datos bidireccional constante entre el backend y la interfaz y su soporte en ambos idiomas.

Eventos del juego


Todo el juego se divide en eventos:

Eventos
  • juego
    • crear
    • unirse
    • empezar
    • sobre
    • reconectar

  • dia
    • empezar

  • noche
    • empezar

  • saludo ciudadano
    • empezar
    • papel
    • fin

  • saludo de la mafia
    • empezar
    • jugadores
    • fin

  • corte
    • empezar
    • jugadores
    • fin

  • mafia
    • empezar
    • jugadores
    • fin

  • doctor
    • empezar
    • jugadores
    • fin

  • chica
    • empezar
    • jugadores
    • fin

  • Sherif
    • empezar
    • jugadores
    • fin



Los eventos tienen un principio, final y contenido.
Al principio y al final del evento, se envía una notificación a todos los jugadores activos, que debe confirmarse. El juego continúa solo después de la confirmación de este evento por parte de todos los jugadores activos (por ejemplo, solo después de reproducir el archivo de sonido).

Docker


Todo el juego se puede elevar usando Docker :
docker-compose.yml

 version: '3' services: mafia-frontend: image: mrsuh/mafia-frontend:latest container_name: mafia_frontend ports: - 9080:80 mafia-backend: image: mrsuh/mafia-backend:latest container_name: mafia_backend ports: - 8000:8000 

Es suficiente instalar Docker (si aún no lo ha hecho), copie el texto docker-compose.yml y ejecute el comando:

 docker-compose up 

Después de eso, puedes abrir la pestaña del juego en el navegador:

 http://127.0.0.1:9080 

Conclusión


Aquí puede ver cuál fue el resultado (la velocidad de reproducción aumentó 1.5 veces).


Después de casi un mes de desarrollo en mi tiempo libre, obtuve un juego bastante estable que puedes jugar con amigos. El juego soporta recargas de páginas o interrupciones temporales de la red. La actuación de voz de eventos en dispositivos funciona, aunque sin sincronización de tiempo. El desarrollo adicional del juego no está planeado.

PD: Gracias a Lera por la actuación de voz del juego.

Source: https://habr.com/ru/post/es423821/


All Articles