Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Multiplayer
Gamedevelopment

Membangun Jaringan Game Multiplayer Peer-to-Peer

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Nasrullah Baddolo (you can also view the original English article)

Bermain game multi-pemain selalu menyenangkan. Alih-alih mengalahkan lawan yang dikendalikan AI, pemain harus menghadapi strategi yang dibuat oleh manusia lain. Tutorial ini menyajikan implementasi permainan multiplayer yang dimainkan melalui jaringan menggunakan pendekatan peer-to-peer (P2P) non-authoritative.

Catatan: Meskipun tutorial ini ditulis menggunakan AS3 dan Flash, Anda harus dapat menggunakan teknik dan konsep yang sama di hampir semua lingkungan pengembangan game. Anda harus memiliki pemahaman dasar tentang komunikasi jaringan.

Anda dapat mengunduh atau membayar kode terakhir dari repo GitHub atau file sumber yang di-zip.


Pratinjau Hasil Akhir

Demo jaringan. Kontrol: panah atau WASD untuk bergerak, Spasi untuk menembak, B untuk menyebarkan bom.

Seni dari Remaster Tyrian GraphicsIron Plague, dan Hard Vacuum oleh Daniel Cook (Lost Garden).


Pengantar

Permainan multi-pemain yang dimainkan melalui jaringan dapat diimplementasikan menggunakan beberapa pendekatan yang berbeda, yang dapat dikategorikan ke dalam dua grup: otoritatif dan non-otoritatif.

Dalam grup otoritatif, pendekatan yang paling umum adalah arsitektur client-server, di mana entitas pusat (server otoritatif) mengontrol seluruh permainan. Setiap klien yang terhubung ke server secara konstan menerima data, secara lokal menciptakan representasi dari status game. Ini seperti menonton TV.

Implementasi otoritatif menggunakan arsitektur client-server. 

Jika klien melakukan suatu tindakan, seperti berpindah dari satu titik ke titik lain, informasi itu dikirim ke server. Server memeriksa apakah informasinya benar, kemudian memperbarui status game-nya. Setelah itu menyebarkan informasi ke semua klien, sehingga mereka dapat memperbarui status game mereka sesuai.

Dalam grup non-authoritative, tidak ada entitas pusat dan setiap rekan (game) mengontrol status permainannya. Dalam pendekatan peer-to-peer (P2P), rekan mengirim data ke semua peer lain dan menerima data dari mereka, dengan asumsi bahwa informasi tersebut dapat diandalkan dan benar (bebas kecurangan):

Implementasi non-otoritatif menggunakan arsitektur P2P.

Dalam tutorial ini saya menyajikan implementasi game multiplayer yang dimainkan melalui jaringan menggunakan pendekatan P2P non-otoritatif. Game ini adalah arena deathmatch di mana setiap pemain mengendalikan kapal yang mampu menembak dan menjatuhkan bom.

Saya akan fokus pada komunikasi dan sinkronisasi negara rekan. Game dan kode jaringan disarikan sebanyak mungkin demi penyederhanaan.

Tips: pendekatan otoritatif lebih aman terhadap kecurangan, karena server sepenuhnya mengontrol status gim dan dapat mengabaikan pesan mencurigakan apa pun, seperti entitas yang mengatakannya bergerak 200 piksel padahal hanya bisa bergerak 10.

Mendefinisikan Game Non-Otoritatif

Permainan multi-pemain yang tidak memiliki otoritas tidak memiliki entitas pusat untuk mengontrol status permainan, jadi setiap rekan harus mengontrol status gimnya sendiri, mengkomunikasikan segala perubahan dan tindakan penting kepada pihak lain. Sebagai akibatnya, pemain melihat dua skenario secara bersamaan: kapalnya bergerak sesuai dengan masukannya dan simulasi semua kapal lain yang dikendalikan oleh lawan:

Kapal pemain dikontrol secara lokal. Lawan kapal disimulasikan berdasarkan komunikasi jaringan.

Gerakan dan tindakan kapal pemain dipandu oleh masukan lokal, sehingga status gim pemain diperbarui hampir seketika. Untuk pergerakan semua kapal lainnya, pemain harus menerima pesan jaringan dari setiap lawan yang menginformasikan ke mana kapal mereka berada.

