Cara mengelola perubahan data desainer bersamaan dengan mengubah data pemain

14

Saya memiliki permainan online di mana para pemain bisa membentuk dunia dengan beberapa cara - misalnya. Perumahan Ultima Online, tempat Anda dapat membangun rumah langsung ke bagian-bagian tertentu dari peta dunia. Ini adalah perubahan yang harus bertahan seiring waktu sebagai bagian dari dunia yang gigih.

Pada saat yang sama, tim desain menambahkan konten baru dan mengubah konten lama untuk meningkatkan dan memperluas permainan untuk pemain baru. Mereka akan melakukan ini pada server pengembangan terlebih dahulu selama pengujian dan kemudian harus menggabungkan pekerjaan mereka dengan "pekerjaan" para pemain di server langsung.

Dengan asumsi kami memperbaiki masalah desain game - mis. pemain hanya bisa membangun di area yang ditentukan, sehingga mereka tidak pernah berbenturan secara geografis dengan hasil edit desainer - apa cara yang baik untuk menangani data atau mengatur struktur data sehingga untuk menghindari konflik ketika data desainer baru digabungkan dengan data pemain baru?

Contoh 1: pemain membuat item jenis baru, dan gim tersebut memberikan ID 123456 untuknya. Contoh item itu semua merujuk kembali ke 123456. Sekarang bayangkan desainer game memiliki sistem yang sama, dan seorang desainer membuat item baru juga bernomor 123456. Bagaimana ini bisa dihindari?

Contoh 2: seseorang membuat mod populer yang memberi semua naga Anda aksen Prancis. Ini termasuk skrip dengan objek baru yang disebut assignFrenchAccentyang mereka gunakan untuk menetapkan aset suara baru untuk setiap objek naga. Tetapi Anda akan menggunakan DLC "Napoleon vs Smaug" Anda yang memiliki objek dengan nama yang sama - bagaimana Anda dapat melakukan ini tanpa banyak masalah layanan pelanggan?

Saya telah memikirkan strategi berikut:

  • Anda dapat menggunakan 2 file / direktori / basis data terpisah, tetapi kemudian operasi membaca Anda sangat rumit. "Show All Items" harus melakukan satu pembacaan pada DB desainer dan satu membaca pada DB pemain (dan masih harus membedakan antara 2, entah bagaimana.)
  • Anda dapat menggunakan 2 ruang nama yang berbeda dalam satu toko, mis. menggunakan string sebagai kunci utama dan mengawali mereka dengan "DESIGN:" atau "PLAYER:", tetapi membuat ruang nama tersebut mungkin non-sepele dan ketergantungan tidak jelas. (mis. Dalam RDBMS Anda mungkin tidak dapat menggunakan string secara efisien sebagai kunci primer. Anda dapat menggunakan bilangan bulat dan mengalokasikan semua kunci utama di bawah angka tertentu, misalnya 1 juta, sebagai data perancang, dan segala sesuatu di atas titik itu menjadi data pemain. Tetapi info itu tidak terlihat oleh RDBMS dan tautan kunci asing akan melewati 'bagi', artinya semua perkakas dan skrip perlu secara eksplisit mengatasinya.)
  • Anda selalu dapat bekerja pada database bersama yang sama secara waktu nyata, tetapi kinerjanya mungkin buruk dan risiko kerusakan pada data pemain dapat ditingkatkan. Itu juga tidak mencakup game yang berjalan di lebih dari 1 server dengan data dunia yang berbeda.
  • ... Ada ide lain?

Terpikir oleh saya bahwa meskipun ini terutama merupakan masalah untuk game online, konsepnya mungkin berlaku untuk modding juga, di mana komunitas membuat mod pada saat yang sama ketika pengembang menambal game mereka. Apakah ada strategi yang digunakan di sini untuk mengurangi kemungkinan putus mod ketika tambalan baru keluar?

