Some time ago, our team built a mobile game. But first things first. Let’s start with a short disclaimer - we are mainly web developers. We love to tinker with different technologies, and some of us had some experience with Unreal Engine, Unity, Phaser or even Flash in good ol’ days. Yet, we’re not specialized in game dev - that’s a fact, nothing to be embarrassed and we think an important acknowledgement for the rest of this article.
We got commissioned to build a mobile game for an NGO. It had to be educational, yet we really wanted to keep it playful and engaging for a casual player. Our creative team came up with an idea of an illustrated 2d platform game, interspersed with educational quizzes from time to time.
Why we’ve picked Godot
As our design team decided to go with an illustrational style, we knew that we’ll be working mostly with animated sprites. The gameplay quality was really important for us, so we knew we want to use an existing engine, rather than reinvent the wheel. We thought about Unity for a brief moment, but we don’t love how it works with version control, as scenes are saved in binary format. We also prefer to pick open source projects when possible. If you google for such engine, you’ll probably find Godot, Defold and some 2d-only engines.
We wanted to pick something universal, that could benefit us also in 3d game dev in future. Defold seems nice, but at the time of our decision, it seemed much less mature and popular (1.2k stars on GitHub, vs 35k for Godot). Also one of the team members had already played with Godot a little bit, so we went with his recommendation.
While many competitors in the area of open-source game engines rely on Lua, Godot brings its very own GDScript language. It also brings support for C++ and C# on top of Mono. Yet, GDScript seems like the best option as it deeply integrates with the engine so most times code for the same functionality will be much simpler in GDScript. Also, most of the materials you’ll find over the Internet is based on GDScript. So, as long as you’re not a daily C++ or C# developer, you should probably pick GDScript. And that’s what we did.
GDScript is a python-influenced language, created with a single purpose. In our experience, it’s easy to learn. If you casually use Python, you’ll feel most at home. Honestly, it felt easy to start using even for a person who hasn’t used Python for like 10 years.
We really liked the integration with the engine. It brings easy to use event system, that was good enough for most of our cases. The option of writing semi-async parts of code with yield is really helpful. Yet, there are also disadvantages of being a single-purpose and not widely used language. It lacks the idea of private fields or methods, so you end up with an underscore-prefixed mess. Instantiating object is inconsistent - for scripts you call
new(), yet for scenes, you call
instance(). What’s worse, you can instantiate a script instead of a scene by mistake if you name it with
class_name or load
.gd instead of
.tscn file and you won’t get any clue from the engine or editor other than meaningless runtime errors. Also, a clean way of importing classes/scripts together with a proper package manager would make it less like it’s 2003 and you’re still rockin’ PHP3. Yet, if you learn to live with those disadvantages, it does its job and you’ll find it okay.
GDScript also comes with optional Types. The notation is similar to Python’s typing, but you can only use native types along with classes, that you can access either by making them global with
class_name keyword or loading using
const … = preload('…'). No generics, interfaces and other things that you expect to find in a strongly typed language. Yet we still appreciated the existing support and used it as much as possible.
But things are changing and GDScript will get its next iteration with Godot 4, which looks very promising, to be honest.
Godot as a fully blown game engine comes with its very own editor for both visual stuff and scripting. What’s impressive is that the editor itself is fully written in Godot. Works okay and has a lot of helpful features, including animation editor (if you ever used Flash, you’ll feel the nostalgia), visual editor for scenes and UI and easy way to bind signals (events) with your scripts. It also has built-in documentation, which is a nice bonus.
On the other hand, we sometimes felt it tries too hard to do everything within the engine. For example, things that in most programs are using OS controls like file open/save dialogues, here are also custom-built. Maybe we wouldn’t mind if the experience was similar to the native one, but using it is dreadful and we’d really appreciate native controls here instead.
For writing scripts, you can use an external editor (there are third party packages with syntax support for VSCode, Atom and Sublime). But that, at least for VSCode, requires the official editor to be open in the background anyway.
Building the gameplay
Godot goes really well with 2D games and the amount of built-in tools and solutions is huge. We rarely had a problem, that a tool or helper was missing.
Games in Godot are built with nodes. The ability to combine two totally different nodes, that the engine gives you, is amazing! Also, in our opinion, the documentation is very good, at least comparing to other game engines. Sometimes it lacks more explanation or examples, but overall it’s in a good state.
But, unfortunately, nothing is perfect, and neither is Godot.
We were struggling with ParallaxBackground, because of the different resolutions we had to handle. And as it turned out, there is a nasty bug, that occurs when you change your screen resolution (at least in versions 3.2.2/3.2.3 that we’ve used). There were also some weird quirks when it came to physics of the body, controlling it, repositioning and stuff like that.
And yet, there were many things that we were very positively surprised with. To name a few - sprite animations, 2D transformations, global and local coordinates, collision handling and many other things. Prototyping, managing assets and level designing were a breeze. And at the end, we managed to (with some effort) get rid of (or around :)) all major bugs.
Building the UI
As even the Godot’s own editor is built on top of the engine, its support for building UIs is a first-class citizen. It brings you a catalogue of ready-made, stylable components that should do the job for most scenarios. The game we were building had quite a lot of UI for its size, as besides the core gameplay we also had to build functionalities like quizzes, educational tips, accomplishments lists, disclaimer screens and stuff like that.
Godot provides us with two ways of styling components. You can either manually attach styles per each component (these can be saved into files and reused between multiple components), or you can define so-called themes. This way, you can style a component together with its children - kinda like with CSS, but with a visual editor. To be honest, we found using just reusable styles without whole themes thing more streamlined and easy enough to maintain for a project of our scale.
What we found surprising and very unfortunate, was the total lack of touch support for scrollable containers. You should keep this in mind, that when implementing UI for mobile games, you’ll be required to code goodies like kinetic scrolling all by yourself.
What you will find helpful, is that the engine brings us multiple ways for creating animations. Besides the mentioned visual animation editor, you can use built-in tweens. If you ever used TweenMax, you’ll know what to do. It lacks a true timeline for orchestrating animations from code, however in our case playing a little with delays and durations did the job. What’s missing is an option to provide a custom easing curve, so you need to relay on built-ins.
One big, yet important hole in the ecosystem is the lack of any navigation management. So if you want to build some hierarchy between UI screens, together with animated transitions, you’ll once again be on your own.
In terms of animations, you’d be able to build something modest pretty easily. However, if you’re about to create anything fancy, you’ll quickly end up messing with shaders. So what’s missing is something to fill the gap between super simple and super complex animation techniques.
Integration with native APIs
TL;DR: if there’s an existing plugin, it’s easy. If not, you’re on your own.
Our game was intended mostly for Android, and for this OS, there is a pretty good new plugin system, introduced with 3.2 version of Godot. It’s much more straightforward than the previous module system. Godot does not bring too many platform-specific integrations. If you want to integrate analytics, push notifications, social media integrations etc, you won’t find any of these stuff within the core so you’ll need to rely on plugins. That’s a reasonable idea as it allows Godot maintainers to focus on the engine’s core.
At the time of writing this article, a lot of possibly useful plugins don’t exist yet, and if you find what you need it would probably be some alpha version with few stars on GitHub, poor documentation and not always working properly. We hope this to change in future, but if you plan to use Godot for your next project, do some research to avoid trouble in the middle of the job.
Overall, we’ve enjoyed working with Godot on the project. We’ve built a playful and enjoyable game and were able to rapidly prototype its mechanics at an early stage. However, due to limitations of the engine’s UI framework and lack of high-quality plugins for Android, we found it pretty challenging to develop a smooth experience around the core gameplay.
Anyway, we deeply appreciate lots of hard work done by Godot’s maintainers and we’ll keep our fingers crossed for the engine’s future development.
Thanks for reading!