top of page

Why you shouldn't use Godot preload all over your game.

  • Jun 12
  • 5 min read

I thought I was being smart. That’s usually how these stories start. My son and I were working on our game, JiuJitsu Hero Flow Roll. It’s a fast-paced game. Moves happen quickly. Animations need to pop. Inputs have to feel instant. No lag. No waiting. No weird delays where your character just stands there like they forgot how legs work. So naturally, we wanted everything to be fast. And in Godot, when you want something fast, you find this nice little command called preload(). At first glance, it feels like magic. You write something like:var attack_scene = preload("res://scenes/attack.tscn") and bang. The engine loads it right away. It’s ready. Waiting. Like a ninja hiding in the shadows, prepared to strike at any moment. I explained it to my son like this: “Preload means the game grabs everything ahead of time, so it doesn’t have to think later.” He nodded. That sounded smart. And it was… at first.


The Plan That Seemed Perfect

We started using preload() everywhere. New enemy? Preload it. New animation? Preload it. UI elements? Preload. Effects? Preload. Sound effects? Oh yeah, preload those too. Pretty soon, our code looked like a grocery list of preloads. It felt good. Organized. Efficient. Like we were planning ahead. We told ourselves: “If everything is already loaded, the game will run faster.” And for a while, that seemed true. When we tested small parts of the game, everything felt snappy. Smooth. Responsive. My son said, “It feels fast.” I said, “That’s because we’re doing it right.” We were not doing it right.


The First Crack

The first problem didn’t look like a big deal. The game took a little longer to start. Not terrible. Just… noticeable. We shrugged. “More stuff to load,” I said. “No problem,” he said. We moved on. Then came the second problem. The game would freeze for a second during certain transitions. Not always. Just sometimes. That’s the worst kind of bug. The “sometimes” bug. We started guessing. “Maybe it’s the animations.” “Maybe it’s physics.”, “Maybe it’s the input system.” We checked everything except the real problem.


The Crash Era

Then the crashes started. At first, it was rare. One crash after ten runs. Then one after five. Then every other run. Then sometimes right at startup. That’s when you know something is very wrong. My son looked at me and said, “It wasn’t doing this before.” He was right. We had made it worse. Way worse.


The Investigation

So we did what developers do. We blamed everything except ourselves. We checked:

  • Physics calculations

  • Animation trees

  • Input handling

  • Signals

  • Scene transitions

  • Memory leaks

We even questioned the engine for a second. “Is Godot buggy?” I wondered out loud. It wasn’t Godot. It was us. Eventually, we looked at memory usage. And that’s when we saw it.


The Big Realization

The game was eating memory like it was an all-you-can-eat buffet. Every scene. Every asset. Every sound.

Loaded. All the time. Even if we didn’t need it yet. Even if the player would not see it for five minutes. Even if it was used once. It was all sitting there. Taking up space. My son asked, “Why is everything loaded already?” I paused. Because I told it to. That’s what preload() does. It loads things at compile time. Before the game even starts running properly. So every time we used preload(), we were saying: “Hey Godot, grab this now. Keep it in memory. Don’t let go.” And we said that… a lot.


The Problem with Being Too Prepared

Preloading is not bad. Let me say that again. Preloading is not bad. But using it everywhere? That’s like packing your entire house into your backpack because you might need it. Technically, you’re prepared. But you can’t walk anymore. Our game had become that backpack. Heavy. Slow. Struggling. And eventually… it fell over.


Enter load()

That’s when we looked at the other option. load() At first, it seemed worse. Slower. Less efficient. Because it loads things at runtime, not ahead of time. So instead of: “Have everything ready” It says: “Get it when you need it” That sounded risky. “What if it causes lag?” my son asked. “Good question,” I said. We were about to find out.


The Experiment

We picked one system. Just one. Enemy spawning. Originally, it looked like this: var enemy_scene = preload("res://scenes/enemy.tscn") We changed it to: var enemy_scene = load("res://scenes/enemy.tscn") Then we ran the game. We waited for the lag. It didn’t happen. The enemy spawned just fine. No stutter. No delay. Nothing exploded. That was a good sign.


The Domino Effect

So we kept going. One system at a time.

  • Attacks

  • Effects

  • UI popups

  • Sound triggers

  • Background elements

Each time, we replaced preload() with load(). And each time, something interesting happened. The game didn’t get slower. It got lighter.


The Turning Point

Then we ran the full game again. Same test that used to crash. We waited. And waited. And… nothing. No crash. My son said, “Did it just… work?” I said, “Run it again.” We ran it again. Still fine. Again. Still fine. That’s when we knew. We had found the problem. And more importantly…We had fixed it. yay us!


The Rebuild

Here’s the part people don’t like. We didn’t just tweak a few lines. We rebuilt a lot of our code. Because once you start relying on preload(), it spreads everywhere. It becomes part of your structure. Your assumptions. Your habits. So switching to load() wasn’t a find-and-replace job, naa wrighting code is way more involved than that. We had to rethink how to do a bunch of crap:

  • Scene instancing

  • Resource management

  • Timing of loads

  • Object lifecycles

It took time. It was annoying. But hey, it was absolutely worth it to not blow up our game, right?


What We Learned (The Simple Version)

I explained it to my son like this: “Preload is like cooking all your meals at once and putting them on the table.” He nodded. “And load is like cooking when you get hungry.” He nodded again. “Which one makes more sense?” He said, “The second one. The food won’t go bad.” Exactly.


A Simple Example

Here’s the difference in practice. Using preload: var explosion = preload("res://explosion.tscn")

This loads the explosion before the game even starts. Even if you never explode anything. Using load:

var explosion = load("res://explosion.tscn") This loads it when the code runs. Only when needed. Less waste. Less memory. Less chance of crashing.


Why the Crashes Happened

Let’s break it down simply. Computers have limited memory. When you preload too many assets:

  • Memory fills up

  • The system struggles

  • Garbage collection gets messy

  • Performance drops

  • Eventually… crash

We basically told the game: “Hold everything at once.” And the game said: “Naa, I can’t.”


The Aftermath

After the rebuild, everything changed. The game:

  • Started faster

  • Ran smoother

  • Crashed less (actually, not at all in our tests)

  • Felt more stable overall

Even better, we understood our system more. We weren’t just guessing anymore. We knew what was happening.


A Better Strategy

Now we use a simple rule. Preload only what must be instant. Load everything else.

For example:

  • Core player assets: preload

  • Main UI elements: preload

  • Rare effects: load

  • Enemy variations: load

  • Optional content: load

That balance keeps things fast without overloading memory.


The Human Side

This wasn’t just a coding lesson. It was a thinking lesson. We learned that: Just because something is faster in one moment doesn’t mean it’s better overall. And more importantly: Doing something “everywhere” is usually a bad idea. Even if it starts as a good idea.


The Game Today

JiuJitsu Hero Flow Roll is now running smoother than ever. No random crashes. No weird freezes. (that we know of right now, fingers crossed, knock on wood) Just clean, responsive gameplay. Exactly what we wanted from the start. You can check it out here: https://store.steampowered.com/app/4780970/JiuJitsu_Hero_Flow_Roll/ And yes, it feels a lot better than it did before. So if you’re using Godot and you love preload(), that’s fine. Just don’t love it too much. Because we did. And it almost broke our game. Actually, it did break our game. But now we know better. And now you do too.




Remember when video games used to be fun and not expensive? We're bringing it back!

© 2022 Yavoz.fun. All rights reserved.

bottom of page