Mafia on Go, Vanila JS et WebSocket'ah



Il s'agira de la mise en œuvre Web du jeu de cartes populaire " Mafia ". Il a été écrit pour le plaisir et l'expérience du développement de jeux. La première version a été écrite en deux semaines de temps libre du travail et en même temps a été réécrite dans la deuxième version. L'avantage de ce jeu est l'absence d'hôte.

Sur la base des objectifs de développement, j'ai décidé de l'implémentation / non-implémentation des fonctionnalités.
Ce qu'il fallait exactement faire:

  • Jeu minimal répétant les règles du jeu classique
  • Voix des commandes du leader sur les appareils clients
  • Poursuite du jeu même après redémarrage de l'onglet navigateur

Ce qui n'était pas prévu ou pourrait être reporté:

  • Inscription au jeu
  • Interface d'administration
  • Stockage permanent des données de jeu dans une base de données
  • Synchronisation horaire entre les appareils

Backend


https://github.com/mrsuh/mafia-backend
Écrit en Go. Il stocke l'état du jeu et est responsable de sa logique.

Pendant le jeu, vous pouvez contacter le serveur pour connaître les informations complètes:

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

Affichage des informations sur le jeu
{
"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
}


Ou découvrez l'état du serveur:

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

Afficher les informations sur l'état du serveur
{
"runtime.MemStats.Alloc": 764752,
"runtime.MemStats.NumGC": 0,
"runtime.MemStats.Sys": 4165632,
"runtime.MemStats.TotalAlloc": 764752,
"runtime.NumGoroutine": 14
}


Pour déterminer si le joueur est toujours actif, le backend envoie un battement de coeur. Si un joueur ne répond pas après un certain intervalle, il est alors éliminé de la partie. Dans le même temps, si un joueur se reconnecte avant la fin de l'intervalle (le réseau a disparu), il peut continuer la partie.

Pour un fonctionnement stable, le backend a été couvert par des tests unitaires avec la bibliothèque Go standard, où les principaux scénarios de fonctionnement sont vérifiés.

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

Frontend


https://github.com/mrsuh/mafia-frontend
Il est écrit en JS pur et construit à l'aide de Grunt .
Il n'a aucune logique.

Lorsqu'un événement se produit avec le backend, il affiche la page souhaitée, affiche les données qui lui ont été envoyées et lit le son du nouvel événement.

Frontend stocke les ID de jeu et de joueur dans LocalStorage ou dans la chaîne de requête du navigateur (si vous devez exécuter plusieurs onglets dans un navigateur pour différents joueurs). L'absence totale de logique, ainsi que le stockage des paramètres de base du jeu permettent même après rechargement de la page de restaurer l'état du jeu.

Le navigateur interdit la lecture automatique des sons sans intervention de l'utilisateur (par exemple, en appuyant sur un bouton). Afin de jouer des sons pour chaque événement fourni avec le backend, un seul objet audio JavaScript a été créé. Chaque joueur doit appuyer sur un bouton pour démarrer le jeu et à ce moment, l'objet audio devient actif (disponible pour la lecture), et par la suite il peut changer le paramètre src pour jouer différents sons sans intervention de l'utilisateur.

De plus, pour tester le jeu, un «bot» a été écrit qui peut jouer avec lui-même.
Ouvrez simplement l'onglet du navigateur, où les paramètres indiquent que vous souhaitez exécuter le test

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

et autoriser l'ouverture de nouveaux onglets à partir de JavaScript pour ce domaine.
Après le début du jeu, 5 onglets supplémentaires avec les joueurs s'ouvriront et ils commenceront à jouer entre eux.

Protocole d'interaction


Le protocole WebSocket a été choisi en raison de la nécessité d'un échange de données bidirectionnel constant entre le backend et le frontend et sa prise en charge dans les deux langues.

Événements de jeu


L'ensemble du jeu est divisé en événements:

Les événements
  • jeu
    • créer
    • rejoindre
    • commencer
    • sur
    • reconnecter

  • jour
    • commencer

  • nuit
    • commencer

  • salut des citoyens
    • commencer
    • rôle
    • fin

  • mafia-salutation
    • commencer
    • joueurs
    • fin

  • cour
    • commencer
    • joueurs
    • fin

  • mafia
    • commencer
    • joueurs
    • fin

  • docteur
    • commencer
    • joueurs
    • fin

  • fille
    • commencer
    • joueurs
    • fin

  • chérif
    • commencer
    • joueurs
    • fin



Les événements ont un début, une fin et un contenu.
Au début et à la fin de l'événement, une notification est envoyée à tous les joueurs actifs, qui doit être confirmée. Le jeu se poursuit uniquement après la confirmation de cet événement par tous les joueurs actifs (par exemple, uniquement après la lecture du fichier audio).

Docker


L'ensemble du jeu peut être augmenté à l'aide de 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 

Il suffit d'installer Docker (si vous ne l'avez pas déjà fait), copiez le texte docker-compose.yml et exécutez la commande:

 docker-compose up 

Après cela, vous pouvez ouvrir l'onglet du jeu dans le navigateur:

 http://127.0.0.1:9080 

Conclusion


Ici, vous pouvez voir le résultat (vitesse de lecture augmentée de 1,5 fois).


Après presque un mois de développement dans mon temps libre, j'ai obtenu un jeu assez stable que vous pouvez jouer avec des amis. Le jeu résiste aux rechargements de page ou aux pannes de réseau temporaires. L'action vocale des événements sur les appareils fonctionne, mais sans synchronisation horaire. La poursuite du développement du jeu n'est pas prévue.

PS: Merci à Lera pour le doublage du jeu.

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


All Articles