Hi, i’m a bit confused about the Godot styling guidelines for private and virtual functions (prepending the function name with an underscore) and I would like to clarify my understanding of that topic. Couldn’t that be sometimes contradictory or confusing?
I have an example from a short video I’m learning from. I’m aware that the author doesn’t really follow the official styling guide, but I’m not sure that I get the thought process here:
A private function means it is never called outside of its class, right?
In this case:
_update() is called from parent node _physics_process().
update() is meant to be overridden in child classes.
So, if I want to follow the Godot style guide, should I simply swap their names? Is it simply personal guidelines preferences or am I missing something?
And as a small side question: is there a meaning for prepending a function parameter name with an underscore (as “_input” in update() in this example)?
You can call base-class overriden functions with super, so this separation may not be needed.
func base_update(delta: float) -> void:
print("I am the base class", delta)
# in extended script
func base_update(delta: float) -> void:
super.base_update(delta) # prints "I am the base class"
print("I am the extended class")
I find the underscore on Godot built-in functions like _process help to denote virtual functions that can be overridden, for virtual/override functions the underscore does matter as the name must be exactly the same, so process will do nothing on it’s own while _process is automatically called every frame.
A warning is produced when you define unused variables, by prepending _ Godot will ignore the warning, it asserts you understand the argument is unused and want it to remain that way.
I took a look at that video, and this is an over-engineered solution for the problem he’s trying to solve to begin with.
In Godot, we typically say you should call down (execute functions) and signal up. A parent node calling down should only be calling public functions. A private function should only be used by the script itself.
In your example, there should only be a single public function. If you want to override it, you can either call it or not with super()
Thank you for your answers
So, my initial understanding is correct (names should be swapped according to GDScript style guide), and without splitting the function in two, update() would actually neither be a private or a virtual function.
I can’t think of a good reason to actually split it, so I’ll stick with super(), as you suggest.
Thanks, I already encountered these warnings, but I didn’t fully understand the usecase. I understand now it can be useful for virtual functions at least. If I understand it correctly, what is called a virtual function NEVER have an implementation in its base class, right?
No, virtual functions (which are all GDScript functions) can be implemented in the base class and overridden later by extended classes. If marked with @abstract then yes the virtual function does not exist on the base class and also means the base class is impossible to instantiate on it’s own as it’s missing a vital function.
Godot built-in virtuals like _process are special because they bridge from core C++ code into GDScript, _process doesn’t really exist as a function on Node-extended classes. So they are kind of in-between being @abstract and a normal function.
Ok, I’m still a bit confused then. Are virtual functions only the Godot Built-In functions?
If I create my own empty function meant only to be overridden in child class, is there a specific term to name it? And according to the style guide, should I prepend it with _ ?
There are plenty of built-in C++/core functions like Vector3.normalized(), the built-in virtual functions are a little stranger than GDScript functions, they happen to be prefixed with _ I’d assume not because they are virtual but because it would be strange to call another node’s _process or _ready, so they are good candidates as private functions. I haven’t seen a built-in virtual that wasn’t prefixed with _ and I suppose that also tracks as the engine will automatically call the function, usually for it’s side effects- it would be strange to also call it elsewhere.
Most would call it a virtual function, for Godot it’s a regular function.
Only if you don’t intend other scripts to use this function. i.e if you see other._function the ._ should be a red flag that maybe this function shouldn’t be used.
Ok, I (kind of) begin to understand why private and virtual have the same styling guideline.
I also understand Godot doesn’t have real private or virtual function, it’s mostly styling and readability. But without good reason to do otherwise, I’m trying to understand what is relevant of these categories and to stick to the official style guide:
GDScript style guide:
Prepend a single underscore (_) to virtual methods functions the user must override, private functions, and private variables:
I believe you are conflating the two. A private function or variable is prepended with an underscore (_) by convention. That’s it. That’s the whole rule.
A virtual function is technically a function that can be overridden in a derived class. In GDScript, any function that is created with GDScript can be a virtual function. In classes created in C++ for GDScript, only virtual functions can be used as virtual functions. By convention, those functions happen to all be private functions. (That was a change made between 3.x and 4.x.)
That is partially for the former, but not the latter. You are conflating “Godot” with “GDScript”.
GDScript does not have a concept of access modifiers (private/public/protected). However other languages like C# do have those access modifiers and they can be used in Godot.
Likewise, in GDScript, any function you declare can be overridden, and therefore technically is virtual. Again, in other languages, you must declare them properly depending on the language. The style guide recommends prepending virtual functions with an underscore, but it you have an interface you’ve made with a public function, it’s ok to override it.
Part of the confusion comes from how the terminology is used in the docs. They call built-in abstract functions that user is supposed to override - “virtual”. In GDScript, similarly to Python, every function is virtual in strictly technical sense of the term. Since those built in functions are meant to be called almost exclusively by the underlying engine code - is makes sense to consider them “private” - hence they all follow the underscore prefix convention.
Yes, I totally meant GDScript, sorry for the confusion and thanks for rephrasing it clearly.
From the style guide, the rule is to prepend both private and virtual functions. That’s where my confusion came from. I was trying to clarify these concepts in the context of GDScript and its style guide application. (I was wondering why they have the same style guide? does the concepts mostly overlaps in practice. etc… more in terms of conventions/best practices than technical feasibility)
Thank you for your answers
I’m actually self-taught, and I am learning all of this within the GDScript context (and previously Unreal Blueprints, which actually have these access modifiers), but I still don’t know much from a more theorical point of view.