How do functions work in GDscript exactly?

Godot Version

Godot 4.2


Hello! I started to learn Godot 4.2 a week ago. I’m a beginner in coding. As my first project, I’m developing a simple incremental idle game. I have 10 upgrade tiers in this game for upgrading gained currency per second. I wrote the first tier’s code like this:

func _on_cpu_button_pressed(): if goldAmount > cpu_cost or goldAmount == cpu_cost: # If player’s gold is enough to buy a cpu cpu += 1 # Increase cpu by one goldPerSecond += cpu_value # Increase GPS by cpu’s value goldAmount -= cpu_cost cpu_cost *= 2 # Make the cpu’s cost double $ else: show_error_message() $

And it’s worked flawlessly. ( I know it’s probably very inefficient but it’s simple enough to me understand.) Then I started to write the same code for other upgrade tiers with copy-pasting. After the third one, I got bored and thought “Well maybe I can use a function to automate this?” By using the documentary I came up with this:

func handle_upgrade(upgrade_value, upgrade_cost, upgrade_variable): if goldAmount >= upgrade_cost: upgrade_variable += 1 # Increase the corresponding upgrade variable goldPerSecond += upgrade_value # Increase GPS by the upgrade's value goldAmount -= upgrade_cost upgrade_cost *= 2 # Double the upgrade's cost $ else: show_error_message() $ ``

then used it with another upgrade button

func _on_ram_button_pressed(): print("Before upgrade: ram =", ram, "ram_cost =", ramCost) handle_upgrade(ram_value, ramCost, ram) print("After upgrade: ram =", ram, "ram_cost =", ramCost)

It prints:

Before upgrade: ram =0ram_cost =100ram_value =1 After upgrade: ram =0ram_cost =100ram_value =1

It correctly upgrades gold gained by seconds but it doesn’t remove the cost for it and also doesn’t double the cost for it. I’m lost.

The way I see it, it works for half of the variables while doesn’t work for the other half. Code is the same as manual writing and using a function to write it. Can anybody explain it, please?


Make sure to format your code. Press the </> button above the textfield and paste your code where it says to do so.
It’s hard to read and people maybe don’t want to help you.

Also it would be helpful to have everything needed, like where you declared the variables etc.

func handle_upgrade(upgrade_value, upgrade_cost, upgrade_variable):
	if goldAmount >= upgrade_cost: 
		# Increase the corresponding upgrade variable
		upgrade_variable += 1
		# Increase GPS by the upgrade's value
		goldPerSecond += upgrade_value  
		goldAmount -= upgrade_cost
		# Double the upgrade's cost 
		upgrade_cost *= 2 	

Do you have a global upgrade_cost variable? Global meaning outside any functions?
In your upgrade function you are doubling the upgrade_cost variable you used as parameter and not the one that is outside the function I guess.

EDIT again ^^: global variables = outside any functions, local variables = variables that are declared within a function or passed in as parameter.

You can use self. to use the global variable, but imho it’s better to name variables differently. Here a little test to demonstrate:

var var1 = 1

func _ready() -> void:

func test(var1):
	var1 += 100

func test2(var1):
	self.var1 += var1



Just for completion: Things like characterbody or other objects are passed in as references. Meaning you actually access the thing you pass into the function like you did by accident (but with the wrong type).

1 Like

Thank you for your answer. Sorry about textfield, this was my first post so I didn’t know how to use it. I’ll use it from now on.

I declared upgrade_cost outside of a function just like goldPerSecond variable.

I did some research about function parameters. Are my findings correct?

When you try to use a function like my purpose, there are two types. Values and references. Ints, floats, and strings are normal values and you can use them in but not out. This means you can use their values in your function but you can’t use the function to change their values because the variables inside it are new values not the same.

References are like dictionaries arrays etc They’re already references themselves. So when you use them in function, it’s still not the same variable, but it’s a reference anyway so it can be changed.

Also, there’s a third way. Creating a new class and defining your variable in it. Then you can reference it inside of function I assume.

I tried self. method but it didn’t worked.

1 Like

Hey, no problem. That’s why I mentioned it. Most new users don’t know that code formatting exists.

Yes, your findings are correct! :slight_smile:

Regarding classes and variables, they behave like what you described.
Passing instances of classes as parameter will be references, but If you pass in a property of a class it depends on its type.

1 Like