It's about the web-implementation of the popular card game " Mafia ". It was written for fun and experience in game development. The first version was written in two weeks of free time from work and for the same time was rewritten before the second version. Plus this game - the absence of a lead. Based on the development goals, I made decisions on the implementation / non-implementation of features. What exactly needed to be done:
Minimally working game, repeating the rules of the classic game
Voice command of the host on client devices
Continuation of the game even after reloading the browser tab
To determine if the player is still active, the backend sends heartbeat. If the player does not answer after a certain interval, then he leaves the game. At the same time, if a player reconnects before the end of the interval (the network is gone), then he can continue the game.
For stable operation, the backend was covered by Unit tests with the standard Go library , where the main work scenarios are checked.
go test mafia-backend/src -cover ok mafia-backend/src 1.315s coverage: 70.7% of statements
When an event occurs with a backend, it renders the necessary page, displays the data that was sent to it and plays the sound of a new event.
Frontend stores the game ID and player ID in LocalStorage or the browser's request bar (if you need to run multiple tabs for different players in one browser). The complete absence of logic, as well as the storage of the basic parameters of the game, make it possible, even after reloading the page, to restore the state of the game.
The browser prohibits the autoplay of sounds without user intervention (for example, pressing a button). In order to play sounds for each event, only 1 JavaScript Audio object was made with the backend. Each player must press the button to start the game and at this point the Audio object becomes active (available for playback), and subsequently it can change the src parameter to play different sounds without user intervention.
Also to test the work of the game was written "bot", which can play with itself. Just open the browser tab, where the parameters indicate that you need to run the test
and allow opening new tabs from javascript for this domain. After the start of the game, 5 more tabs with players will open and they will start playing among themselves.
Interaction protocol
The WebSocket protocol was chosen because of the need for constant two-way data exchange between the backend and frontend and its support in both languages.
Game events
The whole game is divided into events:
Developments
game
create
join
start
over
reconnect
day
start
night
start
citizens-greeting
start
role
end
mafia-greeting
start
players
end
court
start
players
end
mafia
start
players
end
doctor
start
players
end
girl
start
players
end
sherif
start
players
end
Events have a beginning, an end and a meaningful part. At the beginning and end of the event, a notification is sent to all active players that needs to be confirmed. The game continues only after the confirmation of this event by all active players (for example, only after the sound file is played).
Docker
The whole game can be raised using Docker : docker-compose.yml
It is enough to install Docker (if you have not already done this), copy the docker-compose.yml text to yourself and execute the command:
docker-compose up
After that, you can open the tab with the game in the browser:
http://127.0.0.1:9080
Conclusion
Here you can see what happened (playback speed increased by 1.5 times).
After nearly a month of development in my spare time, I got a fairly stable game that you can play with friends. The game can withstand page reload or temporary network loss. Voice events on the devices works, albeit without time synchronization. Further development of the game is not planned.