When you sit down to create a game, one of the first decisions you need to make is how you’re going to actually build it. I’ve attempted to build games a couple of times in the past, but each time I wanted to build up the engine from scratch (or at least from OpenGL and SDL primitives). This has always been exciting to me from a programming perspective, but, inevitably, I end up getting bogged down in systems details and never get around to working on the game itself.
Given this past experience, we wanted to try something different for Rads & Relics and use an existing game engine. We wanted to use a free open source engine, and, after watching the Unity debacle from afar, decided to work with Godot. We’re about three months into our development of Rads & Relics, and we’ve been learning our way around Godot, so today I wanted to share some reflections on the experience.
As a through-line, I’m pretty pleased with using Godot. The engine has automated a lot of the basics (graphics, sound, filesystems) and let us focus more on what makes our game unique. We don’t need all of the features (we’re not currently using any of the physics or any of the 3D logic), but none of those have slowed us down. It’s really nice to be able to export to multiple platforms easily and the performance has been fine so far (although we haven’t done anything too intensive yet). If you’re in the market for a game engine, I would definitely recommend Godot. That said, here are a couple of things to watch out for for the aspiring game developer.
GDScript
We’ve been working primarily in GDScript, Godot’s custom scripting language. As a language it covers most of the bases, but the tooling is obviously not going to be as developed as a mainline language like Python or Lua. However, if there’s one thing to be aware of it’s that the type hints can be somewhat problematic, especially around typed arrays.
In Godot, unlike say Typescript, the type information can affect run time behavior. This has been most relevant when dealing with typed arrays. Godot will throw a run time error (not a static error) if you try to return the incorrect array type. Unfortunately, a lot of the built in array functions return untype arrays which then will have to pollute the entire call chain.
For example, consider this snippet:
func foo(a: A) -> B:
...
func map_wrapper(arr: Array[a]) -> Array[b]:
return arr.map(foo)
This will cause an error at run time :Trying to return an array of type "Array" where expected return type is "Array[b]"
. You can get around this, but it requires different ways of constructing the array, which can be annoying.
Working with the Editor
I’ve been enjoying working with the Godot editor. Make liberal use of the @export
annotation to allow you to make adjustments to your resources and nodes directly within the editor. I’ve also been leveraging the @tool
annotation which allows scripts to run both in game and in the editor, allowing me to run complex logic without having to reboot the entire game.
My only warning here is around version control. We have been using Git with Godot and overall it has worked well. However, if you change branches while you have the editor open, it will sometimes get confused as files are changing around underneath it. I’ve taken to just closing the editor before switching branches as a precautionary measure.
Godot and the Ecosystem
The Godot ecosystem is moderately developed. I think the strongest part is the official documentation which has extensive documentation and a number of helpful tutorials. I’ve found the non-official ecosystem a bit weaker, with a number of tutorials on very basic things, but fewer tutorials on advanced concepts or specific problems in the development process. I’ve still been able to find everything eventually, but sometimes I am scraping things together.
One other note on this topic is that LLMs have a decent knowledge of Godot, but they often mix up Godot 3 and 4. I’ve noticed this across models, and whether it’s due to training cut off dates, or just a lack of documentation I’m not sure. I would just advise to double check the output for your version of Godot (this is a good practice anyways).
State of the Game
-
Progress this Week
-
Improved card pool
-
Improved UI for card and character abilities
-
Implemented pathfinding logic
-
-
Coming up
-
Add new enemy types
-
Add enemy intent system
-