From a264154c9d3a44dd6405a1bc709b3b0c407f017e Mon Sep 17 00:00:00 2001 From: Malcolm Anderson Date: Thu, 6 Feb 2025 14:42:55 -0800 Subject: [PATCH] Add GDScript warning pages --- .../scripting/gdscript/gdscript_basics.rst | 3 + tutorials/scripting/gdscript/index.rst | 1 + .../get_node_default_without_onready.rst | 55 +++++++++++++++++++ .../scripting/gdscript/warnings/index.rst | 27 +++++++++ .../gdscript/warnings/integer_division.rst | 43 +++++++++++++++ .../warnings/return_value_discarded.rst | 42 ++++++++++++++ .../gdscript/warnings/shadowed_variable.rst | 40 ++++++++++++++ .../gdscript/warnings/unassigned_variable.rst | 35 ++++++++++++ .../gdscript/warnings/unused_variable.rst | 52 ++++++++++++++++++ 9 files changed, 298 insertions(+) create mode 100644 tutorials/scripting/gdscript/warnings/get_node_default_without_onready.rst create mode 100644 tutorials/scripting/gdscript/warnings/index.rst create mode 100644 tutorials/scripting/gdscript/warnings/integer_division.rst create mode 100644 tutorials/scripting/gdscript/warnings/return_value_discarded.rst create mode 100644 tutorials/scripting/gdscript/warnings/shadowed_variable.rst create mode 100644 tutorials/scripting/gdscript/warnings/unassigned_variable.rst create mode 100644 tutorials/scripting/gdscript/warnings/unused_variable.rst diff --git a/tutorials/scripting/gdscript/gdscript_basics.rst b/tutorials/scripting/gdscript/gdscript_basics.rst index 90e0aaab65d..4c9b1bef4d7 100644 --- a/tutorials/scripting/gdscript/gdscript_basics.rst +++ b/tutorials/scripting/gdscript/gdscript_basics.rst @@ -1593,6 +1593,9 @@ Lambda functions capture the local environment: lambda.call() print(a) # Prints `[1]`. + +.. _doc_gdscript_basics_static_functions: + Static functions ~~~~~~~~~~~~~~~~ diff --git a/tutorials/scripting/gdscript/index.rst b/tutorials/scripting/gdscript/index.rst index 909e3bf986f..2a7e3498c20 100644 --- a/tutorials/scripting/gdscript/index.rst +++ b/tutorials/scripting/gdscript/index.rst @@ -16,4 +16,5 @@ GDScript gdscript_styleguide static_typing warning_system + warnings/index gdscript_format_string diff --git a/tutorials/scripting/gdscript/warnings/get_node_default_without_onready.rst b/tutorials/scripting/gdscript/warnings/get_node_default_without_onready.rst new file mode 100644 index 00000000000..01802910bf6 --- /dev/null +++ b/tutorials/scripting/gdscript/warnings/get_node_default_without_onready.rst @@ -0,0 +1,55 @@ +GET_NODE_DEFAULT_WITHOUT_ONREADY +================================ + +This warning appears when a node's property is initialized to a node in the scene tree +without using the ``@onready`` annotation. + +Depending on how you attempt to access the scene tree, the warning message will +be one of the following: + +.. code-block:: none + + The default value uses "get_node()" which won't return nodes in the scene tree before "_ready()" is called. Use the "@onready" annotation to solve this. + + The default value uses "$" which won't return nodes in the scene tree before "_ready()" is called. Use the "@onready" annotation to solve this. + + The default value uses "%" which won't return nodes in the scene tree before "_ready()" is called. Use the "@onready" annotation to solve this. + +The default warning level for this warning is **Error**. +To modify it, set :ref:`Project Settings > Debug > GDScript > Warnings > Get Node Default Without Onready`. + +When this warning occurs +------------------------ + +This warning may appear when attempting to assign the default value of a property +to a node in the scene tree, like so: + +.. code-block:: gdscript + + extends Area2D + + # Will give warning GET_NODE_DEFAULT_WITHOUT_ONREADY. + var my_collision_shape = $CollisionShape2D + +If you want a property to refer to another node in the scene tree, you may be inclined +to reference it using :ref:`get_node() ` +(or the ``$`` and ``%`` shorthand versions) when setting its default value. + +However, properties' default values are evaluated and assigned *before* nodes are added to the scene tree. +This means that when the script tries to assign that value, it won't be able to find the node it's looking for, +because it isn't a part of the scene tree containing that node yet. +As a result, the property will be set to ``null`` instead. + +How to fix this warning +----------------------- + +Add the ``@onready`` annotation before your property declaration: + +.. code-block:: gdscript + + extends Area2D + + @onready var my_collision_shape = $CollisionShape2D + +Now, the default value of the property will not be assigned until the scene tree has been initialized, +at which time the node will be present. diff --git a/tutorials/scripting/gdscript/warnings/index.rst b/tutorials/scripting/gdscript/warnings/index.rst new file mode 100644 index 00000000000..fe38f33b6bc --- /dev/null +++ b/tutorials/scripting/gdscript/warnings/index.rst @@ -0,0 +1,27 @@ +:allow_comments: False + +.. _doc_gdscript_warnings: + +GDScript warnings +================= + +This is a collection of warnings that GDScript can emit, and information on how to fix the code that causes them. + +.. note:: + + The list of warnings is currently incomplete. We hope to add pages for more warnings over time, + so that each one can be thoroughly reviewed for correctness and clarity. + +.. rubric:: Warnings + :heading-level: 2 + +.. toctree:: + :maxdepth: 1 + :name: toc-gdscript-warnings + + get_node_default_without_onready + integer_division + return_value_discarded + shadowed_variable + unassigned_variable + unused_variable diff --git a/tutorials/scripting/gdscript/warnings/integer_division.rst b/tutorials/scripting/gdscript/warnings/integer_division.rst new file mode 100644 index 00000000000..07411b98898 --- /dev/null +++ b/tutorials/scripting/gdscript/warnings/integer_division.rst @@ -0,0 +1,43 @@ +INTEGER_DIVISION +================ + +The warning message is: + +.. code-block:: none + + Integer division. Decimal part will be discarded. + +The default warning level for this warning is **Warn**. +To modify it, set :ref:`Project Settings > Debug > GDScript > Warnings > Integer Division`. + +When this warning occurs +------------------------ + +This warning may appear when attempting to divide two integers: + +.. code-block:: + + var result = 5 / 3 # Will give warning INTEGER_DIVISION. + +Because both operands are integers, the result will be an integer as well. +Integers can't store fractional parts of numbers, so the result must be a whole number. +Godot discards anything after the decimal point in the mathematical result to obtain the integer result. +**Note that the number is not rounded to the nearest whole number.** + + +How to fix this warning +----------------------- + +Use a floating-point number (``float``) for at least one operand of the division operation: + +.. code-block:: + + var result = 5.0 / 3 + +If the integers being divided are variables, cast them to ``float``: + +.. code-block:: + + var a: int = 5 + var b: int = 3 + var result = float(a) / float(b) diff --git a/tutorials/scripting/gdscript/warnings/return_value_discarded.rst b/tutorials/scripting/gdscript/warnings/return_value_discarded.rst new file mode 100644 index 00000000000..ebbc8f45032 --- /dev/null +++ b/tutorials/scripting/gdscript/warnings/return_value_discarded.rst @@ -0,0 +1,42 @@ +RETURN_VALUE_DISCARDED +====================== + +The warning message is: + +.. code-block:: none + + The function "get_number()" returns a value that will be discarded if not used. + +The default warning level for this warning is **Ignore**. +To modify it, set :ref:`Project Settings > Debug > GDScript > Warnings > Return Value Discarded`. + +When this warning occurs +------------------------ + +This warning may appear if a method returns a value, but that value is not used +in an expression or assigned to a variable: + +.. code-block:: + + func _ready(): + print("About to get a number...") + get_number() # Will give warning RETURN_VALUE_DISCARDED. + print("Got a number!") + + func get_number() -> int: + return 5 + +How to fix this warning +----------------------- + +Assign the returned value to a variable for use later. + +.. code-block:: + + func _ready(): + print("About to get a number...") + var num = get_number() + print("Got a number! It's %s" % num) + +However, some methods in Godot's APIs return values that are not necessary to store. +As such, depending on the situation, it may make more sense to ignore this warning. diff --git a/tutorials/scripting/gdscript/warnings/shadowed_variable.rst b/tutorials/scripting/gdscript/warnings/shadowed_variable.rst new file mode 100644 index 00000000000..a3a8b1d7523 --- /dev/null +++ b/tutorials/scripting/gdscript/warnings/shadowed_variable.rst @@ -0,0 +1,40 @@ +SHADOWED_VARIABLE +================= + +The warning message is: + +.. code-block:: none + + The local variable "level" is shadowing an already-declared variable at line 3 in the current class. + +The default warning level for this warning is **Warn**. +To modify it, set :ref:`Project Settings > Debug > GDScript > Warnings > Shadowed Variable`. + +When this warning occurs +------------------------ + +This warning may appear when giving something the same name as a variable previously +defined in the class. + +.. code-block:: + + extends Node + + var level = 3 + + func _ready(): + # Will give warning SHADOWED_VARIABLE. + var level = 1 + print("Time for level %s" % level) + +In this example, the script class has a property ``level`` which can be accessed from its functions. +However, at the first line of ``_ready()``, a new ``level`` variable is declared for that function specifically. +After this declaration, any references to ``level`` will go to that version and not the shared variable for the class. +This is called *shadowing*. + + +How to fix this warning +----------------------- + +Change the name to something that isn't being used by the class. +For example, if receiving a warning about using the identifier ``level``, consider using something more descriptive like ``new_level``. diff --git a/tutorials/scripting/gdscript/warnings/unassigned_variable.rst b/tutorials/scripting/gdscript/warnings/unassigned_variable.rst new file mode 100644 index 00000000000..3227001a4c7 --- /dev/null +++ b/tutorials/scripting/gdscript/warnings/unassigned_variable.rst @@ -0,0 +1,35 @@ +UNASSIGNED_VARIABLE +=================== + +The warning message is: + +.. code-block:: none + + The variable "my_var" is used before being assigned a value. + +The default warning level for this warning is **Warn**. +To modify it, set :ref:`Project Settings > Debug > GDScript > Warnings > Unassigned Variable`. + +When this warning occurs +------------------------ + +This warning may appear when attempting to use a variable that hasn't had a value +assigned to it yet. + +.. code-block:: + + var my_var + print(my_var) + +By default, the variable will be ``null``. However, Godot considers this a warning +because the user did not explicitly assign the value, and as such might be unaware of it. + +How to fix this warning +----------------------- + +Assign a value to the variable before including it in an expression or function call: + +.. code-block:: + + var my_var = 5 + print(my_var) diff --git a/tutorials/scripting/gdscript/warnings/unused_variable.rst b/tutorials/scripting/gdscript/warnings/unused_variable.rst new file mode 100644 index 00000000000..16321e5acc7 --- /dev/null +++ b/tutorials/scripting/gdscript/warnings/unused_variable.rst @@ -0,0 +1,52 @@ +UNUSED_VARIABLE +=============== + +The warning message is: + +.. code-block:: none + + The local variable "counter" is declared but never used in the block. If this is intended, prefix it with an underscore: "_counter". + +The default warning level for this warning is **Warn**. +To modify it, set :ref:`Project Settings > Debug > GDScript > Warnings > Unused Variable`. + +When this warning occurs +------------------------ + +This warning may appear when a variable is declared, but never used before its +function or scope ends: + +.. code-block:: + + extends CharacterBody2D + + func _process(delta): + var player_speed = 5.0 # Will give warning UNUSED_VARIABLE. + velocity = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") + move_and_slide() + +In this example, the variable ``player_speed`` is presumably meant to control how +fast the player moves. However, ``velocity`` never actually takes into account +this speed variable; it only uses the result of ``Input.get_vector()``. +It's likely that the programmer meant to include ``player_speed`` here somehow but forgot to write it. + +How to fix this warning +----------------------- + +If a variable is being marked as unused, you probably meant to use it somewhere +but forgot to include it in the relevant statement. Following the example above, +the likely solution would be to incorporate it into the calculation of ``velocity``: + +.. code-block:: + + velocity = player_speed * Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") + +If you're certain you don't need the variable for anything right now, but might +need its value later on, prefix its name with an underscore (``_``) as the warning text suggests. +Once you start referencing it elsewhere in the code, you can remove the underscore. + +.. code-block:: + + var _player_speed = 5.0 # Will not give warning UNUSED_VARIABLE. + +If you know you won't ever need the variable, then simply delete it.