If you have noticed lag spikes/stutters when instancing particles and particles2D nodes for the first time, you're not alone! Travis Maynard originally wrote a blog post on how to solve this, but I have made some improvements to his method and also wanted to make this info more available. Source code available in the description! EDIT: Also just realized that rather than doing set_modulate() for every particles2D you create in the ready function, you can just do self.set_modulate() to make the canvas node invisible!
This is exceptionally helpful, I've noticed in html the first time i call a particle has such a huge lag spike and wondered why. Will certainty be using this method
Nice video! I think it would be easier to make the ParticlesCache emit a signal like "particles_loaded" instead of using a bool, so in the TitleScreen _ready method you just need to add yield(ParticlesCache, "particles_loaded") on top.
Ok, this is pure genius. The freeze on particles was really noticeable on my project so I'll definitely do this. Wonderfully clear explanation. I also like how you add the bool on the singleton to spread the load. I might go further and apply this method to my procedural terrain and move some of that work to the downtime when the user is logging in through the gateway server and then just pick up what's left when entering the game. One thing I've not looked into yet in Godot is multithreading, this might be a good candidate for that given the fetching waits. On the procedural terrain I could use multiprocessing even.
Thanks for the kind words! I didn't even know you could do threading in Godot! Though I doubt any of my games will be complex enough to benefit from it for a while.
@@acb_gamez I'm quite new to godot, just three months, background in python where multithreading/multiprocessing takes two lines of code. I just assumed you could. Let me google it and see.
@@acb_gamez Yup, threading in the docs: func _ready(): thread = Thread.new() thread.start(self, "_thread_function", "Wafflecopter") Unlike python where multiprocessing and multithreading are very distinct and solve different problems, the Thread primitive basically hands everything off to threads as available dynamically by the look of it. Couldn't be easier, just call the method you want to thread and as long as it's CPU intensive enough to be worth paying the small overhead then you're cooking with gas. Love the docs use of "Wafflecopter" btw! :D They even thread safe "multexes" for avoiding simultaneous memory calls. I'd only look at this if it crashes. Wow, they have "semiphores" for starting and stopping execution all in built and readt to use. Huh, what I was talking about it all inbuilt. That Luis guy that made Godot really is good.
Heya! Sorry for replying so long after your original comment, but I was wondering if you remember how you managed to solve this issue? I'm running into it as well in my 3D game in C# and can't figure out the solution at all...
Thank you so much. Still works on Godot 4.2. Essential if we are going to export the project to the web. However, I did it using _process instead of _physics_process.
I like the idea behind this! Although I have a few questions: 1. Why do we wait 3 frames? Since the game lags during the compilation, the next frame is not going to occur until all compilation is done right? 2. Why not give the singleton a signal that you can connect to the scripts instead of bulking the physics_process function 3. Why make a variable for each material, instead of putting the preload functions inside the array? I'm not very proficient with GDScript, so I apologise for any dumb questions I said. Really appreciate the tutorial however, I can see this being very useful in 3D as well.
Hey Nekoto Arts, 1. Totally arbitrary. You should be right, it should only lag for 1 frame, but I thought I would cover my bases and make it 3 because that is still an infinitesimal amount of time. 2. That is actually close to what I do now, but didn't know Godot well enough at that time. I actually use the yield function in the ready statements of those nodes, but either way works! 3. The array is necessary so we can use a for loop.
Thanks for the video, couldn't find much on this on the Godot forums so I'm happy I found this cause I had a stutter on every first touch input and traced it back to the particle effect that spawned. To me it almost seems like a bug that a new instance of the particle node doesn't compile/calculate the particle effect but every next new instance does, maybe a precalculate() function could be added to get the wanted/expected behavior at runtime. But this is a nice workaround for now :)
Great to hear! They said they will be addressing this in the future releases. They might have even already fixed it in the 3.4 build, but definitely in the 4.0 build if not.
I was happy to find this, but I'm still seeing a spike in frame time when instancing particles (in 3D). I'm using a material override that is set "Local to Scene" because otherwise all the particles would looks the same... maybe this is why? Thanks anyway for the helpful info!
This is a very good idea! Might it work with audio streams to avoid that lag when playing a sound? (If you try to play a sound with audiostreamplayer every certain amount of time you will notice that the tempo is not constant)
In my first loading screen I put a copy of every particle node in side another node. After loading I destroy that parent carrying my particles. It works fine to :)
Good question. It is pretty arbitrary honestly. You could probably get away with 1 frame, but I figured I would use 3 just to be safe in case Godot takes multiple frames to compile the particle materials. 3 frames is ~1/20 of a second, so I figured it covered the bases well while also not causing a noticeable amount of load/wait time.
I learned python first, then a month later I watched HeartBeasts tutorial series and then just started making games! After you get the basics, just making games is def the best thing to do to learn. Start out with simple games first, then move on the complex ones. I also made an intro to GDScript course that takes you through the coding basics you need to get up and running. From there you can watch HeartBeasts Tuts and be good to go!