Saya juga menandai ini sebagai "kontrol versi" karena pada satu tingkat itulah yang terjadi - 2 cabang pengembangan data yang perlu digabung. Mungkin beberapa wawasan mungkin datang dari arah itu.

EDIT - beberapa contoh ditambahkan di atas untuk membantu memperjelas masalah. Saya mulai berpikir masalah ini benar-benar salah satu dari namespacing, yang dapat diimplementasikan di toko melalui kunci komposit. Itu menyederhanakan strategi penggabungan, setidaknya. Tetapi mungkin ada alternatif yang tidak saya lihat.

Kylotan
sumber
1
Saya membayangkan jawaban untuk ini bisa tergantung setidaknya sebagian pada tipe data apa yang ditambahkan oleh desainer dan apa yang ditambahkan oleh para pemain.
lathomas64
Bisa, tapi saya lebih tertarik pada solusi umum untuk 2 pihak yang berkontribusi pada satu penyimpanan data.
Kylotan
1
Banyak orang kehilangan titik pertanyaan ini - bukan perubahan pemain yang bertentangan: melainkan pembaruan konten dll. Melanggar tata letak yang ada. @ Kandyl apakah saya benar?
Jonathan Dickinson
Di sinilah pembaruan konten pengembang berpotensi berbenturan dengan pembaruan konten pemain. Saya tidak terlalu tertarik dengan solusi desain game (mis. Hanya membiarkan pemain membangun di tempat tertentu) tetapi dalam solusi struktur data (mis. Hanya membiarkan pemain membuat sesuatu dengan ID lebih dari 1 juta).
Kylotan
2
Anda tidak menentukan, apakah Anda mengharapkan untuk melakukan pembaruan langsung ke dunia nyata? Catatan tambahan: 2 pihak yang berkontribusi pada penyimpanan data tunggal ADALAH basis data, itulah yang dilakukan basis data, Anda tidak dapat menyiasati fakta itu dan akan bodoh mengabaikan dekade pengetahuan tentang cara menghindari masalah dengan data bersama.
Patrick Hughes

Jawaban:

2

Saya pikir jawaban yang mengusulkan solusi DB melompat ke implementasi spesifik tanpa memahami masalahnya. Database tidak membuat penggabungan menjadi mudah, mereka hanya memberi Anda kerangka kerja untuk menyimpan data Anda. Konflik masih merupakan konflik meskipun dalam DB. Dan memeriksa adalah solusi orang miskin untuk masalah - itu akan berhasil, tetapi dengan biaya yang melumpuhkan bagi kegunaan Anda.

Apa yang Anda bicarakan di sini termasuk dalam model pengembangan masalah yang didistribusikan. Langkah pertama yang saya yakini adalah tidak menganggap pemain dan desainer sebagai tipe pembuat konten yang terpisah. Itu menghilangkan dimensi buatan untuk masalah Anda yang tidak mempengaruhi solusi.

Secara efektif Anda memiliki jalur utama Anda - versi kanonik, yang disetujui pengembang. Anda mungkin (mungkin) juga memiliki cabang lain - server langsung adalah orang-orang secara aktif mengembangkan dan berbagi mod. Konten dapat ditambahkan di cabang mana pun. Yang terpenting, desainer Anda tidak ada yang istimewa di sini - mereka hanya pembuat konten yang kebetulan tinggal di rumah (dan Anda dapat menemukan mereka dan menabrak mereka ketika mereka gagal).

Kemudian menerima konten yang dibuat pengguna adalah masalah penggabungan standar. Anda harus menarik perubahannya kembali ke jalur utama, menggabungkan, lalu mendorong keluar lagi, atau menarik perubahan jalur utama ke cabang mereka dan menggabungkan (membiarkan jalur utama 'bersih' dari barang yang dibuat pengguna). Seperti biasa, menarik ke cabang Anda dan memperbaikinya di sana lebih ramah daripada meminta orang lain untuk menarik perubahan Anda dan kemudian mencoba memperbaikinya dari jarak jauh.

