elega Elega Corporation

Kalling Kingdom Engine Port and YouTube Hiatus

Porting C# Unity Code to Rust

Since the Unity debacle where they nearly committed to charging an install fee to developers using their runtime, I had decided to port our first game out of the Unity engine. Rewriting programs in the Rust programming language has, at this point, long been an internet meme. I'm not here to evangelize - it's just a fact that I had decided nearly a year ago now that I would build a proprietary game engine using the Rust language because of the benefits it offers around performance.

I would also argue that Rust provides other benefits that, contrary to what many would probably say, are ergonomic advantages over something like C#. Object-oriented programming languages provide a lot of conveniences and have some positive qualities like being explicitly typed when it comes to defining variables, for example, but they lack making obvious the way in which memory is being interacted with by the program. Rust is a lower-level language that, like C or C++, allows me to handle the way in which memory is worked with explicitly. For game development, this is a needed advantage in many instances.

Kalling Kingdom, in its most recent version (0.41 at the time of this writing), is about 7 thousand lines of C# code, and that code is aided by code that underlies the Unity engine itself. Within Elega, I've been working on what we call the Aperture Engine. The Aperture Engine was being built first and foremost for a 2D top-down action adventure game that we're also working on initially... but then I've since begun to switch it into being sufficiently compatible for Kalling Kingdom.

Kalling Kingdom is significantly different than a 2D top-down action-adventure game. In fact, everything after 2D in that phrase is different. For the most part, Kalling Kingdom is about its menus and UIs more than anything. There's a ton of work that was put into all of its menus, and in fact the original game was scoped in concept as being a game of menus. Luckily, all the essentials are also there within the Aperture Engine: 2D sprite rendering, sound, and pretty soon: enough for input management.

To my surprise, porting Kalling Kingdom's code has so far been incredibly smooth going in terms of converting gameplay logic code for what gets processed from turn-to-turn. I know C# and I know Rust, so it's all been a matter of simply going line-by-line and translating. Yes, I am doing this by hand: some things require rearranging, so to speak, and are more verbose in Rust than their C# counterparts. Most of the work remains ahead of me: I've only converted about 20 percent of Kalling Kingdom's code and most of the work ahead of me will lie in porting the entire user interface and presentation layer. As I'll describe in more detail here, as well, it's not as simple as line by line translating in every sense. Unity has its way of doing things in its engine and Aperture does too, so I have to rework how some things are referenced and accomplished in some instances.

This project marks the first time I've ever done a game port and I'm grateful that it is my own game - it means I know every aspect of the codebase in which I'm converting. Still, I've been kind of shocked how straightforward it has been so far. For some people, they have no idea where to begin with creating a new engine, and then porting an entire game into it (even if it is just kind of a small game). Many would think this is dark magic!

No magic whatsoever, though. Let's think carefully about what's different...

Kalling Kingdom, and the Unity engine, are broken up into a few distinct parts, fundamentally. To begin with, the Unity engine provides the basic parts for rendering anything to the game window, playing sounds, and receiving keyboard presses and mouse clicks on whatever operating system it's running on. Since all of Kalling Kingdom uses only a tiny subset of what the Unity engine is fully capable of, that means that our Aperture Engine does not need to meet full-on parity with Unity: we only need to recreate the things I just mentioned. Oh, and we use Unity's built-in UI system, the one that originally came out around the time of Unity version 5's release (not their latest one or other options out there on the Unity Asset Store).

The Unity UI system provides a ton of conveniences and allowed me to fairly rapidly construct the Kalling Kingdom UI. Each Kalling UI element, whether it is a button or a patterned background, is rendered as a sprite (or image) within the game window by the Unity engine's renderer. The big things I lose by abandoning the UI system is the easy compatibility with mobile devices via touch interface it offers (which I haven't used) and the ability to visually see what I'm building in the Unity editor. I'll eventually be circling back to creating a similar system that lacks the mobile device touch support that will work with an edit mode within the Aperture Engine. It is worth noting that the Aperture Engine will not have some kind of special editor window that is separate from the game: there's just two modes within the new game itself. The edit mode will allow me to drag UI elements around, resize them, or alter their colors. I've not begun work on this yet.

