1 poin oleh GN⁺ 2023-09-18 | 1 komentar | Bagikan ke WhatsApp
  • ‘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, serta GameManager di 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 .bmp lama, 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 ConsoleLib dan Genkit dipindahkan secara utuh, sedangkan Kobold, solusi sprite dan atlasing lama, akan diimpor per file sambil diperiksa kebutuhannya
  • KoboldJSON dipindahkan 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 GeneratedCode yang 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 Builder dan 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 Game sebagian besar merupakan glue antara Unity dan game, tetapi ada juga folder yang bukan glue seperti CodeGeneration, sehingga dipilih arah memindahkannya ke root terpisah atau folder Platform
  • Saat memindahkan library Language dan HistoryKit, 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 PlayFab untuk sementara dikomentari dan dibiarkan sebagai kandidat untuk dinaikkan ke modul glue

Stub pengganti API Unity dan perbedaan C# di Godot

  • Color32 adalah 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
  • AudioSource juga 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 Math serta perbedaan PI/Pi
    • penanganan perbedaan nama koordinat huruf besar X, Y di Godot
    • perapian masalah System.Drawing.Color dan System.Numerics.Vector3 yang salah di-import oleh IDE
  • 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.cs ditempelkan pada node dasar; GameManager mewarisi Node dan membutuhkan kode partial
  • _Ready di Godot digunakan setara dengan Awake di Unity, dan _Process setara dengan Update
  • 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

 
GN⁺ 2023-09-18
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

    • Benar. Dalam sebuah wawancara, pernah dikatakan bahwa Qud saat itu berjalan di dalam Unity seperti aplikasi konsol
      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
    • Menurut saya hasil akhirnya adalah komponen bawaan Unity dalam jangka panjang hampir semuanya menjadi tidak berguna
      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

  • Wah, keren sekali. Senang juga bisa melihat proses porting ini langkah demi langkah, dan mengejutkan karena waktu yang dibutuhkan cukup masuk akal

    • Godot fiturnya jauh lebih sedikit, tetapi menurut saya benar-benar mudah dipelajari
    • Saya ingin melihat bagaimana mereka mewujudkan nuansa visual khas Caves of Qud di Godot
  • Kalau banyak sekali kode kustom dan strukturnya tidak terlalu memakai fitur editor, sepertinya bisa juga memakai library rendering alih-alih engine

    • Kalau ingin merilis game di beberapa platform sekaligus, mengurus sendiri kode rendering, suara, dan input per platform akan cepat terasa membosankan
      Dengan engine sebagai fondasi, hal-hal seperti ini bisa didapatkan gratis. Kalau Unity, mungkin ada biayanya
    • Mereka sudah memakai library rendering. Namanya “Unity”
  • 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?