Setelah Anda bekerja dengan model semacam itu, semua proses normal tentang menghindari konflik gabungan berlaku. Beberapa yang lebih jelas:

  • Dorong penggunaan liberal ruang nama untuk memagari konten dari penulis / mod / tim tertentu.
  • Di mana konten perlu berinteraksi, buat konvensi panggilan / penggunaan yang jelas, konvensi penamaan, dan 'aturan' longgar lainnya yang memandu pengembangan sehingga mudah untuk digabungkan kembali. Menyediakan alat yang memungkinkan pembuat konten untuk mengetahui apakah mereka mengikuti aturan-aturan itu, idealnya diintegrasikan ke dalam pembuatan konten itu sendiri.
  • Sediakan alat pelaporan / analisis untuk mengenali kemungkinan penggabungan kegagalan sebelum terjadi. Memperbaikinya setelah penggabungan mungkin sangat menyakitkan. Buat sedemikian sehingga sedikit konten tertentu dapat diperiksa dan diberi semua jelas sebagai siap-gabung, sehingga penggabungan tidak menimbulkan rasa sakit
  • Buat penggabungan / integrasi Anda menjadi kuat. Izinkan pengembalian uang mudah. Lakukan pengujian ketat terhadap konten yang digabungkan: jika gagal pengujian, jangan gabungkan! Iterasi konten mereka atau konten Anda hingga penggabungan berlangsung dengan bersih.
  • Hindari menggunakan ID integer tambahan untuk apa pun (Anda tidak memiliki cara yang dapat diandalkan untuk membagikannya kepada pembuat). Itu hanya berfungsi dalam DB karena DB itu sendiri adalah penyedia ID kanonik sehingga Anda tidak pernah mendapatkan duplikat; namun itu juga memperkenalkan satu titik kegagalan / beban dalam sistem Anda.
  • Alih-alih menggunakan GUID - harganya lebih mahal untuk disimpan, tetapi khusus untuk mesin dan karenanya tidak akan menyebabkan tabrakan. Atau gunakan pengenal string, ini jauh lebih mudah untuk debug / penyelesaian, tetapi lebih mahal untuk penyimpanan dan perbandingan.
MrCranky
sumber
Sayangnya beberapa dari ini tidak membantu untuk masalah saya (mis. Memiliki pemain mengikuti aturan tertentu, karena ini semua harus dilakukan secara otomatis di sisi server) dan saya tidak berpikir itu akan praktis untuk mendukung tingkat manajemen gabungan dan transaksional semantik yang Anda sebutkan, tetapi pendekatan umum mengalokasikan ID unik yang dijamin, mungkin GUID, mungkin paling dekat dengan yang akan saya gunakan.
Kylotan
Ah, begitu. Yah karena Anda mengontrol alat bangunan mereka, setidaknya menegakkan pendekatan ramah gabungan (ruang nama, dll.) Adalah sesuatu yang dapat Anda lakukan tanpa pemain harus setuju.
MrCranky
Apa yang Anda lakukan jika dua pemain membuat konten duplikat? Atau apakah kejadian terpisah dari gameworld Anda diperlakukan unik? Dalam hal ini mungkin ini merupakan pendekatan yang bermanfaat untuk secara otomatis memeriksa setiap instance unik yang Anda tahu bertentangan dengan inti / cabang utama Anda untuk konflik yang akan terjadi ketika Anda mendorong perubahan tersebut ke instance. Jika Anda tidak bisa mengendalikan para pemain, Anda setidaknya bisa memperingatkan tim internal Anda bahwa pekerjaan yang mereka lakukan bertentangan dengan instance X dunia, sejak awal dalam pengembangan.
MrCranky
Konsep ruang nama bukanlah masalah - memilih ruang nama yang memadai dari ruang nama dari semua ruang nama yang mungkin adalah! :) Dan duplikat konten untuk saya bukan masalah - itu hanya 2 contoh dari sesuatu yang setara. Yang penting adalah tidak ada merger atau overwrite yang merusak. Adapun pemeriksaan tabrakan otomatis, yang menghentikan kerusakan yang dilakukan dalam penulisan, tetapi tidak menyelesaikan masalah penamaan asli. (Mengganti nama hal-hal untuk menghindari tabrakan mungkin tidak sepele, karena referensi silang.)
Kylotan
Ah ya, saya mengerti sekarang, bukan ruang nama itu sendiri melainkan pilihan nama. Dalam hal ini, GUID mungkin jawabannya lagi - buat konten secara efektif disimpan di area kecilnya sendiri. Nama dekoratif dapat diberikan, tetapi game akan menggunakan GUID.
MrCranky
1

