Game stutters when a particle explosion is triggered

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By unfa

I am making a 3D platformer game, where you have to collect pink stars.

Once the player touches one - an AnimationPlayer is triggered to among other things start two particle systems, play some animations on two meshes and change energy of an Omni Light. Then the animation triggers a queue_free() call after 12 seconds when the particles are gone.

Here’s how the game looks and works:

I’ve noticed that the first time I trigger this during a run the game hangs for the longest period right before showing the particles, and the consecutive times usually are faster or even almost glitch-free.

The smoke particles probably take up the most resources, because they use a 2K texture (Albedo + Normal Map) with 4x4 tiles - each smoke particle uses a random tile to produce more natural image.

They also receive shadows and there’s some hue variation.

I see that even without the initial stutter the smoke effect is too heavy. I will be looking into ways to optimize it, but now I want to find a way to fix this initial stutter.

How can I debug and fix such a problem in Godot 3?

Are the textures being preloaded, or are they being loaded initially on the first trigger? This topic is way beyond my current knowledge, but that’s what came to mind when you mentioned that it is worse on the first triggering :slight_smile:

i_love_godot | 2019-12-11 13:47

I am not doing any preloading, because I don’t know how I would do that.

The particle emision is triggered by an AnimationPlayer node flipping the Emit property from false to true. And only at that instant the game knows it needs to load two big textures.

I don’t know how I could make the required resources load earlier in this case.
Is it possible to mark them for preloading in the UI without writing a script or what?
I guess I could write a function to spawn the particle effects from a separate scene and use the preload statement, but will that actually do the trick?

unfa | 2019-12-11 14:02

I’ve added two lines to the Star.gd script which triggers the animation:

const SmokeBaseColor = preload("res://Assets/Smoke/Smoke BaseColor.png")
const SmokeNormal = preload("res://Assets/Smoke/Smoke Normal.png")

I’ve put this right on top. I didn’t do anything else with these resources. But it doesn’t seem to work.

unfa | 2019-12-11 14:43

So preloading didn’t help the initial stutter? Perhaps the issue is when it is initially loaded into the particle system. Can you try smaller textures (like really small, just for comparison), to see if it loads more smoothly? I think the fact that it only happens the first time is really telling. I watched your video, and I’m assuming that it doesn’t matter which star is collected first, it still causes the stutter the first time?

Also, can you isolate the effects and test them one at a time to see if there is a specific effect that is causing the issue?

i_love_godot | 2019-12-11 14:53

:bust_in_silhouette: Reply From: scrubswithnosleeves

I know this is long overdue, but here is a video I just made for anyone in the future encountering this problem:

It is because Godot compiles the particle materials at runtime the first time the particle is instanced.