Pengodean berbasis data
Setiap hal yang Anda sebutkan adalah sesuatu yang dapat ditentukan dalam data. Mengapa Anda memuat aspecificmap
? Karena konfigurasi gim mengatakan bahwa itu adalah level pertama ketika seorang pemain memulai gim baru, atau karena itulah nama titik penyimpanan saat ini dalam file penyimpanan pemain yang baru saja mereka muat, dll.
Bagaimana Anda menemukan aspecificmap
? Karena ada dalam file data yang mencantumkan id peta dan sumber daya pada-disk mereka.
Hanya perlu ada satu set kecil sumber daya "inti" yang secara sah sulit atau tidak mungkin untuk menghindari hard-coding. Dengan sedikit kerja, ini dapat dibatasi untuk satu nama aset default seperti main.wad
atau sejenisnya. File ini berpotensi dapat diubah saat runtime dengan meneruskan argumen baris perintah ke gim, alias game.exe -wad mymain.wad
.
Menulis kode berbasis data bergantung pada beberapa prinsip lain. Sebagai contoh, seseorang dapat menghindari sistem atau modul meminta sumber daya tertentu dan sebaliknya membalikkan dependensi tersebut. Artinya, jangan membuat DebugDrawer
memuat debug.font
dalam kode inisialisasi; sebagai gantinya, telah DebugDrawer
mengambil pegangan sumber daya dalam kode inisialisasi. Pegangan itu mungkin diambil dari file konfigurasi game utama.
Sebagai contoh nyata dari basis kode kami, kami memiliki objek "data global" yang diambil dari basis data sumber daya (yang secara default ./resources
folder itu tetapi dapat dibebani dengan argumen baris perintah). ID databse sumber daya dari data global ini adalah satu-satunya nama sumber daya hard-coded yang diperlukan dalam basis kode (kami memiliki yang lain karena kadang-kadang programmer merasa malas, tetapi pada akhirnya kami pada akhirnya memperbaiki / menghapusnya). Objek data global ini penuh dengan komponen yang tujuan utamanya adalah untuk menyediakan data konfigurasi. Salah satu komponen adalah komponen Data Global UI yang berisi sumber daya menangani semua sumber daya UI utama (font, file Flash, ikon, data pelokalan, dll.) Di antara sejumlah item konfigurasi lainnya. Ketika pengembang UI memutuskan untuk mengubah nama aset UI utama dari /ui/mainmenu.swf
menjadi/ui/lobby.swf
mereka hanya memperbarui referensi data global itu; tidak ada kode mesin yang perlu diubah sama sekali.
Kami menggunakan data global ini untuk semuanya. Semua karakter yang dapat dimainkan, semua level, UI, audio, aset inti, konfigurasi jaringan, semuanya. (yah, tidak semuanya , tetapi hal-hal lain itu adalah bug yang harus diperbaiki.)
Pendekatan ini memiliki banyak keunggulan lain. Untuk satu, itu membuat pengemasan sumber daya dan bundling menjadi bagian integral dari keseluruhan proses. Jalur hard-coding dalam mesin juga cenderung berarti bahwa jalur yang sama harus dikodekan dalam skrip atau alat apa pun yang mengemas aset game, dan jalur tersebut kemudian dapat keluar dari sinkronisasi. Mengandalkan pada aset inti tunggal dan rantai referensi dari sana, kita dapat membangun bundel aset dengan perintah tunggal seperti bundle.exe -root config.data -out main.wad
dan tahu bahwa itu akan mencakup semua aset yang kita butuhkan. Lebih lanjut, karena bundler hanya akan mengikuti referensi sumber daya, kami tahu bahwa itu hanya akan mencakup aset yang kami butuhkan dan lewati semua sisa bulu yang tak terelakkan terakumulasi selama masa proyek (ditambah kita dapat secara otomatis menghasilkan daftar yang bulu untuk pemangkasan).
Kasus sudut rumit dari semua ini ada di skrip. Membuat engine-driven data mudah secara konseptual, tetapi saya telah melihat begitu banyak proyek (hobi untuk AAA) di mana skrip dianggap data dan karenanya "diizinkan" untuk hanya menggunakan jalur sumber daya tanpa pandang bulu. Jangan lakukan itu. Jika file Lua membutuhkan sumber daya dan itu hanya memanggil fungsi seperti textures.lua("/path/to/texture.png")
maka pipa aset akan mengalami banyak kesulitan mengetahui bahwa skrip membutuhkan /path/to/texture.png
untuk beroperasi dengan benar dan mungkin menganggap tekstur itu tidak digunakan dan tidak perlu. Skrip harus diperlakukan seperti kode lain: data apa pun yang mereka butuhkan termasuk sumber daya atau tabel harus ditentukan dalam entri konfigurasi yang dapat diperiksa oleh mesin dan sumber daya pipa untuk dependensi. Data yang mengatakan "muat skrip foo.lua
" seharusnya mengatakan "foo.lua
dan berikan parameter ini "di mana parameter menyertakan sumber daya yang diperlukan. Jika skrip secara acak memunculkan musuh misalnya, masukkan daftar musuh yang mungkin ke dalam skrip dari file konfigurasi tersebut. Mesin kemudian dapat memuat musuh sebelumnya dengan level ( karena ia mengetahui daftar lengkap dari kemungkinan spawns) dan pipa sumber daya tahu untuk menggabungkan semua musuh dengan game (karena mereka secara definitif dirujuk oleh data konfigurasi). Jika skrip menghasilkan string nama path dan hanya memanggil load
fungsi maka tidak ada mesin atau pipa sumber daya memiliki cara untuk mengetahui secara spesifik aset mana yang mungkin dicoba dimuat oleh skrip.
Cara yang sama Anda menghindari hardcoding pada fungsi umum.
Anda melewatkan parameter dan menyimpan informasi Anda dalam file konfigurasi.
Dalam situasi itu, sama sekali tidak ada perbedaan dalam rekayasa perangkat lunak antara menulis mesin dan menulis kelas.
Kemudian kode klien Anda membaca file konfigurasi "master" (yang ini baik kode atau dilewatkan sebagai argumen baris perintah) yang berisi informasi yang memberitahu di mana file aset dan peta apa yang dikandungnya.
Dari sana, semuanya didorong oleh file konfigurasi "master".
sumber
Saya suka jawaban yang lain jadi saya akan sedikit bertolak belakang. ;)
Anda tidak dapat menghindari pengkodean pengetahuan tentang data Anda ke mesin Anda. Dari mana pun informasi itu berasal, mesin harus tahu untuk mencarinya. Namun, Anda dapat menghindari penyandian informasi aktual itu sendiri ke mesin Anda.
Pendekatan berbasis data "murni" akan membuat Anda memulai yang dapat dieksekusi dengan parameter baris perintah yang diperlukan untuk memuat konfigurasi awal tetapi mesin harus diberi kode untuk mengetahui bagaimana menafsirkan informasi itu. Misalnya jika file konfigurasi Anda JSON, Anda perlu kode keras variabel Anda mencari, misalnya mesin harus tahu untuk mencari
"intro_movies"
dan"level_list"
dan sebagainya.Namun, mesin "dibangun dengan baik" dapat bekerja untuk banyak game yang berbeda hanya dengan menukar data konfigurasi dan data yang dirujuk.
Jadi mantra ini tidak terlalu banyak untuk menghindari pengkodean yang sulit karena itu untuk memastikan bahwa Anda dapat membuat perubahan dengan jumlah usaha seminimal mungkin.
Berbeda dengan pendekatan file data (yang saya dukung dengan sepenuh hati), mungkin Anda baik-baik saja mengompilasi data ke dalam mesin Anda. Jika "biaya" untuk melakukannya lebih rendah, maka tidak ada salahnya; jika Anda satu-satunya yang mengerjakannya, maka Anda dapat menunda penanganan file di kemudian hari dan tidak harus menipu diri sendiri. Beberapa proyek gim pertamaku memiliki tabel besar data yang di-hardcode ke dalam gim itu sendiri, misalnya daftar senjata dan berbagai macam data mereka:
Jadi Anda meletakkan data ini di suatu tempat yang mudah dirujuk dan mudah diedit seperlunya. Yang ideal adalah untuk meletakkan barang-barang ini ke dalam file konfigurasi, tetapi kemudian Anda perlu melakukan parsing dan terjemahan dan semua jazz itu, ditambah dengan menghubungkan referensi antar-struktur mungkin menjadi rasa sakit tambahan yang Anda benar-benar tidak ingin melakukannya. berurusan dengan.
sumber