Simpan semuanya sebagai atribut (atau dekorator) - dengan titik pemasangan. Mari kita ambil rumah yang telah dirancang pemain sebagai contoh:

o House: { Type = 105 } // Simple square cottage.
 o Mount point: South Wall:
  o Doodad: Chair { Displacement = 10cm }
   o Mount point: Seat:
    o Doodad: Pot Plant { Displacement = 0cm, Flower = Posies } // Work with me here :)
 o Mount point: North Wall:
  o Doodad: Table { Displacement = 1m }
    o Mount point: Left Edge:
     o Doodad: Food Bowl { Displacement = 20cm, Food = Meatballs}

Jadi setiap entitas dapat memiliki satu atau lebih titik pemasangan - setiap titik pemasangan dapat menerima nol atau lebih komponen lainnya. Data ini akan disimpan bersama versi yang disimpan di, bersama dengan setiap properti yang relevan (seperti Pemindahan dll dalam contoh saya) - NoSQL kemungkinan akan membuat kesesuaian yang sangat bagus di sini (Kunci = ID Entitas, Nilai = Biner Serialized Binary Data).

Setiap komponen kemudian harus dapat 'memutakhirkan' data lama dari versi sebelumnya (jangan pernah menghapus bidang dari data bersambung - hanya 'null' mereka) - pemutakhiran ini terjadi pada saat itu dimuat (kemudian akan segera disimpan kembali dalam versi terbaru tersedia). Katakanlah rumah kita sudah dimensinya berubah. Kode peningkatan relatif akan menentukan jarak antara tembok utara dan selatan dan secara proporsional mengubah perpindahan semua entitas yang ada. Sebagai contoh lain mangkuk daging kita mungkin memiliki bidang 'Makanan' dihapus, dan bukannya mendapatkan 'Variety' (Daging) dan 'Resep' (Balls). Skrip pemutakhiran akan mengubah 'Meat Balls' menjadi 'Meat', 'Balls'. Setiap komponen juga harus tahu bagaimana menghadapi perubahan untuk me-mount poin - mis

Ini semua meninggalkan satu masalah terbuka: apa yang terjadi jika dua objek saling bentrok (bukan wadahnya - titik pemasangan melindungi Anda dari itu)? Setelah peningkatan, Anda harus memeriksa tabrakan dan mencoba menyelesaikannya (dengan memisahkan, sedikit seperti SAT). Jika Anda tidak dapat menemukan cara untuk menyelesaikan tabrakan, lepaskan salah satu objek dan letakkan di simpanan - tempat mereka dapat membeli item yang dihapus ini (gratis) atau menjualnya (dengan harga penuh); dan jelas memberi tahu pemain bahwa pemutakhiran merusak sebagian tata letak mereka - mungkin dengan fitur 'perbesar' sehingga mereka dapat melihat masalahnya.

Pada akhirnya Anda harus meninggalkan perubahan kompleks di tangan para pemain (gagal dengan cepat) karena tidak ada algoritma yang dapat menjelaskan estetika - Anda seharusnya hanya dapat memberikan konteks kepada pemain tentang di mana item itu digunakan (sehingga mereka dapat mengingat, bukan hanya mendarat dengan semua barang-barang ini di simpanan mereka dan tidak tahu di mana mereka berada).

