Saya sudah memikirkan game multi-pemain RTS. Bagian yang sepertinya tidak bisa kudapatkan adalah menjaga pergerakan unit tersinkronisasi. Jika saya memindahkan unit A ke tempat XY, saya harus mengkomunikasikannya kembali ke server yang menyampaikan ke klien lain.
Saya ingin tahu seperti apa bentuk komunikasi itu. Apakah Anda hanya berkomunikasi dengan server bahwa saya memindahkan unit A ke XY dari JZ? Mungkin Anda perlu mengkomunikasikan gerakan coord dengan coord saja? Metodologi apa yang paling efisien untuk mengkomunikasikan perpindahan unit dari satu klien ke klien lainnya?
EDIT
Ini adalah pertanyaan yang diposting ulang dari stackoverflow . Saya menemukan bahwa situs ini mungkin tempat yang lebih baik untuk pertanyaan itu.
Salah satu jawaban yang lebih baik dari pos itu:
Saya berasumsi Anda bermaksud menggunakan paradigma jaringan Client-Server? Dalam hal ini Anda tidak bisa mempercayai klien untuk menangani penentuan posisi unit yang sebenarnya, Anda harus mendelegasikan tugas itu ke server. Anda kemudian mengambil daftar perintah dari setiap klien per-centang, dan menghitung pergerakan setiap unit, setelah ini selesai, centang berikutnya Anda menyampaikan posisi masing-masing unit yang relevan untuk setiap klien (baik secara keseluruhan peta, atau per-view basis), dan mulai proses lagi.
Jawaban:
Anda tidak ingin menyinkronkan posisi semua unit dari server ke setiap klien; yang akan memakan bandwidth jauh lebih banyak dari yang Anda butuhkan. Anda juga harus berurusan dengan posisi unit interpolasi / ekstrapolasi, dll. Hampir tidak ada klien / server RTS profesional!
Sebaliknya, Anda hanya ingin mengirim perintah para pemain. Alih-alih memindahkan unit segera ketika pemain mengklik, Anda akan mengantri-perintah untuk dilakukan di beberapa titik di masa depan - biasanya hanya beberapa frame. Semua orang mengirim perintah kepada semua orang. Beberapa frame kemudian, semua orang mengeksekusi semua perintah, dan karena gim ini deterministik, mereka semua melihat hasil yang sama.
Kekurangannya adalah bahwa setiap pemain selambat pemain paling lambat - jika ada yang ketinggalan mengirim perintah, semua orang harus memperlambat dan menunggunya untuk mengejar ketinggalan (di Starcraft 2, ini adalah "XXX memperlambat permainan " dialog).
Bahkan, ada satu hal lagi yang biasanya dilakukan: menghilangkan server sekaligus . Mintalah setiap klien mengirim perintah mereka ke setiap klien lainnya. Ini mengurangi lag (alih-alih perintah dari Anda -> server -> lawan, itu hanya pergi dari Anda -> lawan) dan membuat pengkodean lebih mudah, karena Anda tidak perlu lagi kode server yang terpisah. Arsitektur semacam ini disebut peer-to-peer (P2P).
Kelemahannya adalah bahwa sekarang Anda membutuhkan cara untuk menyelesaikan konflik, tetapi karena perintah pemain tidak tergantung satu sama lain di sebagian besar RTS, ini biasanya tidak terlalu menjadi masalah. Selain itu, skalanya tidak baik - setiap kali Anda menambahkan pemain baru, setiap pemain harus mengirim perintah kepadanya. Anda tidak akan membuat RTS MMO menggunakan P2P.
Pengaturan ini (hanya mengirim perintah menggunakan P2P) adalah cara sebagian besar RTS, termasuk Starcraft, C&C, dan AoE bekerja, dan merupakan satu-satunya cara AoE mungkin dapat mendukung 1500 unit pada koneksi 28,8 kbps .
Berikut adalah beberapa tips untuk menulis RTS P2P:
rand()
,cos()
dll, tetapi hampir semua matematika floating-point keluar dari pertanyaan (lihat di sini , di sini , dan di sini ) ! Dalam hal ini, Anda mungkin lebih baik menggunakan client-server.sumber
Saya telah membuat RTS jaringan-TCP, di mana saya melewati perintah sendiri, bukan hasil dari perintah . Misalnya, seorang pemain memberikan perintah bergerak. Jika perintah pemindahan berlaku sesuai dengan klien itu, itu akan dikirim ke server. Server kemudian mengirimkannya kembali ke semua klien, yang memvalidasi dan menjalankannya.
Jadi semua mesin klien menjalankan game sendiri, kode server menerima pesan dan mengirimkannya kembali ke semua klien. Jika klien memberikan perintah pindah, itu tidak akan mulai menjalankannya sampai diterima kembali dari server.
Server mengirimkan nomor 'centang' di mana untuk mengeksekusi perintah juga, yang merupakan beberapa centang di depan centang 'saat ini'. Dengan cara ini semua perintah dapat dieksekusi pada 'centang' yang sama pada semua mesin.
Satu manfaat metode ini adalah tidak bergantung pada mesin klien individual untuk memvalidasi perintah. Jika saya melewati hasil pemindahan, saya mungkin bisa meretasnya untuk memindahkan unit saya lebih cepat. Semua klien harus menjalankan perintah yang sama dan jika satu mesin mengeksekusinya secara berbeda, itu akan menjadi jelas.
Memvalidasi sisi klien perintah sebelum mengirimnya ke server tidak perlu, tetapi secara teori menghemat lalu lintas jaringan. Saya menggunakan kode validasi yang sama untuk memberi tahu UI bahwa langkah itu mungkin, jadi tidak perlu menulis kode tambahan.
Adapun seperti apa pesan-pesan itu. Saya tidak peduli dengan efisiensi ultra karena ini adalah game jaringan pertama saya. Saya melewati perintah sebagai string. Perintah akan diformat seperti ini:
"<player_id>:<command>:<parameters>"
Untuk contoh buat, perintah langkah mungkin terlihat seperti ini:
"3:move:522:100:200"
. Ini berarti Pemain3
inginmove
unit522
ke (100
,200
).Server melewati perintah ke semua klien, termasuk orang yang mengirimkannya, dengan sejumlah centang terpasang seperti ini:
"153238:3:move:522:100:200"
.Kemudian semua klien akan menjalankan perintah ini ketika tick 153238 dieksekusi.
sumber