#Where in Node Tree to keep track of player stats?

20 messages · Page 1 of 1 (latest)

rancid jungle
#

Hello GDQuest community,

Simple question: What is the cleanest way to keep track of something like an integer called power_level?

Originally I wanted to keep it on the player node themselves, and pass it using a setter function to the player's child node: spell_manager.

Part of the setter function of spell_manager will then update each spell in use to use the appropriate integer value of the current power_level.

This seems too complicated though. Is there not a way to have the player hold onto his own power_level and then when necessary, each spell asks "What is the current power level?"

I guess this is an issue of can children classes start asking questions (calling functions probably) of their parents and grandparents. I've run into this question before and just designed lots of passing information downstream but non upstream.

#

An alternative way I thought of is to have an Array called player_stats and player_stats[0] would be amount of lives, player_stats[1] would be power_level: int, player_stats[2] ... etc

I like this idea because Array's are passed as references and then child nodes can edit the data directly as needed.

This is where I need more expereinced programmer's opinions though, as I'm completely self taught and solo.

rancid jungle
#

ok!

I went with my alternative approach of using an array containing Ints and then passing those down to children so they can interact with them directly.

I also made a dictionary that references the array so that my code is more readable

rich locust
#

if i can give my opinion i recommend using singleton

that means that u can put every variables into another script that can be accessed by any node anywhere, anytime as long as it is in the script that is in the autoload (autoload is where u make singleton).

example:
u have a script in the autoload named Global and u put the variables power_level, level, lives etc.... in there

now in your player node/scene or a child of player node u can call those variables
u can now just simply say
var power_level = Global.power_level
or u can just directly use it
var dmg = Global.power_level * some_modifier
u can also modify it like
Global.power_level = something

this vid will explain it in the fastest way https://youtu.be/u91O9iwG-Ng?si=JIYM6G72GsTfKxKK but ofc if u don't fully understand it there is a lot of videos talking about it online just seach for either "godot autoload" or "godot singleton"

i myself do not know everything about it but its one way to solve your current problem

A brief tutorial that aims to explain how you can use singletons in the Godot games engine

In this video I may refer to myself as "Hacket Dev". I have since changed my online username to "Mossy"

▶ Play video
rancid jungle
#

Ah! Thank you so much. This is the functionality I was searching for, I just forgot what it was.

glad harness
#

Yeah, Globals or file.

#

If you want stats to persist from gameplay to gameplay, you need to store it in file. If you want to just juggle between scenes, Global is enough.

weak shoal
#

Singletons / Autoload has a bunch of drawbacks, Godot 4 supports a more elegant way, it is explained here:
https://www.youtube.com/watch?v=jQvcTiVwUgw&t=3s

▶︎ GODOT 4 COURSES : https://school.gdquest.com/godot-4-early-access

🎓 FREE APP "Learn GDScript From Zero" : https://www.gdquest.com

🎮 FREE INTERACTIVE GODOT TOUR - The Godot Editor - https://www.gdquest.com/tutorial/godot/learning-paths/godot-tours-101/

🗨 DISCORD INVITE : https://discord.gg/87NNb3Z

----------------------------------...

▶ Play video
glad harness
#

Static variable is a variable that shares state between every instance and can also be accessed outside this class.

#

Now for testing, static variables are actually worse because you can create duplicate/empty Global/Singleton node and have it's blank state right away.

#

And in testing, for whole project's lifetime, static variables will have value as you modified it. You can't reset unless you manually set every single each of them or make custom method to reset them all.

#

So while they do have their own usage, static variables are not an answer to every problem related to sharing information between scenes

#

"Originally I wanted to keep it on the player node themselves, and pass it using a setter function to the player's child node: spell_manager. "

I don't think you can just throw static variable inside Player (which is Sprite2D I believe) script. You would have to probably create a new class and then inside this class, you can make static variable. Now, if you don't plan on creating many players, using class might not be ideal.

I use class_name for abstractions (base clases, interfaces), plain data, recipe to create objects from, static interfaces.

#

I mean it is valid if you want to check for example if Sprite2D is Player

#

Other way would be to use some enum, check concrete object or look for unique method etc.

#

So yeah @rancid jungle , there are many ways to do that. Find one you like and stick to it as long as it fits your purpose.

#

Singletons are valid choice, specially if you group many data types together that are not strictly related to each other and you should have to read from multiple class static variables

#

And specially if you want to add some logic to that

#

For example, singleton can run method that will parse/check text file in background and fill array with necessary data as you start application. It's a node, it's _ready method activates during runtime.

Same if you want to wrap changing this value you want to share between scenes. You can write method change_value(new_val) and this method can clamp your new_val to ranges available.