Saya telah merancang sistem entitas untuk FPS. Ini pada dasarnya bekerja seperti ini:
Kami memiliki objek "dunia", yang disebut GameWorld. Ini menampung array dari GameObject, serta array dari ComponentManager.
GameObject memegang larik Komponen. Ini juga menyediakan mekanisme acara yang sangat sederhana. Komponen itu sendiri dapat mengirim acara ke entitas, yang disiarkan ke semua komponen.
Komponen pada dasarnya adalah sesuatu yang memberikan GameObject properti tertentu, dan karena GameObject sebenarnya hanya sebuah wadah dari mereka, segala sesuatu yang berkaitan dengan objek permainan terjadi di Komponen. Contohnya termasuk ViewComponent, PhysicsComponent dan LogicComponent. Jika komunikasi di antara mereka diperlukan, itu bisa dilakukan melalui penggunaan acara.
ComponentManager hanya antarmuka seperti Component, dan untuk setiap kelas Component, umumnya harus ada satu kelas ComponentManager. Manajer komponen ini bertanggung jawab untuk membuat komponen dan menginisialisasi komponen tersebut dengan properti yang dibaca dari sesuatu seperti file XML.
ComponentManager juga menangani pembaruan komponen secara massal, seperti PhysicsComponent di mana saya akan menggunakan perpustakaan eksternal (yang melakukan semuanya di dunia sekaligus).
Untuk konfigurasi, saya akan menggunakan pabrik untuk entitas yang akan membaca file XML atau skrip, membuat komponen yang ditentukan dalam file (yang juga menambahkan referensi ke dalamnya di manajer komponen yang tepat untuk pembaruan massal), dan lalu menyuntikkannya ke objek GameObject.
Sekarang masalah saya: Saya akan mencoba menggunakan ini untuk game multi-pemain. Saya tidak tahu bagaimana mendekati ini.
Pertama: Entitas apa yang harus dimiliki klien sejak awal? Saya harus mulai dengan menjelaskan bagaimana mesin pemain tunggal akan menentukan entitas apa yang akan dibuat.
Di editor tingkat Anda dapat membuat "kuas" dan "entitas". Kuas untuk hal-hal seperti dinding, lantai dan langit-langit, pada dasarnya bentuk sederhana. Entitas adalah GameObject yang telah saya ceritakan. Saat membuat entitas di editor level, Anda dapat menentukan properti untuk masing-masing komponen itu. Properti ini diteruskan langsung ke sesuatu seperti konstruktor dalam skrip entitas.
Ketika Anda menyimpan level untuk memuat mesin, itu didekomposisi menjadi daftar entitas dan properti terkait. Kuas diubah menjadi entitas "worldspawn".
Ketika Anda memuat level itu, itu hanya instanciates semua entitas. Kedengarannya sederhana, eh?
Sekarang, untuk jaringan entitas saya mengalami banyak masalah. Pertama, entitas apa yang harus ada pada klien dari awal? Dengan asumsi bahwa baik server dan klien memiliki file level, klien mungkin juga dapat mem-instanci semua entitas di level tersebut, bahkan jika mereka ada di sana hanya untuk keperluan aturan permainan di server.
Kemungkinan lain adalah bahwa klien membuat entitas segera setelah server mengirim informasi tentangnya, dan itu berarti bahwa klien hanya akan memiliki entitas yang dibutuhkan.
Masalah lain adalah bagaimana mengirim informasi. Saya pikir server dapat menggunakan delta-kompresi, artinya hanya mengirim informasi baru ketika sesuatu berubah, daripada mengirim snapshot ke klien di setiap frame. Padahal itu berarti server harus melacak apa yang diketahui setiap klien saat ini.
Dan akhirnya, bagaimana jaringan disuntikkan ke mesin? Saya sedang memikirkan komponen, NetworkComponent, yang disuntikkan ke setiap entitas yang seharusnya jaringan. Tetapi bagaimana seharusnya komponen jaringan tahu variabel apa yang ada di jaringan, dan bagaimana mengaksesnya, dan akhirnya bagaimana komponen jaringan yang sesuai pada klien harus tahu cara mengubah variabel jaringan?
Saya mengalami masalah besar dalam mendekati ini. Saya akan sangat menghargai jika Anda membantu saya dalam perjalanan. Saya terbuka untuk tips tentang bagaimana meningkatkan desain sistem komponen juga, jadi jangan takut menyarankan itu.
sumber
Akan menulis komentar tetapi memutuskan ini mungkin informasi yang cukup untuk jawaban.
Pertama, +1 untuk pertanyaan yang ditulis dengan begitu baik dengan banyak detail untuk menilai jawabannya.
Untuk pemuatan data, saya ingin klien memuat dunia dari file dunia. Jika entitas Anda memiliki Id di dalamnya yang berasal dari file data maka saya juga akan memuatnya secara default sehingga sistem jaringan Anda bisa merujuk mereka untuk mengetahui objek mana yang dibicarakannya. Setiap orang yang memuat data awal yang sama harus berarti mereka semua memiliki Id yang sama untuk objek-objek tersebut.
Kedua, jangan membuat komponen NetworkComponent karena ini tidak akan melakukan apa-apa selain mereplikasi data dalam komponen lain yang ada (fisika, animasi dan sejenisnya adalah beberapa hal umum yang harus dikirim). Untuk menggunakan penamaan Anda sendiri, Anda mungkin ingin membuat NetworkComponentManager. Ini akan sedikit tidak aktif dari hubungan Component to ComponentManager lain yang Anda miliki tetapi ini dapat dipakai saat Anda memulai permainan jaringan dan memiliki semua jenis komponen yang memiliki aspek jaringan untuk mereka memberikan data mereka kepada manajer sehingga dapat mengemasnya dan kirimkan. Di sinilah fungsi Simpan / Muat Anda dapat digunakan jika Anda memiliki semacam mekanisme serialisasi / deserialisasi yang juga dapat Anda gunakan untuk mengemas data, seperti yang disebutkan,
Mengingat pertanyaan dan tingkat informasi Anda, saya pikir saya tidak perlu membahas lebih detail, tetapi jika ada yang tidak jelas, silakan kirim komentar dan saya akan memperbarui jawaban untuk mengatasinya.
Semoga ini membantu.
sumber