
Es geht um die Web-Implementierung des beliebten Kartenspiels "
Mafia ". Es wurde für Spaß und Erfahrung in der Spieleentwicklung geschrieben. Die erste Version wurde in zwei Wochen Freizeit von der Arbeit geschrieben und gleichzeitig in die zweite Version umgeschrieben. Der Vorteil dieses Spiels ist das Fehlen eines Hosts.
Basierend auf den Entwicklungszielen habe ich mich für die Implementierung / Nichtimplementierung von Features entschieden.
Was genau getan werden musste:
- Minimales Spiel, das die Regeln des klassischen Spiels wiederholt
- Stimme der Befehle des Führers auf Clientgeräten
- Fortsetzung des Spiels auch nach dem Neustart der Browser-Registerkarte
Was nicht geplant war oder verschoben werden konnte:
- Spielregistrierung
- Administrationsoberfläche
- Permanente Speicherung von Spieldaten in einer Datenbank
- Zeitsynchronisation zwischen Geräten
Backend
https://github.com/mrsuh/mafia-backendGeschrieben in Go. Es speichert den Status des Spiels und ist für seine Logik verantwortlich.
Während des Spiels können Sie den Server kontaktieren, um die vollständigen Informationen zu erhalten:
curl 'http://127.0.0.1:8000/info?game=23' | python -m json.tool
Spielinformationsanzeige{
"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
}
Oder finden Sie den Status des Servers heraus:
curl 'http://127.0.0.1:8000/health' | python -m json.tool
Serverstatusinformationen anzeigen{
"runtime.MemStats.Alloc": 764752,
"runtime.MemStats.NumGC": 0,
"runtime.MemStats.Sys": 4165632,
"runtime.MemStats.TotalAlloc": 764752,
"runtime.NumGoroutine": 14
}
Um festzustellen, ob der Player noch aktiv ist, sendet das Backend einen Herzschlag. Wenn ein Spieler nach einem bestimmten Intervall nicht reagiert, wird er aus dem Spiel ausgeschlossen. Wenn sich ein Spieler vor dem Ende des Intervalls erneut verbindet (das Netzwerk ist verschwunden), kann er das Spiel fortsetzen.
Für einen stabilen Betrieb wurde das Backend durch Unit-Tests mit der Standard-
Go-Bibliothek abgedeckt, in denen die wichtigsten Betriebsszenarien überprüft werden.
go test mafia-backend/src -cover ok mafia-backend/src 1.315s coverage: 70.7% of statements
Frontend
https://github.com/mrsuh/mafia-frontendEs ist in reinem JS geschrieben und mit
Grunt erstellt .
Es enthält keine Logik.
Wenn ein Ereignis mit dem Backend auftritt, wird die gewünschte Seite gerendert, die an es gesendeten Daten angezeigt und der Sound des neuen Ereignisses abgespielt.
Das Frontend speichert die Spiel- und Spieler-
IDs in
LocalStorage oder in der Browser-
Abfragezeichenfolge (wenn Sie mehrere Registerkarten in einem Browser für verschiedene Spieler ausführen müssen). Das völlige Fehlen von Logik sowie die Speicherung der Grundparameter des Spiels ermöglichen es, auch nach dem erneuten Laden der Seite den Status des Spiels wiederherzustellen.
Der Browser
verhindert die automatische Wiedergabe von Sounds ohne Benutzereingriff (z. B. Drücken einer Taste). Um Sounds für jedes Ereignis abzuspielen, das mit dem Backend geliefert wird, wurde nur 1 JavaScript-Audioobjekt erstellt. Jeder Spieler muss eine Taste drücken, um das Spiel zu starten. In diesem Moment wird das Audio-Objekt aktiv (zur Wiedergabe verfügbar). Anschließend kann er den src-Parameter ändern, um ohne Benutzereingriff verschiedene Sounds abzuspielen.
Um das Spiel zu testen, wurde ein „Bot“ geschrieben, der mit sich selbst spielen kann.
Öffnen Sie einfach die Registerkarte Browser, auf der die Parameter angeben, dass Sie den Test ausführen möchten
http://127.0.0.1?master=1&test=1&sound=0&testUsersCount=5
und ermöglichen das Öffnen neuer Registerkarten aus JavaScript für diese Domain.
Nach dem Start des Spiels werden 5 weitere Registerkarten mit Spielern geöffnet und sie beginnen untereinander zu spielen.
Interaktionsprotokoll
Das
WebSocket- Protokoll wurde ausgewählt, da ein ständiger bidirektionaler Datenaustausch zwischen Backend und Frontend erforderlich ist und beide Sprachen unterstützt werden.
Spielereignisse
Das ganze Spiel ist in Ereignisse unterteilt:
Ereignisse- Spiel
- erstellen
- beitreten
- starten
- vorbei
- wieder verbinden
- Tag
- Nacht
- Bürgergruß
- Mafia-Gruß
- Gericht
- Mafia
- Arzt
- Mädchen
- Sherif
Ereignisse haben einen Anfang, ein Ende und einen Inhalt.
Zu Beginn und am Ende des Events wird eine Benachrichtigung an alle aktiven Spieler gesendet, die bestätigt werden muss. Das Spiel wird erst nach Bestätigung dieses Ereignisses durch alle aktiven Spieler fortgesetzt (z. B. erst nach dem Abspielen der Sounddatei).
Docker
Das ganze Spiel kann mit
Docker ausgelöst werden :
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 reicht aus, Docker zu installieren (falls Sie dies noch nicht getan haben), den Text
docker-compose.yml zu kopieren und den folgenden Befehl auszuführen:
docker-compose up
Danach können Sie die Registerkarte Spiel im Browser öffnen:
http://127.0.0.1:9080
Fazit
Hier können Sie sehen, wie sich das Ergebnis herausstellte (Wiedergabegeschwindigkeit um das 1,5-fache erhöht).
Nach fast einem Monat Entwicklungszeit in meiner Freizeit habe ich ein ziemlich stabiles Spiel bekommen, das Sie mit Freunden spielen können. Das Spiel hält dem erneuten Laden von Seiten oder vorübergehenden Netzwerkausfällen stand. Die Sprachausgabe von Ereignissen auf Geräten funktioniert, allerdings ohne Zeitsynchronisation. Eine Weiterentwicklung des Spiels ist nicht geplant.
PS: Danke an
Lera für die Sprachausgabe des Spiels.