- ‘Caves of Qud’ sedang melakukan pembuktian konsep teknis untuk melepaskan ketergantungan lamanya pada Unity dan membangun serta mem-boot inti game di Godot, dengan target awal menjalankannya dalam mode ASCII+tile tanpa VFX atau UI modern
- Pekerjaan dibagi menjadi impor aset tile, porting assembly C# inti, dan penyusunan rig rendering serta input; file tile BMP lama dikonversi ke PNG lalu dimuat ke Godot
- 5.641 error pada build awal berkurang seiring pemindahan GeneratedCode, ConsoleLib, Genkit, Language, HistoryKit, Newtonsoft JSON, CodeDom, dan lainnya, sementara permukaan dependensi UnityEngine dipersempit lewat stub
- Titik penggunaan Unity untuk Color, GameObject, AudioSource, Debug.Log, dan Screen ditangani dengan UnityEngineReplacer serta kelas pengganti, sementara lapisan chargen dan presentasi yang dekat dengan PlayFab serta Unity UI untuk sementara dihapus atau dibiarkan sebagai kandidat pemisahan ke modul glue
- Hasilnya, sekitar 500 ribu baris inti game C# kini berhasil boot di Godot, menghasilkan frame dan menunggu input, meski pekerjaan pada renderer, harness input, serta rigging VFX, suara, dan UI masih tersisa
Cakupan pekerjaan memindahkan dari Unity ke Godot
- Pekerjaan porting dibagi menjadi tiga jalur
- Impor aset: memasukkan aset tile ke dalam proyek Godot
- Porting assembly inti: memindahkan
XRL Application, yang merupakan engine game utama di luar Unity, sertaGameManagerdi sisi engine - Penyusunan rig rendering: menghubungkan output layar dan input setelah inti berhasil boot
- Dibuat proyek Godot “mobile” dan konten tekstur Qud disalin ke folder root proyek
- Karena Godot tidak bisa menangani file
.bmplama, file termasuk tile ASCII dikonversi massal ke PNG - Setelah konversi, aset berhasil dimuat, tetapi butuh sekitar 30 detik sampai indikator progres impor muncul
Memindahkan assembly inti sambil mengurangi error build
- Setelah menyalin
XRL Application, proyek dan solution C# dibuat di Godot, dan pada kondisi awal muncul 5.641 error - Library umum seperti
ConsoleLibdanGenkitdipindahkan secara utuh, sedangkan Kobold, solusi sprite dan atlasing lama, akan diimpor per file sambil diperiksa kebutuhannya KoboldJSONdipindahkan apa adanya karena merupakan library serialisasi JSON sederhana- Dengan penggantian global pada 85 titik penggunaan
Color, jumlah error turun menjadi 4.700 - Setelah menambahkan folder
GeneratedCodeyang sempat hilang, hasil code generation kelas per event ikut masuk dan jumlah error turun menjadi 1.557- Caves of Qud menggunakan struktur yang menghasilkan kode kelas per event dengan banyak boilerplate demi performa dan permukaan event bertipe kuat
Merapikan dependensi Unity dan lapisan glue
Embark Builderdan pembuatan karakter chargen memiliki banyak kode Unity UI, jadi dihapus dari pembuktian konsep ASCII awal- Versi console memang belum ada, tetapi verifikasi awal tetap bisa diuji lewat memuat save game atau memulai secara acak
- Folder
Gamesebagian besar merupakan glue antara Unity dan game, tetapi ada juga folder yang bukan glue sepertiCodeGeneration, sehingga dipilih arah memindahkannya ke root terpisah atau folderPlatform - Saat memindahkan library
LanguagedanHistoryKit, jumlah error turun menjadi 454, dan pemisahan game/glue yang sudah ada meski tidak sempurna sangat membantu - Kategori besar error yang tersisa adalah
CodeDom/Roslyn,PlayFab,Harmony, beberapa masalah terkait compiler, dan permukaan UnityEngine yang bocor ke lapisan game - Kode terkait
PlayFabuntuk sementara dikomentari dan dibiarkan sebagai kandidat untuk dinaikkan ke modul glue
Stub pengganti API Unity dan perbedaan C# di Godot
Color32adalah tipe warna berbasis byte, sehingga implementasi pengganti cepat dibuat- Dibuat folder
UnityEngineReplacer, dan tanpa mengacu ke dokumentasi atau kode Unity, hanya permukaan yang diperlukan yang diimplementasikan sambil mengikuti error kompilasi - Setelah membuat stub
GameObject, error “tidak mengenal GameObject” berubah menjadi error field dan method yang benar-benar dibutuhkan, sehingga permukaan antarmuka yang dipakai game bisa dipahami AudioSourcejuga ditangani dengan melihat daftar error dan menambahkan member yang diakses satu per satu, hingga antarmuka port AudioSource yang benar-benar digunakan game selesai dibuat- Permukaan lain yang ditangani meliputi:
- shim pengganti
Debug.Log - implementasi pengganti
Screen - porting library extension method
IsNullOrEmpty - penanganan referensi
Mathserta perbedaanPI/Pi - penanganan perbedaan nama koordinat huruf besar
X,Ydi Godot - perapian masalah
System.Drawing.ColordanSystem.Numerics.Vector3yang salah di-import oleh IDE
- shim pengganti
- Newtonsoft JSON diselesaikan dengan menambahkan paket NuGet di Visual Studio, dan CodeDom juga diselesaikan dengan paket NuGet
CodeDom
Sampai boot penuh di Godot
- Saat jumlah error turun menjadi 11, masalah yang tersisa adalah kode terkait kompilasi C# dinamis untuk mod management; tidak wajib, tetapi rumit sehingga tertinggal sampai akhir
- Setelah itu, tahap linking dan error field pada stub ditangani sehingga sekitar 500 ribu baris C# berhasil di-build
- Langkah berikutnya adalah membuat renderer kecil dan harness input untuk mem-boot assembly inti, dengan tujuan menjalankan game dalam mode ASCII+tile
- Di Godot dibuat scene kosong dan
GameManager.csditempelkan pada node dasar;GameManagermewarisiNodedan membutuhkan kode partial _Readydi Godot digunakan setara denganAwakedi Unity, dan_Processsetara denganUpdate- Selama inisialisasi, load path dan mod management dipindahkan, lalu masalah type resolver yang tidak bisa menemukan type berdasarkan nama dilacak dengan pendekatan printf
- Penyebabnya adalah penanganan dynamic assembly
- karena mod assembly bersifat dynamic, pemeriksaan main assembly mengecualikan dynamic assembly
- di editor Godot, main game assembly juga bersifat dynamic, sehingga ikut terlewat dari target pencarian type
- Setelah diperbaiki, boot penuh berhasil dilakukan, dan inti game 500kloc masuk ke keadaan menghasilkan frame sambil menunggu input
- Pekerjaan yang tersisa digambarkan sebagai “just work”, tetapi kenyataannya masih ada pekerjaan besar pada rigging VFX, suara, dan UI
1 komentar
Pendapat di Hacker News
Game ini tampaknya hampir sepenuhnya memakai engine buatan sendiri, sementara Unity hanya dipakai sebagai lapisan abstraksi hardware dan kerangka untuk porting, jadi dari sisi tingkat kesulitan porting ini terlihat mendekati skenario terbaik
Game seperti ini ternyata cukup banyak, meski tentu saja tidak mewakili sebagian besar judul Unity
Saya tidak tahu apakah setelah perombakan UI masih seperti itu, tetapi kalau iya, selalu terasa aneh bahwa mereka tidak menghemat biaya dengan mem-porting-nya ke MonoGame
Android juga mirip: sistem operasinya hanya dipakai untuk memanggil library pengganti hal-hal seperti deteksi kamera atau enkripsi, lalu suatu hari kita sadar bahwa sistem operasi itu pada dasarnya hanya lapisan logam tipis dan bootloader
https://nitter.net/unormal/status/1703163364229161236
Sialan Elon. Sekarang berurusan dengan Twitter benar-benar menyebalkan
Wah, keren sekali. Senang juga bisa melihat proses porting ini langkah demi langkah, dan mengejutkan karena waktu yang dibutuhkan cukup masuk akal
Kalau banyak sekali kode kustom dan strukturnya tidak terlalu memakai fitur editor, sepertinya bisa juga memakai library rendering alih-alih engine
Dengan engine sebagai fondasi, hal-hal seperti ini bisa didapatkan gratis. Kalau Unity, mungkin ada biayanya
Kalau penasaran bagaimana pendapat Brian, video ini bagus untuk ditonton: https://www.youtube.com/watch?v=U03XXzcThGU
Dulu saya banyak belajar dari sini
Ini mengingatkan saya pada kontroversi TypeScript DHH baru-baru ini
Bayangkan melakukan porting seperti ini tanpa static typing: setiap kali mengubah sesuatu harus build, menjalankan, dan mencari crash. Di saat seperti ini, kita benar-benar bersyukur sudah membangunnya dengan bahasa yang mudah di-refactor dan arsitektur yang baik
Saya tidak punya akun Twitter, jadi ada apa?