I was reading the official Godot docs and in code examples, variables are added in the process_() function, which confuses me a bit. Doesn't that mean that the variable gets redeclared every frame? It may just be my Javascript senses, but I find it a bit weird to put the "var" keyword inside a function that gets repeated every frame.

In GDScript var keyword works different than in JavaScript. Scope of variable depends on place where you define it.


extends Node


var class_variable = "can acces from whole class and other classes"


func _ready():
	var func_variable = "can access from definition to the end of func"
	for x in 1:
		var block_variable = "can acces from definition to the end of for block"

@pkowal1982 said: In GDScript var keyword works different than in JavaScript. Scope of variable depends on place where you define it.


extends Node


var class_variable = "can acces from whole class and other classes"


func _ready():
	var func_variable = "can access from definition to the end of func"
	for x in 1:
		var block_variable = "can acces from definition to the end of for block"

I perfectly know how scopes work, but I thought the _process() function is called every frame. Is that true?

The added overhead resulting from declaring local variables in _process() should be negligible.

You don't want variables that are just used for counting to be global. You declare it in a function because you want it to be gone when the function is done. Global variables (class wise) are variables needed outside of functions to retain a value. I like to keep as much code as possible out of the process function. Makes it more readable. If you have ever seen people making a platformer with all that code in the process function, you will know what I mean. Instead, use a match statement to call state functions from an enum.

This is an easy question to answer. Just time the process function both ways with the profiler. On my system (out of two trials), I get:

class variable: #1 0.005854ms #2 0.006317ms local variable: #1 0.005719ms #2 0.005931ms

So, either local variables in _process() are slightly more efficient, or the difference is so small that the normal fluctuations of processing on my system make it impossible to measure.

@duane said:

So, either local variables in _process() are slightly more efficient, or the difference is so small that the normal fluctuations of processing on my system make it impossible to measure.

Definitely looks like margin of error to me.

@Megalomaniak said: Definitely looks like margin of error to me.

If it's not error in measurement, then it's probably because the one local variable in my test is being mapped to a register. The class variable has to be retained, which could involve more overhead.

I encourage everyone to test it on their systems. One experiment is worth ten theories.

You should aim for code clarity. Not making premature optimizations of things that have no effect on performance. Declaring variables where there are needed in scope is best, as not to pollute the class namespace with one-use variables or promote unintended side-effects. Plus, a single graphic feature, like say shadow mapping, could take 10ms, so any variable optimization in process would have no effect. You could likely declare a thousand variables, and it would still not be longer than 10ms, in which case there would be no difference in the FPS.

I mean I bet both those values will vary between runs, don't measure it once, measure it ten times or a hundred.

8 months later