Pesan tersebut membutuhkan waktu untuk melakukan perjalanan melalui jaringan dari satu komputer ke komputer lain, jadi ketika pemain menerima informasi yang mengatakan bahwa kapal lawan ada di (x, y), itu mungkin tidak ada lagi - itulah mengapa itu adalah simulasi:

Penundaan komunikasi yang disebabkan oleh jaringan. 

Untuk menjaga agar simulasi tetap akurat, setiap rekan bertanggung jawab untuk menyebarkan hanya informasi tentang kapalnya, bukan yang lain. Ini berarti bahwa, jika permainan memiliki empat pemain - katakanlah ABC dan D - player A adalah satu-satunya yang dapat memberi tahu di mana kapal A, jika terkena, jika menembakkan peluru atau menjatuhkan bom, dan seterusnya. Semua pemain lain akan menerima pesan dari A menginformasikan tentang tindakannya dan mereka akan bereaksi sesuai, jadi jika peluru A-nya mendapat kapal C-nya, maka C akan menyiarkan pesan yang menginformasikan bahwa itu dihancurkan.

Sebagai akibatnya, setiap pemain akan melihat semua kapal lain (dan tindakan mereka) sesuai dengan pesan yang diterima. Di dunia yang sempurna, tidak akan ada latensi jaringan, jadi pesan akan datang dan pergi seketika dan simulasi akan sangat akurat.

Karena latensi meningkat, bagaimanapun, simulasi menjadi tidak akurat. Sebagai contoh, pemain A menembak dan secara lokal melihat peluru memukul kapal B-nya, tetapi tidak ada yang terjadi; itu karena pandangan A tentang B tertunda karena jeda jaringan. Ketika B benar-benar menerima pesan peluru AB berada di posisi yang berbeda, jadi tidak ada yang disebarkan.


Memetakan Tindakan yang Relevan

Langkah penting dalam mengimplementasikan permainan dan memastikan bahwa setiap pemain akan dapat melihat simulasi yang sama secara akurat adalah identifikasi tindakan yang relevan. Tindakan tersebut mengubah status game saat ini, seperti berpindah dari satu titik ke titik lain, menjatuhkan bom, dll.

Dalam permainan kami, tindakan penting adalah:

  • shoot (kapal pemain menembakkan peluru atau bom)
  • move (kapal pemain dipindahkan)
  • die (kapal pemain hancur)

Aksi pemain selama pertandingan. 

Setiap tindakan harus dikirim melalui jaringan, jadi penting untuk menemukan keseimbangan antara jumlah tindakan dan ukuran pesan jaringan yang akan mereka hasilkan. Semakin besar pesannya (yaitu, semakin banyak data yang dikandungnya), semakin lama waktu yang dibutuhkan untuk diangkut, karena mungkin memerlukan lebih dari satu paket jaringan.

Pesan singkat menuntut lebih sedikit waktu CPU untuk berkemas, kirim, dan buka kemasan. Pesan jaringan kecil juga menghasilkan lebih banyak pesan yang dikirim pada saat yang bersamaan, yang meningkatkan throughput.


Melakukan Aksi Secara Mandiri

Setelah tindakan yang relevan dipetakan, saatnya membuatnya direproduksi tanpa masukan pengguna. Meskipun itu adalah prinsip rekayasa perangkat lunak yang baik, itu mungkin tidak jelas dari sudut pandang permainan multi pemain.

Menggunakan aksi pengambilan gambar dari permainan kami sebagai contoh, jika itu sangat terkait dengan logika masukan, tidak mungkin untuk menggunakan kembali kode pemotretan yang sama dalam situasi yang berbeda:

Melakukan tindakan secara mandiri. 

Ketika kode pemotretan dipisahkan dari logika input, misalnya, dimungkinkan untuk menggunakan kode yang sama untuk menembak peluru pemain dan peluru lawan (ketika pesan jaringan tersebut tiba). Ini menghindari replikasi kode dan mencegah banyak sakit kepala.

