Performance

You might expect a game engine to prioritize performance above all else, but that’s not exactly the case with Godot. The performance issues of Godot are like a big elephant in the room, so let’s lighten the mood with a short satirical piece before we dive into the details:

Given that games are soft real-time systems, performance is usually of paramount importance for game engines. It’s not clear whether Godot would like to hit AAA games in the future, but existing decisions suggest that Godot is mostly suitable for smaller games that are not performance-demanding.

If we look at older but still juicy proposals such as “Using the slowest data structure almost every time” at Godot1, it becomes clear at first glance that Godot favors ease of use and maintenance over absolute performance. Godot often chooses the easiest and most maintainable data structures, even if they are not the fastest.

Under normal conditions, this could indicate that Godot values user-friendliness and code simplicity over performance in most cases. This kind of approach may be reinforced further by lead developer’s article called “Why isn’t Godot an ECS-based game engine?” by doing what he describes as “clever optimizations” as a compromise2.

Unfortunately, Godot’s optimization deficiency is painted as a preference for code readability. This is often seen as a sign of negligence by professional game developers. For example, lead developer of Godot doesn’t believe in “death by thousands cuts”3:

I never really believed in the “death by thousands cuts” premise regarding to optimization of code. This premise exists as a counter to “premature optimization is the root of all evil” and it basically says that if you don’t optimize early, then it will eventually be too late..

The rationale is that, if you don’t optimize early, then all the code accumulates will add “slowness” to the project and at some point the whole codebase will need large rewrites to optimize. To avoid this, everything should be optimized early. I think this is a big mistake.. And that it leads to extra complexity, or software that is much harder to develop and use.

This attracted a fair amount of criticism towards Juan’s claims concerning optimizations, which frankly apply to the Godot codebase as well4:

“Optimization” is always ill-defined in these discussions. Optimization is a spectrum that includes a myriad of elements, techniques, concerns. Data structures. Memory layouts. Mem allocations. Lazy-evaluation. Over-Eager evaluation. SIMD. Multithreading. GPU version. And so on.

Nobody says you should write everything in SIMD / multithreaded / GPU form right from the start. That is definitely premature. But writing it “properly” (without pointless memory allocations, or O(n^2) loops that could be easily avoided, etc)… is not.

In other words, do the basic optimization bits early, yes. Not everything. Remember: it’s a spectrum. Putting yourself at the absolute beginning of it makes no sense, at any time, because it takes so little effort to move a bit in the right direction. Some of these things should not even count as “optimization”.

For example removing a pointless allocation, or skipping code that doesn’t need to run, is just good practice and basic cleanup. Not really optimizing the code.

Do that early.

Juan often makes discussions quite ambiguous, as evident from the above criticism concerning Juan’s claims. What we can possibly infer is that Godot might not even care much about performance in the first place, or until slowdown is so noticable that it creates enough pain for Juan to start optimizing code.

This kind of approach as expressed by Juan sounds more like excuse-making. These justifications as being offered by Juan are not genuinely intended to clarify the approach, but rather to avoid responsibility or deflect criticism that Godot’s codebase receives from industry experts, such as analysis of Godot’s codebase riddled with bugs, as you’ll find out in subsequent “Quantity vs Quality” section.

In contradiction to Godot’s alleged claims regarding performance, like Godot not accepting ECS principles or architecture, Juan even wrote an entire article accepting a possibility of Godot becoming viable for AAA game development, titled “Godot for AA/AAA game development - What’s missing?”5. Taking into account what was presented here so far, in most likelihood, articles with click-baits like these are written to attract corporate sponsors. To answer the actual question put forward by the article… Godot is missing! 😁

Another notable source comes from a Unity user who was considering a switch to Godot. In an article titled “Godot is not the new Unity - The Anatomy of a Godot API Call”6, within the section “So why are we waiting for Godot?”, the author, after conducting thorough comparisons and benchmarks, summarizes Godot’s performance with the following concise statement:

Godot has made a philosophical decision to be slow. The only practical way to interact with the engine is via this binding layer, and its core design prevents it from ever being fast. No amount of optimising the implementation of Dictionary or speeding up the physics engine is going to get around the fact we’re passing large heap allocated values around when we should be dealing with tiny structs. While C# and GDScript APIs remain synchronised, this will always hold the engine back.

Read a summary of the conversation between Sam Pruden and Juan Linietsky, as well as notable reactions from industry experts, including Mojang’s business developer:

Juan Linietsky’s assurances that Godot will become a more powerful game engine are meant to instill a belief in a so-called “bright future” rather than something to rely on in the present moment. People are misled to believe that they must wait for Godot to become a performant engine, when the underlying architecture suggests that Godot will never become one, so waiting is by definition futile. Most people will just choose a different engine:

Since we are only discussing development philosophy at the highest level of abstraction here, it’s recommended that you read the entire article yourself to get a full understanding, as it is quite technically dense.

You can also discover more about Godot’s performance issues by looking at post-mortems that involve intersecting technologies like Rust:

We’ve been using Rust on basically all of our games since mid 2021. This was when BITGUN initially started as a Godot/GDScript only project, and as we ran into issues with Godot’s pathfinding (both performance and functionality wise) I looked into alternatives, found gdnative, and then was recommended godot-rust. It wasn’t the first time I’ve seen or used Rust, but it was the first serious usage for game development, being preceeded only by game-jam-y projects.

Sadly, there are people who persist in believing Juan Linietsky’s repeated Godot-is-almost-here assurances, viewing him as an unquestionable authority. This perception is so strong that even those who initially criticized Godot’s performance might retract/delete their statements years later, despite ongoing evidence of performance issues in the present.

This isn’t necessarily because they’ve changed their minds. This social phenomenon is mainly due to the overzealousness of the Godot community in upholding the engine’s flawless public image, where they often attack critics deemed to have “misunderstandings” about the engine, leading these critics to doubt their own perception of reality. One notable instance occurred when rendering priorities were criticized, and the rendering lead, Clay John, dismissed those concerns as mere misunderstandings:

This pattern of behavior has become so obvious that people have begun to mock it ironically:

It is undeniable that Godot will make strides in performance improvement in some way or another. However, the pace and extent of these improvements remain minimal when contrasted to professional-grade alternatives.

References

1

Using the slowest data structure almost every time - Discussion at Godot, GitHub.