- ‘Caves of Qud’ ने अपनी लंबे समय से चली आ रही Unity dependency हटाकर Godot में game core को build और boot करने का technical validation किया है; शुरुआती लक्ष्य आधुनिक VFX या UI के बिना ASCII+tile mode में चलाना है
- काम को tile assets import करने, core C# assemblies port करने, और rendering/input rig तैयार करने में बांटा गया; पुराने BMP tile files को PNG में convert करके Godot में load किया गया
- शुरुआती build की 5,641 errors GeneratedCode, ConsoleLib, Genkit, Language, HistoryKit, Newtonsoft JSON, CodeDom आदि को स्थानांतरित करते हुए कम हुईं, और UnityEngine dependency surface को stubs से सीमित किया गया
- Unity के Color, GameObject, AudioSource, Debug.Log, Screen उपयोग वाले हिस्सों को UnityEngineReplacer और alternative classes से handle किया गया; PlayFab और Unity UI के करीब chargen/presentation layers को अस्थायी रूप से हटाया गया या glue modules में अलग करने के candidates के रूप में छोड़ा गया
- नतीजे में लगभग 5 लाख लाइनों का C# game core Godot में boot होकर frames supply करने और input का इंतज़ार करने की अवस्था तक पहुंच गया, लेकिन renderer/input harness और VFX/sound/UI rigging का काम अभी बाकी है
Unity से Godot में ले जाने का कामकाजी scope
- porting का काम तीन हिस्सों में बंटा
- assets import करना: tile assets को Godot project में डालना
- core assembly port करना: Unity नहीं, बल्कि main game engine
XRL Applicationऔर engine-sideGameManagerको ले जाना - rendering rig तैयार करना: core boot होने के बाद screen output और input को जोड़ना
- Godot “mobile” project बनाया गया और Qud के texture content को project root folder में copy किया गया
- Godot पुराने
.bmpfiles को handle नहीं कर पाया, इसलिए ASCII tiles वाले files समेत सबको batch में PNG में convert किया गया - conversion के बाद assets load हो गए, लेकिन import progress indicator दिखने में करीब 30 सेकंड लगे
build errors घटाते हुए core assembly को ले जाना
XRL Applicationcopy करने के बाद Godot में C# project और solution बनाया गया, और initial state में 5,641 errors आईंConsoleLibऔरGenkitजैसी general-purpose libraries को पूरा का पूरा ले जाया गया, और पुराना sprite/atlasing solution Kobold file-by-file जरूरत जांचकर import करने का फैसला किया गयाKoboldJSONएक simple JSON serialization library है, इसलिए उसे वैसे ही ले जाया गयाColorके 85 usage points को globally replace करने पर errors घटकर 4,700 रह गईं- missing
GeneratedCodefolder जोड़ने पर event-specific generated class code शामिल हुआ और errors घटकर 1,557 तक आ गईं- Caves of Qud का structure ऐसा है कि boilerplate-heavy event-specific classes को code-generate करके performance और strongly typed event surface हासिल की जाती है
Unity dependencies और glue layer को व्यवस्थित करना
Embark Builderऔर character generation chargen में Unity UI code बहुत था, इसलिए initial ASCII technical validation में उन्हें हटाया गया- console version अभी नहीं है, लेकिन initial validation saved game load या random start से test किया जा सकता है
Gamefolder ज्यादातर Unity और game के बीच glue है, लेकिनCodeGenerationजैसे non-glue folders भी हैं, इसलिए उन्हें अलग root याPlatformfolder में ले जाने का रास्ता चुना गयाLanguageऔरHistoryKitlibraries ले जाने पर errors घटकर 454 रह गईं, और game/glue separation भले perfect न हो, फिर भी helpful रहा- बचे हुए बड़े error categories
CodeDom/Roslyn,PlayFab,Harmony, कुछ compiler-related issues, और game layer में leak हुआ UnityEngine surface थे PlayFabसे जुड़ा code अस्थायी रूप से comment out किया गया, और उसे glue module में उठाने के candidate के रूप में छोड़ा गया
Unity API replacement stubs और Godot C# के फर्क
Color32byte-based color type है, इसलिए जल्दी से उसका replacement implementation लिखा गयाUnityEngineReplacerfolder बनाया गया, और Unity docs या code references के बिना compile errors देखकर सिर्फ जरूरी surface implement किया गयाGameObjectstub बनाने पर “GameObject unknown है” वाली error असल में जरूरी fields और methods की errors में बदल गई, जिससे game द्वारा इस्तेमाल किए जाने वाले interface surface को समझना संभव हुआAudioSourceमें भी error list देखकर accessed members एक-एक करके जोड़े गए, और game में सचमुच इस्तेमाल होने वाला पूरा AudioSource port interface पूरा किया गया- इसके अलावा handle किए गए surface इस प्रकार हैं
Debug.Logreplacement shimScreenreplacement implementationIsNullOrEmptyextension method library port करनाMathreferences औरPI/Pidifference handle करना- Godot के
X,Yuppercase coordinate names का फर्क handle करना - IDE द्वारा
System.Drawing.Color,System.Numerics.Vector3गलत import होने की समस्या साफ करना
- Newtonsoft JSON को Visual Studio में NuGet package जोड़कर resolve किया गया, और CodeDom को भी
CodeDomNuGet package से resolve किया गया
Godot में full boot तक
- जब errors घटकर 11 रह गईं, तो बची हुई समस्या mod management के dynamic C# compilation से जुड़े code की थी; यह essential नहीं था, लेकिन complex होने के कारण आखिर तक बचा रहा
- इसके बाद link stage और stub field errors handle करके करीब 5 लाख लाइनों का C# code build हुआ
- अगला step एक छोटा renderer और input harness बनाकर core assembly boot कराना था, और goal game को ASCII+tile mode में runnable बनाना था
- Godot में empty scene बनाई गई और basic node पर
GameManager.csattach किया गया;GameManagerकोNodeinherit करना था और partial code की जरूरत थी - Godot का
_Ready, Unity केAwakeके equivalent और_Process, Unity केUpdateके equivalent के रूप में इस्तेमाल किया गया - initialization process में load path और mod management को port किया गया, और type resolver द्वारा नाम से type न खोज पाने की समस्या को printf-style तरीके से trace किया गया
- कारण dynamic assembly handling था
- mod assembly dynamic था, इसलिए main assembly check में dynamic assembly को exclude किया जा रहा था
- Godot editor में main game assembly भी dynamic होता है, इसलिए वह type search targets से छूट रहा था
- fix के बाद full boot सफल हुआ, और 500kloc game core frames supply करते हुए input का इंतज़ार करने वाली state में आ गया
- बचा हुआ काम “just work” कहा गया, लेकिन असल में VFX, sound, UI rigging में काफी काम बाकी है
1 टिप्पणियां
Hacker News राय
लगता है यह गेम लगभग पूरी तरह अपने खुद के engine का इस्तेमाल करता है, और Unity सिर्फ hardware abstraction layer और porting के ढांचे के तौर पर इस्तेमाल हो रहा है, इसलिए porting की कठिनाई के लिहाज से यह शायद सबसे अच्छे मामलों में से एक है
ऐसे गेम surprisingly काफी हैं, लेकिन बेशक यह ज्यादातर Unity titles का प्रतिनिधित्व नहीं करता
UI revamp के बाद भी ऐसा है या नहीं, पता नहीं, लेकिन अगर ऐसा है तो MonoGame पर port करके खर्च न बचाना मुझे हमेशा अजीब लगा
Android भी कुछ ऐसा ही है: operating system बस camera detection या encryption जैसी चीजों की जगह लेने वाली libraries load करने के लिए इस्तेमाल होता है, और एक दिन आपको एहसास होता है कि operating system असल में बस metal की एक पतली layer और bootloader भर है
https://nitter.net/unormal/status/1703163364229161236
धत् Elon. अब Twitter handle करना सच में बहुत परेशान करने वाला हो गया है
वाह, सच में शानदार। इस porting process को step-by-step देख पाना भी अच्छा है, और लगा हुआ समय भी काफी reasonable है, यह देखकर हैरानी हुई
अगर custom code इतना ज्यादा है और editor features कम इस्तेमाल हो रहे हैं, तो engine की जगह rendering library इस्तेमाल करना भी ठीक लग सकता है
नीचे engine हो तो ये चीजें मुफ्त में मिल जाती हैं। Unity हो तो शायद cost जुड़ सकती है
Brian क्या सोचते हैं, यह जानना हो तो यह video देखना अच्छा रहेगा: https://www.youtube.com/watch?v=U03XXzcThGU
मैंने पहले यहां से बहुत कुछ सीखा था
हालिया DHH का TypeScript controversy याद आ गया
static types के बिना ऐसा porting करने की कल्पना करें: हर बदलाव पर build करना, run करना और crash ढूंढना पड़ेगा। ऐसे समय refactoring-friendly language और अच्छी architecture में बनाया होना सच मेंありが लगता है
Twitter account नहीं है, क्या मामला है?