The Pause Handler: Working around Godot 4’s particle jitter bug
Godot Engine 4 has a bug (#50824) that causes particle jitter when the game is paused. It does look quite distracting.
The Bug in Action
This is a proof-of-concept wave shooter running in Godot Engine 4.0.2. Pausing the game was initially just a simple process_mode toggle. But as shown in the video clip above, there is a noticeable and quite distracting jitter for every particle effect that apparently stems from some interpolation issue.
To work around it, I wrote a small pause handler script that hides all the GPU particle effects:
class_nameGGPauseHandlerextends Node## The pause component allows you to toggle the game.#### While paused, it will hide particle effects to prevent visual jitter.## The issue is present in Godot 4 (tested until 4.0.2).#### @tutorial(Github Issue #50824: Particle jitter on low speed scale or when the SceneTree is paused due to interpolation): https://github.com/godotengine/godot/issues/50824signalpause_toggled(paused:bool)## The nodes' meta data field used to keep stateconstMETA_FIELD="gg_pause"## This game node will have its [member Node.process_mode] adjusted to pause the game@exportvar game:Node## The action name (in the [InputMap]) for pausing the game.@exportvar pause_action_name:String="pause"## Hides/unhides particles when toggling to prevent jitter@exportvar hide_particles:bool=truefunc_ready():assert(game isNode, "Must specify the node that will be paused")assert(InputMap.has_action(pause_action_name), "Please ensure the action '%s' is configured (Project Settings..., Input Map)"% pause_action_name)## Pragmatic way to listen to [InputEvent]s and check whether the pause key/button was pressedfunc_input(event:InputEvent):if event isInputEventKeyand event.is_action_pressed(pause_action_name):toggle_pause()## Toggle pausefunctoggle_pause():if game.process_mode==PROCESS_MODE_INHERIT:if hide_particles:_hide_particles() pause_toggled.emit(true) game.process_mode=PROCESS_MODE_DISABLEDelse:if hide_particles:_show_particles() pause_toggled.emit(false) game.process_mode=Node.PROCESS_MODE_INHERIT## Find and hide all GPUParticle2D effectsfunc_hide_particles():for node inget_tree().root.find_children("*","GPUParticles2D",true,false): node.set_meta(META_FIELD, node.visible) node.visible=false## Restore visibility of all previously hidden GPUParticle2D effectsfunc_show_particles():for node inget_tree().root.find_children("*","GPUParticles2D",true,false):if node.has_meta(META_FIELD): node.visible= node.get_meta(META_FIELD) node.remove_meta(META_FIELD)
Now when the game is paused, the jitter is hidden away from the player, making the experience much more pleasant. Once the bug is fixed, it’s easy to disable or remove the hiding logic. The result looks pretty good.
The
pause_toggled
signal allows other nodes to react to pausing as well, which I’m using to show/hide the UI accordingly.
The Workaround Applied
I’m only writing the code here. The assets used are:
This release addresses an issue that arose due to Godot 4.4 changes in how JSON is deserialized. Relevant Godot issues: #103374 and #61464. Makes sense why it was changed, but it might impact anyone unaware who’s consuming a JSON-based API, and wondering why responses may not be as expected. In addition, this release now includes character damage and …
A new version of the Inventory System is available with more multiplayer-related features. The Multiplayer Interaction Demo can now run in multiple modes, through two separate implementations of the Character scene: The simple character scene leverages the MultiplayerSynchronizer and can either let the client have authority and move the character, or have the client send …
Hugo-Dz created Super Godot Galaxy: https://github.com/Hugo-Dz/super-godot-galaxy, which he announced in this Reddit post. It uses the 3D Starter Kit from Kenney and shows how to achieve the effect of applying gravity toward the center of a small spherical planet.
This release finally uses Godot Engine 4.4. It adds the GGCraftingSystem singleton and updates the GGInteractable2DStrategyCrafting class to use it. The crafting editor nodes now have prefixes, which makes it much easier to search for specific recipe or item nodes in larger crafting libraries. Some syntactic sugar was added as well. You can now easily …
The Pause Handler: Working around Godot 4’s particle jitter bug
Godot Engine 4 has a bug (#50824) that causes particle jitter when the game is paused. It does look quite distracting.
The Bug in Action
This is a proof-of-concept wave shooter running in Godot Engine 4.0.2. Pausing the game was initially just a simple process_mode toggle. But as shown in the video clip above, there is a noticeable and quite distracting jitter for every particle effect that apparently stems from some interpolation issue.
To work around it, I wrote a small pause handler script that hides all the GPU particle effects:
Now when the game is paused, the jitter is hidden away from the player, making the experience much more pleasant. Once the bug is fixed, it’s easy to disable or remove the hiding logic. The result looks pretty good.
The
pause_toggledsignal allows other nodes to react to pausing as well, which I’m using to show/hide the UI accordingly.The Workaround Applied
I’m only writing the code here. The assets used are:
The ship controls and wave transitions are loosely inspired by Galactix, a game released in 1993 (and set in the far-away future of 2019).
Related Posts
Inventory System 2 Alpha 5 available
This release addresses an issue that arose due to Godot 4.4 changes in how JSON is deserialized. Relevant Godot issues: #103374 and #61464. Makes sense why it was changed, but it might impact anyone unaware who’s consuming a JSON-based API, and wondering why responses may not be as expected. In addition, this release now includes character damage and …
Inventory System v1.14 available
A new version of the Inventory System is available with more multiplayer-related features. The Multiplayer Interaction Demo can now run in multiple modes, through two separate implementations of the Character scene: The simple character scene leverages the MultiplayerSynchronizer and can either let the client have authority and move the character, or have the client send …
Super Godot Galaxy Concept
Hugo-Dz created Super Godot Galaxy: https://github.com/Hugo-Dz/super-godot-galaxy, which he announced in this Reddit post. It uses the 3D Starter Kit from Kenney and shows how to achieve the effect of applying gravity toward the center of a small spherical planet.
Inventory System 2 Alpha 4 available
This release finally uses Godot Engine 4.4. It adds the GGCraftingSystem singleton and updates the GGInteractable2DStrategyCrafting class to use it. The crafting editor nodes now have prefixes, which makes it much easier to search for specific recipe or item nodes in larger crafting libraries. Some syntactic sugar was added as well. You can now easily …