Mafia on Go, Vanila JS dan WebSocket'ah



Ini akan tentang implementasi web dari permainan kartu populer " Mafia ". Itu ditulis untuk kesenangan dan pengalaman dalam pengembangan game. Versi pertama ditulis dalam dua minggu waktu senggang dari kerja dan pada saat yang sama ditulis ulang untuk versi kedua. Kelebihan dari game ini adalah tidak adanya tuan rumah.

Berdasarkan tujuan pengembangan, saya memutuskan implementasi / non-implementasi fitur.
Apa yang sebenarnya perlu dilakukan:

  • Game minimal mengulangi aturan game klasik
  • Suara perintah pemimpin di perangkat klien
  • Kelanjutan game bahkan setelah me-reboot tab browser

Apa yang tidak direncanakan atau dapat ditunda:

  • Registrasi Game
  • Antarmuka Administrasi
  • Penyimpanan data game secara permanen dalam database
  • Sinkronisasi waktu antar perangkat

Backend


https://github.com/mrsuh/mafia-backend
Ditulis dalam Go. Ini menyimpan keadaan permainan dan bertanggung jawab untuk logikanya.

Selama permainan, Anda dapat menghubungi server untuk mengetahui informasi lengkap:

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

Tampilan Informasi Game
{
"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
}


Atau cari tahu status server:

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

Tampilkan informasi status server
{
"runtime.MemStats.Alloc": 764752,
"runtime.MemStats.NumGC": 0,
"runtime.MemStats.Sys": 4165632,
"runtime.MemStats.TotalAlloc": 764752,
"runtime.NumGoroutine": 14
}


Untuk menentukan apakah pemain masih aktif, backend mengirimkan detak jantung. Jika seorang pemain tidak merespons setelah interval tertentu, maka ia tersingkir dari permainan. Pada saat yang sama, jika seorang pemain menghubungkan kembali sebelum akhir interval (jaringan telah menghilang), maka dia dapat melanjutkan permainan.

Untuk operasi yang stabil, backend ditutupi oleh tes Unit dengan perpustakaan Go standar, di mana skenario operasi utama diperiksa.

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

Frontend


https://github.com/mrsuh/mafia-frontend
Itu ditulis dalam JS murni dan dibangun menggunakan Grunt .
Itu tidak membawa logika apa pun.

Ketika suatu peristiwa terjadi dengan backend, itu membuat halaman yang diinginkan, menampilkan data yang dikirim ke sana dan memainkan suara acara baru.

Frontend menyimpan ID game dan pemain di LocalStorage atau dalam string kueri browser (jika Anda perlu menjalankan beberapa tab dalam satu browser untuk pemain yang berbeda). Kurangnya logika, serta penyimpanan parameter dasar gim memungkinkan bahkan setelah memuat ulang laman untuk memulihkan keadaan gim.

Browser melarang pemutaran suara secara otomatis tanpa campur tangan pengguna (misalnya, menekan tombol). Untuk memutar suara untuk setiap acara yang datang dengan backend, hanya 1 objek Audio JavaScript yang dibuat. Setiap pemain harus menekan tombol untuk memulai permainan dan pada saat itu objek Audio menjadi aktif (tersedia untuk pemutaran), dan selanjutnya dia dapat mengubah parameter src untuk memainkan suara yang berbeda tanpa campur tangan pengguna.

Juga, untuk menguji permainan, sebuah "bot" ditulis yang dapat bermain dengan sendirinya.
Cukup buka tab browser, di mana parameter menunjukkan bahwa Anda ingin menjalankan tes

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

dan izinkan membuka tab baru dari JavaScript untuk domain ini.
Setelah awal permainan, 5 tab lagi dengan pemain akan terbuka dan mereka akan mulai bermain di antara mereka sendiri.

Protokol interaksi


Protokol WebSocket dipilih karena kebutuhan untuk pertukaran data dua arah yang konstan antara backend dan frontend dan dukungannya dalam kedua bahasa.

Peristiwa game


Seluruh permainan dibagi menjadi beberapa acara:

Acara
  • permainan
    • buat
    • bergabunglah
    • mulai
    • selesai
    • terhubung kembali

  • hari
    • mulai

  • malam
    • mulai

  • ucapan selamat warga
    • mulai
    • peran
    • akhir

  • salam mafia
    • mulai
    • pemain
    • akhir

  • pengadilan
    • mulai
    • pemain
    • akhir

  • mafia
    • mulai
    • pemain
    • akhir

  • dokter
    • mulai
    • pemain
    • akhir

  • perempuan
    • mulai
    • pemain
    • akhir

  • sherif
    • mulai
    • pemain
    • akhir



Acara memiliki awal, akhir, dan konten.
Di awal dan akhir acara, pemberitahuan dikirim ke semua pemain aktif, yang harus dikonfirmasi. Permainan berlanjut hanya setelah konfirmasi acara ini oleh semua pemain aktif (misalnya, hanya setelah file suara dimainkan).

Docker


Seluruh game dapat dinaikkan menggunakan 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 

Cukup menginstal Docker (jika Anda belum melakukannya), salin text docker-compose.yml dan jalankan perintah:

 docker-compose up 

Setelah itu, Anda dapat membuka tab game di browser:

 http://127.0.0.1:9080 

Kesimpulan


Di sini Anda dapat melihat apa hasilnya ternyata (kecepatan pemutaran meningkat 1,5 kali).


Setelah hampir satu bulan perkembangan di waktu luang saya, saya mendapat permainan yang cukup stabil yang bisa Anda mainkan dengan teman-teman. Gim ini menahan reload halaman atau pemadaman jaringan sementara. Akting suara dari peristiwa di perangkat berfungsi, meskipun tanpa sinkronisasi waktu. Pengembangan lebih lanjut dari game ini tidak direncanakan.

PS: Terima kasih kepada Lera untuk akting suara dari game.

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


All Articles