Stuttering and freezing when moving mouse on a large control

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

Hi! I’ve recently been working on an isometric game, and I would like it to contain 100x100 cells. But I’ve just reached a roadblock that I can’t seem to fix, when the size of the control containing the cells reaches a large size (6400px x 6400px), the game begins to stutter, and even freeze, when I move my mouse around. But when I keep it at 3200x3200 (50x50 cells) it works just fine.

This is very strange as the game itself runs fine when I keep the mouse stationary on a large. I don’t even know where to begin, so here’s a recording. (The sprites are “borrowed” from Rimworld, I’m rubbish at drawing)

I also noted that the recording (filmed using Fraps), also seem to stutter at the same time as I move the mouse around, pointing to some kind of error with how things are rendered (I know very little about this, clearly). When the video “freezes” I’m actually moving my mouse in a circular motion. You can also see the delta acting strange in the print in the upper-right corner.

I’ve also set every single control to “ignore mouse”, but this didn’t seem to fix things at all.

So I just changed the size of my tiles to 32x32, and retained the 3200x3200 resolution. The issue seems to be because of the number of cells on the map. None of them process any inputs, nor do they run any processes. I have them all set to ignore mouse. Does the engine have any particular limit on the number of objects it can handle in a given scene?

vrak | 2017-04-27 19:00

:bust_in_silhouette: Reply From: vrak

Can confirm that a high number of controls, even if they contain nothing, will grind the game to a halt. Repro with the following code inside a project containing only a 100x100 control and a label.

extends Control

func _ready():
	for x in range(0, 100):
		for y in range(0,100):
			var box = Control.new()
			box.set_size(Vector2(1, 1))
			add_child(box)
			box.set_pos(Vector2(1*x, 1*y))
	
	set_process(true)

func _process(delta):
	get_node("Label").set_text(str(delta))

Is there any way to get around this issue? Is there something about controls that stresses the engine more?

Having too many nodes in general will slow the engine down. If you’re going to have a big grid like that it’s better to have one Control node and create a cell class that contains any information you need, and make an array containing those cells. Use custom drawing with _draw to draw the cells.

CowThing | 2017-04-27 23:48

10000 active controls on the tree seems like too much, you may need to find a way to optimize the design.
Also could be better if you turn your answer into a comment, that way will stay unanswered and get more attention.

EDIT: Forgot, run the profiler, it may give a hint to where is the bottleneck.

eons | 2017-04-28 00:10

It would be interesting to figure out what is slowing these down. It can be the graphics, but it could also be the hit detection, which is not using the optimized collision engine grid so it’s possible that Godot performs a simple linear search through all buttons to check bounds. I understand doing that is really slow on 10 000 controls :stuck_out_tongue:

Zylann | 2017-04-28 16:59