Jonathan Dickinson
sumber
Ini difokuskan agak terlalu sempit pada penentuan posisi objek, yang sebenarnya bukan masalah utama yang saya coba selesaikan. Ini lebih tentang memiliki pengidentifikasi unik dalam set data bersamaan dan perlu untuk dapat menggabungkan mereka tanpa kemungkinan risiko konflik. Saya menambahkan 2 contoh ke posting saya beberapa hari yang lalu untuk mencoba dan menjelaskan sedikit lebih jauh.
Kylotan
1

Saya mencoba mengaitkan ini dengan sesuatu yang saya mengerti, jadi saya berpikir dalam hal Minecraft sekarang. Saya membayangkan server langsung dengan pemain membuat perubahan secara real-time saat pengembang menjalankan server uji memperbaiki / membuat konten baru.

Pertanyaan Anda hampir seperti 2 pertanyaan unik:

  1. Cara memastikan bahwa ID objek unik
  2. Bagaimana memastikan bahwa ruang nama skrip tidak bertabrakan

Saya akan mencoba memecahkan # 1 melalui sistem referensi sementara. Misalnya, ketika objek baru dibuat oleh seseorang, itu bisa ditandai sebagai volatile atau sementara. Saya akan membayangkan bahwa semua konten baru yang dibuat pada server uji akan ditandai volatil (meskipun mungkin juga referensi konten yang tidak mudah menguap).

Saat Anda siap untuk membawa konten baru ke server langsung, proses impor Anda akan menemukan objek yang mudah menguap dan menetapkan mereka ID objek server hidup yang diatur dalam batu. Ini berbeda dari impor langsung / gabungan karena Anda harus dapat mereferensi objek non-volatil yang ada jika Anda harus memperbaiki atau memperbaruinya.

Untuk # 2, tampaknya Anda benar-benar perlu memiliki beberapa level transmutasi skrip menengah yang dapat mengaitkan nama fungsi ke namespace yang unik. yaitu

assignFrenchAccent

Menjadi

_Z11assignFrenchAccent
Kesalahan 454
sumber
0

Jika file untuk data adalah teks dan bukan biner dan desainer dan pemain memodifikasi area yang berbeda, Anda bisa mencoba gabungan SVN.

lathomas64
sumber
0

Saya pikir database / filesystem direplikasi di lingkungan dengan prosedur 'check-out' akan lebih baik.

Jadi, setiap kali seorang desainer ingin membuat beberapa modifikasi ke dunia, ia akan check-out / mengunci semua aset yang ingin ia buat / modifikasi pada semua salinan database (pengembangan dan produksi), sehingga tidak ada pemain atau desainer lain yang bisa memodifikasinya. . Dia kemudian akan bekerja pada database pengembangan sampai desain baru selesai, dan pada saat itu perubahan akan digabungkan dengan database produksi dan aset-aset itu akan check-in / dibuka di semua lingkungan.

Pengeditan pemain akan bekerja dengan cara yang sama, kecuali peran basis data / sistem file akan terbalik - mereka bekerja pada basis data produksi, dan semua pembaruan diunggah ke dev ketika selesai.

Penguncian aset dapat dibatasi pada properti di mana Anda ingin menjamin tidak ada konflik: dalam Contoh 1, Anda akan mengunci ID 123456segera setelah pemain mulai menyusunnya, sehingga pengembang tidak akan diberi ID itu. Dalam Contoh 2, pengembang Anda akan mengunci nama skrip assignFrenchAccentselama pengembangan, sehingga pemain harus memilih nama yang berbeda ketika mengembangkan modifikasinya (gangguan kecil dapat dikurangi dengan penempatan nama, tetapi dengan sendirinya tidak akan menghindari konflik kecuali Anda memberikan masing-masing pengguna / pengembang namespace tertentu, dan kemudian Anda akan memiliki masalah yang sama dengan mengelola ruang nama). Ini berarti bahwa semua pengembangan harus membaca dari satu database on-line, tetapi semua yang Anda butuhkan dari database itu dalam contoh-contoh ini adalah nama-nama objek, jadi kinerja seharusnya tidak menjadi masalah.