Kelas Ship dalam permainan kami, misalnya, tidak memiliki kode multi-pemain; itu sepenuhnya dipisahkan. Ini menggambarkan sebuah kapal, baik itu lokal atau tidak. Kelas, bagaimanapun, memiliki beberapa metode untuk memanipulasi kapal, seperti rotate() dan penyetel untuk mengubah posisinya. Sebagai akibatnya, kode multiplayer dapat memutar kapal dengan cara yang sama seperti yang dilakukan oleh kode input pengguna - perbedaannya adalah bahwa satu didasarkan pada masukan lokal, sementara yang lain didasarkan pada pesan jaringan.


Bertukar Data Berdasarkan Tindakan

Sekarang semua tindakan yang relevan dipetakan, saatnya untuk bertukar pesan di antara teman-teman untuk membuat simulasi. Sebelum menukar data apa pun, protokol komunikasi harus diformulasikan. Mengenai komunikasi permainan multi pemain, protokol dapat didefinisikan sebagai seperangkat aturan yang menggambarkan bagaimana pesan terstruktur, sehingga setiap orang dapat mengirim, membaca, dan memahami pesan-pesan itu.

Pesan yang dipertukarkan dalam permainan akan digambarkan sebagai objek, semua mengandung properti wajib yang disebut op (kode operasi). op digunakan untuk mengidentifikasi jenis pesan dan menunjukkan properti yang dimiliki objek pesan. Ini adalah struktur semua pesan:

truktur pesan jaringan. 
  • Pesan OP_DIE menyatakan bahwa sebuah kapal hancur. Sifat x dan y nya memuat lokasi kapal ketika hancur.
  • Pesan OP_POSITION berisi lokasi saat ini dari kapal peer. Sifat x dan y nya mengandung koordinat kapal di layar, sedangkan angle adalah sudut rotasi kapal saat ini.
  • Pesan OP_SHOT menyatakan bahwa sebuah kapal menembak sesuatu (peluru atau bom). Properti x dan y berisi lokasi kapal ketika dipecat; properti dx dan dy menunjukkan arah kapal, yang memastikan peluru akan direplikasi pada semua peers menggunakan sudut yang sama dengan yang digunakan oleh kapal penembakan saat membidik; dan properti b mendefinisikan tipe proyektil ( bullet atau bomb ).

Class Multiplayer

Untuk mengatur kode multipemain, kita membuat class Multiplayer. Ini bertanggung jawab untuk mengirim dan menerima pesan, serta memperbarui kapal-kapal lokal sesuai dengan pesan yang diterima untuk mencerminkan keadaan saat ini dari simulasi permainan.

Struktur awalnya, yang hanya berisi kode pesan, adalah:


Mengirim Pesan Aksi

Untuk setiap tindakan relevan yang dipetakan sebelumnya, pesan jaringan harus dikirim, sehingga semua rekan akan diberi tahu tentang tindakan itu.

Aksi OP_DIE harus dikirim ketika pemain terkena peluru atau ledakan bom. Sudah ada metode dalam kode permainan yang menghancurkan kapal pemain ketika dipukul, jadi diperbarui untuk menyebarkan informasi itu:

Tindakan OP_POSITION harus dikirim setiap kali pemain mengubah posisinya saat ini. Kode multiplayer disuntikkan ke dalam kode permainan untuk menyebarkan informasi itu juga:

Akhirnya, aksi OP_SHOT harus dikirim setiap kali pemain menembakkan sesuatu. Pesan yang dikirim berisi jenis peluru yang ditembakkan, sehingga setiap rekan akan melihat proyektil yang benar:


Sinkronisasi Berdasarkan Data yang Diterima

Pada titik ini, setiap pemain dapat mengontrol dan melihat kapal mereka. Di bawah kap, pesan jaringan dikirim berdasarkan tindakan yang relevan. Satu-satunya bagian yang hilang adalah penambahan lawan, sehingga setiap pemain dapat melihat kapal lain dan berinteraksi dengan mereka.

Dalam gim ini, kapal disusun sebagai larik. Array itu hanya memiliki satu kapal (pemain) sampai sekarang. Untuk membuat simulasi untuk semua pemain lain, kelas Multiplayer akan diubah untuk menambahkan kapal baru ke array tersebut setiap kali pemain baru bergabung dengan arena:

