Moving Away from Unity

John 'Snowdrama' July 24, 2024 [Devlog] #FNA #Godot #Unity #C# #Game Dev

Contents

Godot Time

Over the last 14 months, I've slowly been moving over to using other game engines. I detail a bit about that in my previous blog post but basically, my main thing is that, while I had used Unity for a long time, my main issue with Unity was that over time they focused on nongaming features and just overall dissatisfaction with the direction of the engine.

I tried getting into FNA, and while It was fun for some nostalgia, I realized that I'd need to do a ton of hand-rolling some stuff with FNA. Not technically a bad thing but I think that I need to find something that can work with my current workflow as I'm trying to get something released as soon as I can simply out of need.

With the release of Godot 4's update to the newer version of C# and big improvements in terms of C# support from the last time I had used Godot when the latest was version 3.4. The changes to how C# integrated with 4.0 were huge and I finally felt like it was fully supported, not that it wasn't before but some idiosyncrasies kept me from ever being comfortable.

Overall the workflow I was using before works roughly the same as before, very little needed to change which was nice. I had to change a few things and re-tooled some things to take advantage of some Godot-specific things.

Unity's Biggest Mistake

It's likely you already know about the Unity Runtime Fee debacle, but if you don't here's a quick rundown.

In late 2023, Unity announced a change to the way developers would pay for their use of the engine by having a twenty cent per-download fee for the use of the Unity Runtime. It was clear that the intention was so they could additionally monetize large free-to-play games that had huge player bases, but there were a ton of issues with how it was delivered.

The backlash was harsh as Unity was not clear on how Unity would obtain the information on how many downloads there were, saying there was a "proprietary algorithm" that would determine how much you owe. This came across as 1 of 2 things:

  1. They'd be adding spyware to the build to report each time it was a new download.
  2. They would not know how many and would use its built-in analytics to guess based on some percentage of known users.

Neither of which is a great outcome, one is potentially a privacy mess, and the other requires you to trust a billion-dollar corporation with investors to please, not to rip you off and have no way to know where their numbers come from.

Now it was clear this would only apply to games with over one million in revenue but this was still an issue if you hit that threshold because it wasn't clear what downloads you'd pay for, and which ones you wouldn't, would downloads only cost you after you hit one million, in theory, you'd be on the hook for an unknown number of downloads.

The classic hypothetical was if you shipped a game on say iOS that had a $1 in-app purchase to remove ads(not an uncommon price model), and you got one million purchases day 1 and then the game went on to be downloaded 15 million times(with no more purchases) the runtime fee would end up being three million dollars, which is more money than the game even made.

Eventually, Unity would walk this back and clear up that downloads would be self-reported, as well as opting for a much more clear and understandable 5% revenue cut.

Runtime Free

While I started looking into Godot way before the Unity Runtime Fee, I do admit that it did solidify my intention to switch to something else, maybe not Godot, but at least something free and open source.

I was originally thinking about using FNA, which I had been familiar with due to working with XNA in 2008-ish, but being part artist, part designer, and only part programmer, I wanted something with a user interface for creating levels and attaching scripts to objects, something that would at least partially mimic my workflow from Unity.

I still love XNA as it's one of the first game frameworks I used, but I want to ship a game in the next year. While I could create my own custom interface for FNA, I'd like to try not to spend the next year creating tools, so for now, FNA was out.

After trying Godot 4.0 I realized how quickly my Unity workflow fit into the Godot ecosystem for 80% of cases and I got off the ground running quickly.

My first Godot project around August a few months into learning Godot 4.0.

So combined with the open-source nature of Godot and the fact that I was already fairly effective with it, I decided to use Godot at least for the foreseeable future.

It helped me get past the main issue which was worrying about launching and having to deal with a ton of overhead due to using Unity.

Porting Process

Moving scripts to Godot was fairly easy, for some things like my static classes, it was just simple changes like Godot's Vector classes using capital letters for XYZ instead of xyz, swapping Update for _Process and removing "transform" from scripts. So where Unity would be this.transform.position in a MonoBehaviour in a Node it's this.Position

Dumb comparison of very basic scripts note how in these examples they're so similar this won't be the case for everything but you can see how just copying a Unity script into a Godot project than converting could be totally viable:

//Unity
public class MyComponent : MonoBehavior{
  public void Update(){
    if (Input.GetButtonDown("MoveRight")) {
      this.transform.position += new Vector2(1.0f, 0.0f) * Time.deltaTime;
    }
  }
}
//Godot C#
public class MyComponent : Node2D{
  public override void _Process(double delta) {
    if (Input.GetActionPressed("MoveRight")) {
      this.Position += new Vector2(1.0f, 0.0f) * (float)delta;
    }
  }
}

This gets you 80% of the way there, and then you need to start doing some things the "Godot" way which is fine to be completely honest. The whole process of converting most of my tools to Godot only took a couple of hours as well as testing stuff.

The main change I ran into was not thinking about nodes like GameObjects, a GameObject can have many components, but a Node is a single component so you use the node's children to contain dependent components. Like a Rigidbody isn't a single GameObject with both components, but instead a Parent Rigidbody, and a child collider.

Eventually, I started working on porting my Router, Transition and Spring tools, and this sped up my workflow, it took only a week to port most of my tools(thank goodness for Resources being similar enough to ScriptableObjects)

The only one that I had a hard time with was UI stuff. Making custom UI containers is not fun at all and I still don't think I got it right so it's still a work in progress.

Anyway, I plan to release the tools publicly eventually similar to my Unity tools though I think this will just be one submodule you can install into your project rather than separating them into bits most of the tools are generally useful when combined. So maybe if I make something significantly different I'll make a second Submodule but for now I'll wrap them together.

If anyone wants to see an example of my Unity to Godot code, definitely let me know on Twitter or Mastodon! I have been thinking about porting one of my old Ludum Dare projects, and I'll make a video & blog post for it!