Lag spikes every ~1s using C# in 3.0RC1

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By madgit
:warning: Old Version Published before Godot 3 was released.

Hi,

I’m using 3.0RC1 with Mono, trying out C# scripts. I have a simple project that’s making meshes from simple Minecraft-like block chunks. It runs at ~160fps with vsync off so that’s fine, however every second or so I get stutters lasting a few whole frames.

Looking at the perf monitor I get downward spikes every ~1s, and the list of functions on the left is almost empty during those down spikes, indicating to me that the engine isn’t “doing” my code or the game at all for those few frames. Usually you see the list of Physics Time, Script Functions etc but in one of those spikes that mostly disappears to be left with just Script Functions and under it, do_player_movement (simple GDScript reading keys) and _process, both of which take 0.000 time.

Perf monitor during “normal” running period:

Perf monitor during one of the laggy spikes

Is it possible I’m seeing C# garbage collection or something? Why would it keep triggering every ~1s? The only scripts I have are those that create chunks on startup, once-only, and during running there’s nothing happening except moving the camera around by key. No C# scripts running at all to cause GC. I’ve minimised the obvious object creation (I don’t have huge arrays of Block objects, just simple arrays of int block types per chunk) and I can’t think where else the spikes might be coming from.

Interestingly, if I change the chunk size from 16x16x16 to 32x32x32 (thus getting much bigger chunk meshes but fewer of them) and simultaneously reduce the “radius” around the player from 4 chunks to 2 (to maintain the same overall distance), the spikes are basically gone. Could it be something in the graphics pipeline that’s thrashing every ~1s? (32 size chunks give ~250 surface changes & draw calls, 16 size chunks give ~2000 surface changes & draw calls, according to the Monitor).

Could it be something to do with the debugging and it might all vanish if I were able to export (can’t do this with Mono yet) ?

Thoughts?

:bust_in_silhouette: Reply From: Zylann

When you run the game, is the scene tree set to “remote” or “local”? Remote scene tree can cause this spike at regular interval if you have a lot of nodes in your scene (which would explain why increasing chunk size reduces lag). You can switch to local to make it go away, see The Remote Scene Tree causes jerky movement everytime it updates · Issue #13219 · godotengine/godot · GitHub

If it’s not this… then it could be the garbage collector, indicating that you might allocate stuff constantly so it collects constantly too.

Thank you thank you! It’s the remote scene tree causing it - disable that in Editor Settings/Debugger and no more laggy spikes. Wonderful!

Now I guess I need to research what exactly a “remote scene tree” IS, and whether I wanted one now I can’t have it :slight_smile:

madgit | 2018-01-18 19:44

The remote scene tree basically displays the nodes your game contain at runtime, so you can inspect them and see their states.

Zylann | 2018-01-18 20:30

THANK YOU SO MUCH

Using GDScript, and I can’t believe I didn’t try this yet.


When I had several thousand objects in memory and a couple thousand nodes in the Scene Tree (working on a Text Editor), I kept getting this huge lag spike every second or so.

I’d enter text in my Scene (which adds new Nodes), getting around 15-30 fps, then it would drop to 0 fps for a moment, then back up. [See footnote]

I’ve been excessively trying to optimize my node usage and code, thinking the project itself was too heavy.

But I just clicked “Local” in the Scene Tree, and now getting solid constant 60 fps. No lag at all.

I’ve been puzzling and puzzling trying to figure out this lag spike.

Your comment saved me, thank you.

Background : Until now I’ve always had Remote selected in the Scene Dock while running my project.


Footnote:
@anyone in the future, in Godot 3.2 the Debugger → Monitors tab seems to average out the FPS monitor. For me it never accurately logs a dip to 0fps – even when it has definitely frozen for a moment.

gamepad_coder | 2020-11-26 02:27