The Making of Breakout, Again

11/11/2021

I've been interested in learning to use Godot ever since I found out ByttenStudios was using it for their new game. A fully-featured open-source game engine! So exciting. The thing was, I was a little nervous to try out a new editor. I had spent so much time learning to use Unity and I didn't want to have to start over from scratch. I recently got a new laptop, though, and I wasn't in a hurry to gunk up my squeaky clean hard drive with a huge Unity install, not to mention reconciling my old projects with the newest version. So I bit the bullet, downloaded Godot, and worked my way through their “My First Game” tutorial. It wasn't much trouble, and I wanted to get up to speed quickly, so I decided to throw myself into the relative deep end and recreate my latest Unity project, Breakout, in Godot. Here's how it went.

First Impressions

Downloading, installing, and starting up Godot is so much lighter and faster than Unity. In general, it just seems more lithe and flexible. Godot was designed for use with its dynamic-typed GDScript, (though I didn't run into any compatibility issues using C# ! #statictypingorbust) and it kind of shows. It plays real fast and loose with references to other objects in the scene. Need to talk to a child object? Just call GetNode() with its name as the argument and hope it exists. (Names of objects being relevant was a nice blast of nostalgia to Flash). Need to talk to an object on your parent? GetParent().GetNode(), or just append “../” to the address.

Godot also has a lot of tricks to get around constantly subscribing to and unsubscribing from events. Their version of events, called signals, can be assigned right in the editor (though I still used C#'s static events in some cases where I didn't want to hook up each instance of a node). Adding nodes to groups also makes it ridiculously easy to, for example, call Stop() on every node that needs to stop moving or operating when a level ends: GetTree().CallGroup(“Stoppables”, “Stop”).

Now to be fair, a lot of this functionality does exist in Unity. They have UnityEvents, and ways of calling functions on other objects just with the method name. It always felt like a second-class way of doing things, though, while in Godot it's fully embraced.

Nodes vs Components

Beyond the general vibes, I didn't find the differences between the two editors to be so vast. I was happy to find that I very quickly acclimated to working in Godot, and that much of what I'd learned in Unity very much carried over. I guess that means I've learned things intrinsic to game development? I certainly hope so.

The main difference between the two, according to Godot at least, is that they have Nodes while Unity uses Components. Every object in a Unity scene is a Monobehavior, and you add functionality by attaching components to it. Therefore, most scripts you write in Unity extend the Monobehavior class. Every object in a Godot scene is a scene unto itself, called a node. To add functionality, you attach child nodes. Godot scripts extend the class of their node, e.g. RigidBody2D or AudioStreamPlayer.

Switching from components to nodes honestly didn't feel so different.. Godot claims that nodes allow for greater flexibility and easier testing, but testing is actually one area where I think Unity shines. Unity would run the game in the editor, so you could watch exposed variables in real time or fiddle with the scene on the fly. Though to be fair, I don't think I'm really embracing Godot's design philosophy, but just recreating my component-based way of thinking within Godot. It did take me a while before the component system really clicked for me, so maybe I will have a node epiphany later on.

The Results

All in all, I'm very pleased with the final product. It took me about five days to make, which I think is a testament to how much what I already knew from Unity carried over, and to how intuitive using Godot is. The fact that I reused all the same sprites, sounds, and lots of C# logic didn't hurt either. And the two versions are pretty indistinguishable, except for some key differences.

Right off the bat, there's no unity splash! Open-source, baby. The one aesthetic difference is that now the paddle and blocks are square, instead of rounded with an outline. This is just because Godot doesn't have the same “slice” import setting that Unity does that let me scale the paddle in the x-direction without deforming the rounded edges. It was a little disappointing because I do really like rounded rectangles and outlines, but I'll manage. The one game-play feature I added was the pause button, and that was just to show off how easy it is to pause with Godot. It's just GetTree().Paused = true, and make sure to mark something in the scene to stay active and listen for an input action to resume.

The last difference with the game is HTML5 specific. It turns out that Unity and Godot export for the web in very different way. The files a player needs to download in order to run Unity Breakout are 5MB; the ones for Godot take up 35MB. And this is a pretty simple game; I hear it gets much bigger pretty fast. Since Godot is open-source, I am able to compile it myself with all sorts of options to try and reduce the footprint of the web-assembly engine. I think the load time for this game is okay enough that I'm not going to do that right now. But if I make a bigger project that I want to run on the web, I'll either have to get my hands dirty with that, or stick with Unity. I think for now though, I'm going to continue with Godot. It seems like a good engine for my first original 2D game, which hopefully I'll be making soon.

Tags: Game Development, Godot