Kalling Kingdom's gameplay code is then broken into distinct sections, starting with a GameManager class. GameManager implements the MonoBehaviour interface that has been used with most C# script files since the dawn of the Unity engine's history. Unity will look to all of the C# scripts within a scene, or gameplay world, that has been applied to game entities, and first determines if they have implemented an Awake function implementation. When you load a level, or a scene, in the Unity engine, this is the first thing that happens: the engine calls any Awake function that exists. This allows everything in a scene to get initialized, or loading the initial state of the world as it's been defined programmatically.

Then, another function that is similar to Awake runs and that's the Start functions. So, the very first place to start on the port has been these Awake and Start functions within the GameManager class that's written in C#. There is a lot of stuff in there, and all I'm doing so far is literally going line-by-line, and translating each one into Rust. I then have the Aperture Engine call these translated functions.

With initialization taken care of, the next big phase is the Update functions that run every single frame within the Unity engine. These will instead run every frame in the Aperture Engine instead, and that is one of the next major steps along the way toward porting the entire game into Rust and the Aperture Engine. Everything else that involves the plumbing of the engine is, for the most part, a matter of replacing function calls: playing sounds, drawing and rendering 2D images, rendering fonts in a certain position and size... these all require some manual tweaking based on not fully knowing 100% of how Unity does this under-the-hood.

Frankly, I've been pretty excited about the 2D rendering side of the Aperture Engine, as doing straightforward OpenGL rendering on any modern machine can render anything 2D incredibly beautifully, clearly, and crisply in a way that Unity for some reason doesn't do (and it takes a fair bit of work to get it to do that). Unity loves aliasing and atlasing stuff, and converting it into down-sampled or down-scaled resolutions, probably in part because it has to be able to support porting to multiple platforms, some of which may not be very powerful. But honestly, that's just my own speculation. I have certainly seen folks describe some secret tips on how to achieve pixel perfect and true-to-resolution rendering within Unity. Part of me is curious but part of me no longer cares why Unity is the way it is. After all, it won't matter much longer.

This first phase of the project is about producing a port that is super precise and true to exactly the gameplay in the current version of the game. Once that is done, the port itself will be released as the latest version of the game, and folks who purchased the game on Steam or platforms that have launchers will automatically get the updated version. Once the port is 100% complete and stable, then I'll begin on the planned updates, all of which I've discussed for years at this point. I'll try to do another of these blogs once the Kalling Kingdom port is further along.

YouTube Hiatus

The company YouTube channel has been on break since I started this port. I didn't know how long the port would take, and now that I'm in the middle of it: it's very unclear whether I'll get any better at estimating the timeline. That said, I want to assure any of the recent subscribers to the YouTube channel that I do have a lot of plans for videos. If you don't want the channel sticking around in your subscriber list on your account and hate clutter - I get it... but if you're willing to wait: I have exciting content planned.

Obviously, this journey ahead to finally finish Kalling Kingdom is one that needs to be documented, and I'll definitely be capturing some footage that describes my experience in porting the game, as well as adding new features and tweaking all of its systems.

Other video ideas involve more Elegant Dev Storytime, of course, and more one-off concepts like cataloguing my favorite Game Awards moments, making game design review videos that seek to analyze existing well-known games and how their designs could be expanded upon, improved, or just mentioning things they did well.

Future Kalling Kingdom Port and Conclusion

Once I am close to finishing the port out of the Unity engine with Kalling Kingdom, I'll be making a welcome announcement to folks who already own the game to help test it prior it to going onto a stable channel for automatic updates. Then, I'll continue making regular updates as I roll out new features to finally finish the original vision for the game. Folks, if you're reading this, then you're reading the reboot of Elega Corporation - welcome to the party.