Dalam hal implementasi, memiliki satu tabel dengan semua kunci dan status aset (tersedia, dikunci dari dev, dikunci dari prod) disinkronkan / dapat diakses secara real-time di seluruh lingkungan harus cukup. Solusi yang lebih kompleks akan menerapkan sistem Kontrol Versi yang lengkap - Anda dapat menggunakan sistem yang ada seperti CVS atau SVN jika aset Anda semuanya ada dalam sistem file.

SkimFlux
sumber
Biasanya tidak praktis untuk mengunci data apa pun secara global - pemain mungkin mengedit dunia hanya melalui permainan normal, dan Anda tidak ingin permainan itu menghentikan desainer agar dapat bekerja. Jika Anda mengizinkan kunci global, maka operasi penggabungan pada dasarnya adalah operasi overwrite, yang mudah - tetapi jika Anda tidak memiliki kunci global, lalu bagaimana?
Kylotan
Seperti yang disebutkan lathomas64, jawabannya akan tergantung pada jenis data apa yang Anda bicarakan. Tanpa kunci global, saya pikir Anda harus memiliki sistem versi dan seperangkat aturan untuk menyelesaikan konflik - aturan ini akan tergantung pada data dan persyaratan gameplay. Setelah Anda memilikinya, saya kira setiap gabungan dikurangi menjadi operasi timpa sederhana.
SkimFlux
0

Saya pikir intinya di sini adalah menerima tanggung jawab Anda dengan bersih. 1) Server mengatakan apa yang saat ini dapat diterima, dan API untuk mengakses. Basis data sedang dimodifikasi, sesuai dengan aturan tertentu. 2) Pembuat diizinkan untuk membuat konten, tetapi harus dapat diputar setelah pembaruan. Ini murni tanggung jawab Anda: pembaruan apa pun harus dapat menguraikan struktur data lama, sebaiknya sebersih dan semudah mungkin.

Ide mount point memiliki kelebihan jika Anda tertarik untuk melacak item dan posisi unik di dalam struktur yang dapat ditempa, terutama jika kami menerima bahwa seluruh struktur 'rumah' seorang pemain akan mengalami perubahan dramatis, dan Anda ingin mempertahankannya barang deco kecil di loker masing-masing.

Ini masalah yang sangat rumit, semoga berhasil! Mungkin tidak ada satu jawaban pun.

karmington
sumber
0

Saya tidak berpikir ini memiliki masalah besar saat Anda membuatnya.

Saya hanya akan menimpa mod yang dibuat pengguna, dengan peringatan yang menyatakan bahwa "Mod X mungkin tidak bekerja dengan benar dengan versi ini", serahkan kepada pembuat mod untuk mengubah pekerjaan mereka. Saya tidak berpikir ini adalah harapan yang tidak realistis bahwa pembaruan dapat menonaktifkan mod tertentu.

Sama untuk konten yang dibuat pengguna, cukup buat cadangan, dan timpa.

Saya tidak punya pengalaman sebenarnya dalam hal ini, hanya membuat saran.

Woody Zantzinger
sumber
Saya pikir jika itu murni untuk mod yang disediakan pengguna, maka Anda akan benar. Tetapi beberapa game secara eksplisit tentang konten yang dibuat pengguna, jadi Anda tidak bisa menghancurkannya begitu saja.
Kylotan
Kemudian tinggalkan ruang di sistem untuk konten yang mungkin Anda tambahkan nanti. Jika Anda menggunakan nomor ID, pesan 1-1000. Atau jika pengguna dapat memberi nama aset mereka, jangan biarkan pengguna memulai nama dengan "FINAL-" atau sesuatu (cadangan untuk aset Anda sendiri). SUNTING: atau lebih baik lagi, lakukan secara terbalik, memaksa konten pengguna ke dalam rentang atau awalan
Woody Zantzinger