+5 votes

What is the importance of the leading underscore on certain functions/methods? For example, something like func _shoot() versus func shoot().

in Engine by (104 points)

1 Answer

+13 votes
Best answer

It can mean a few different things, but it's always just a convention in those circumstances. There is no "enforcement" by the language or rules. Rather, it is simply a way of conveying information to the one reading the source code so that they have a better idea of the meaning behind the method. Uses include:

  1. The method is "private", i.e. it is meant to only be used internally by the class. Other classes outside the scope of the class shouldn't attempt to access it. Many other statically-typed languages actually force this with a private keyword (C++, C#, Java, etc.), but in GDScript, everything is public on a technical level (you can manually call _shoot even from outside the object, even if it has a leading underscore).

  2. The method is "virtual" meaning that it is intended to be overridden by a derived class. This may be the case if a script has a custom function with a pass in it.

    func _shoot():
        pass # let someone derive this class and define what "shooting" means.

    This is useful if, say, you want to define a base class that does some boilerplate features, but you want people to extend that base class and inject their own behavior into the middle of those predefined operations, e.g. if I shared my own Ranger class with you that has movement, vision, collision logic, a sprite, etc., but I wanted you to be able to say what happens when they attempt to "shoot" arrows.

  3. In Godot, there is a third case: The method is a "notification", i.e. it is a convenience function that provides users with easy access to certain subsections of the core iteration loop in godot: _notification(what). The "what" here is an enum that can hold various integer values defined in the global scope with the NOTIFICATION_* prefix. For example, _ready() is a shortcut for...

    func _notification(p_what):
    match p_what:
            # _ready() content goes here

    There are similarly NOTIFICATION_PROCESS, NOTIFICATION_PHYSICS_PROCESS, and even values that don't have shortcut methods like NOTIFICATION_TRANSFORM_CHANGED which is triggered on CanvasItem nodes (Node2D/Control) when they are moved, rotated, or scaled. Each of the shortcut methods for a notification have a leading underscore in front of them.

    To see what notification enums exist, you should look for "NOTIFICATION_" in the docs and see what pops up. Different classes may use different values and they're displayed as constants for that specific class.


by (104 points)
edited by

Thanks so much for the clear explanation

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.