Kode pertukaran pesan secara otomatis menyediakan pengenal unik untuk setiap pemain (user.id dalam kode di atas). Identifikasi itu digunakan oleh kode multipemain untuk membuat kapal baru ketika seorang pemain bergabung dengan arena; Dengan cara ini, setiap kapal memiliki identifier yang unik. Dengan menggunakan pengidentifikasi pengarang dari setiap pesan yang diterima, adalah mungkin untuk mencari kapal itu dalam susunan kapal.

Akhirnya, saatnya untuk menambahkan handleGetObject() ke class Multiplayer. Metode ini dipanggil setiap kali pesan baru tiba:

Ketika pesan baru tiba, metode handleGetObject() dipanggil dengan dua parameter: ID penulis (pengenal unik) dan data pesan. Menganalisis data pesan, kode operasi diekstrak dan, berdasarkan itu, semua properti lainnya juga diekstraksi.

Menggunakan data yang diekstraksi, kode multiplayer mereproduksi semua tindakan yang diterima melalui jaringan. Mengambil pesan OP_SHOT sebagai contoh, ini adalah langkah-langkah yang dilakukan untuk memperbarui status game saat ini:

  1. Lihat kapal lokal yang diidentifikasi oleh userId.
  2. Perbarui posisi dan sudut Ship sesuai dengan data yang diterima.
  3. Perbarui arah Ship sesuai dengan data yang diterima.
  4. Memanggil metode permainan yang bertanggung jawab untuk menembakkan proyektil, menembakkan peluru atau bom.

Seperti yang dijelaskan sebelumnya, kode pemotretan dipisahkan dari pemutar dan logika input, sehingga proyektil ditembakkan berperilaku persis seperti yang dipecat oleh pemain lokal.


Memitigasi Masalah Latensi

Jika game secara eksklusif memindahkan entitas berdasarkan pembaruan jaringan, pesan yang hilang atau tertunda akan menyebabkan entitas untuk "teleport" dari satu titik ke titik lainnya. Itu bisa dimitigasi dengan prediksi lokal.

Menggunakan interpolasi, misalnya, gerakan entitas secara lokal diinterpolasi dari satu titik ke titik lainnya (keduanya diterima oleh pembaruan jaringan). Akibatnya, entitas akan lancar bergerak di antara titik-titik tersebut. Idealnya, latensi tidak boleh melebihi waktu yang diperlukan suatu entitas untuk diinterpolasi dari satu titik ke titik lainnya.

Trik lain adalah ekstrapolasi, yang memindahkan entitas secara lokal berdasarkan statusnya saat ini. Ini mengasumsikan bahwa entitas tidak akan mengubah rute saat ini, jadi aman untuk membuatnya bergerak sesuai arah dan kecepatannya saat ini, misalnya. Jika latensi tidak terlalu tinggi, ekstrapolasi secara akurat mereproduksi gerakan yang diharapkan entitas sampai pembaruan jaringan baru tiba, menghasilkan pola gerakan yang mulus.

Meskipun trik-trik itu, latensi jaringan bisa sangat tinggi dan kadang-kadang tidak terkendali. Pendekatan termudah untuk menghilangkan itu adalah untuk memutuskan hubungan yang bermasalah. Pendekatan yang aman untuk itu adalah dengan menggunakan timeout: jika rekan membutuhkan waktu lebih dari waktu yang ditentukan untuk menjawab, itu terputus.


Kesimpulan

Membuat gim multiplayer yang dimainkan melalui jaringan adalah tugas yang menantang dan mengasyikkan. Ini membutuhkan cara yang berbeda dalam melihat sesuatu karena semua tindakan yang relevan harus dikirim dan direproduksi oleh semua rekan. Sebagai akibatnya, semua pemain melihat simulasi dari apa yang terjadi, kecuali untuk kapal lokal, yang tidak memiliki latensi jaringan.

Tutorial ini menggambarkan implementasi game multipemain menggunakan pendekatan P2P non-otoritatif. Semua konsep yang disajikan dapat diperluas untuk menerapkan mekanisme multiplayer yang berbeda. Biarkan pembuatan game multiplayer dimulai!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.