Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions tutorials/scripting/gdscript/gdscript_basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1593,6 +1593,9 @@ Lambda functions capture the local environment:
lambda.call()
print(a) # Prints `[1]`.


.. _doc_gdscript_basics_static_functions:

Static functions
~~~~~~~~~~~~~~~~

Expand Down
1 change: 1 addition & 0 deletions tutorials/scripting/gdscript/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ GDScript
gdscript_styleguide
static_typing
warning_system
warnings/index
gdscript_format_string
Original file line number Diff line number Diff line change
@@ -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<class_ProjectSettings_property_debug/gdscript/warnings/get_node_default_without_onready>`.
Comment on lines +4 to +19

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite understand who this section is meant for. I thought this page was aimed at beginners to give them a short explanation on the common warnings.

I don't see how the default value is relevant to them.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually, the hope is to have every warning documented with examples, explanations, and fixes. This initial PR just adds pages for a few warnings that might be the most common, so that the review burden isn't as great.

Can you clarify what you mean by "I don't see how the default value is relevant to [beginners for a short explanation on the common warnings]"? I'm not sure I currently follow; the GET_NODE_DEFAULT_WITHOUT_ONREADY warning involves setting a property's default value with get_node() (or a shorthand equivalent) which is why default values are discussed here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify what you mean by "I don't see how the default value is relevant to [beginners for a short explanation on the common warnings]"?

That was referring to this part:

The default warning level for this warning is Error.

The default value is already in the class reference, and there it's actually always up-to-date (although displaying it as int is a bit terrible I guess).

I don't think including this information here makes that much sense.

Eventually, the hope is to have every warning documented with examples, explanations, and fixes.

Yeah I get that. I was talking about the general structure that you used here. I feel like we might just want to strike this initial section, and start with "When this warning occurs" directly.

This warning appears when a node's property is initialized to a node in the scene tree
without using the @onready annotation.

It seems like this is basically saying the same as the explanation you provide below.

Depending on how you attempt to access the scene tree, the warning message will
be one of the following:

I see no point in spelling out all variations. That's bound to get outdated, and users already know this message if they looked up the error.
(If you did that for SEO, that might be a point I guess. But we have well defined warning names, so that seems unnecessary to me 🤔.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was referring to this part

Ah, I see, thanks for the clarification! Thinking about it now, I agree that it might make more sense to just link to the class reference from these pages, and only specify the default value there. That way, updates to the default value won't make these pages outdated or inaccurate.

I recall there being discussion of adding links from these pages to the settings class reference; perhaps the inclusion of the default values was to make them flow more naturally? I'll see what I can find in the previous conversations, and if I can't find anything or what I find isn't especially compelling, I'll remove the default values and only link to the class reference.


I feel like we might just want to strike this initial section, and start with "When this warning occurs" directly.
...
It seems like this is basically saying the same as the explanation you provide below.

I definitely see where you're coming from here; the first sentence of the page is largely retreading ("pre-treading"?) the description given in the "When this warning occurs" section. The intent here is to provide a short (one- or two-sentence) description of the warning, along with the warning messages that might be displayed to the user (and thus that they might paste into a search engine to figure it out).

The "short description" being largely repeated below has precedent in the Godot documentation. For example, in the Node3D class reference, the initial short description says

Base object in 3D space, inherited by all 3D nodes.

and just below, the long description starts with

The Node3D node is the base representation of a node in 3D space. All other 3D nodes inherit from this class.

Bringing it back to the warning page, I suppose we could remove the short description of the warning and put the examples of warning messages in a section named something like "What this warning looks like". But given that other areas of the manual/class reference often start with an overview/intro section that is expanded upon in the following sections, I think it might be best to keep as-is.


If you did that for SEO, that might be a point I guess

Yep, that was pretty much the reason. I would expect users to copy and paste the warning messages they receive into a search engine to look for help with it, so I want to make sure the messages themselves (not just the codes/codenames, like GET_NODE_DEFAULT_WITHOUT_ONREADY) cause these pages to show up in search results.


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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think "give warning" is an established terminology? Where has this been used elsewhere?

@Meorge Meorge Apr 20, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can see in the Godot Docs, there's not generally a lot of discussion of GDScript warnings. The verb "give" is used in at least one spot, Static typing in GDScript:

Godot gives you warnings about your code as you write it.

Later on the same page, "produce" is used:

if "some_property" in node_2d:
	node_2d.some_property = 20  # Produces UNSAFE_PROPERTY_ACCESS warning.

if node_2d.has_method("some_function"):
	node_2d.some_function()  # Produces UNSAFE_METHOD_ACCESS warning.

However, this code will produce UNSAFE_PROPERTY_ACCESS and UNSAFE_METHOD_ACCESS warnings...

In the dedicated page for the GDScript warning system, "trigger" is used:

Godot will add an annotation above the corresponding line and the code won't trigger the corresponding warning anymore


So, overall it appears that "give", "produce", and "trigger" all have precedent in the docs currently.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Produce seems to be the most common, but I think we can leave it as is

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, I will leave it for now then 🙂

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() <class_Node_method_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.
27 changes: 27 additions & 0 deletions tutorials/scripting/gdscript/warnings/index.rst
Original file line number Diff line number Diff line change
@@ -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
43 changes: 43 additions & 0 deletions tutorials/scripting/gdscript/warnings/integer_division.rst
Original file line number Diff line number Diff line change
@@ -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<class_ProjectSettings_property_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
Comment thread
Meorge marked this conversation as resolved.
-----------------------

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)
Original file line number Diff line number Diff line change
@@ -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<class_ProjectSettings_property_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.
Comment on lines +41 to +42

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be worth mentioning that Variant return types are optional (e.g. type_convert() returns Variant and will not throw a warning if you don't assign it to a variable). This would make it clearer than just "some methods" (but I'm not sure if there are other cases or exceptions).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't go into too much detail on this. To me it's not exactly clear if that's intended in the first place, and even if it is, it's probably just to reduce false positives.

Keeping this in mind:

The target audience for the pages is relative newcomers to GDScript and/or programming in general; people who may be using code from tutorials without fully understanding it, and thus could be confused by the warning messages Godot provides. As such, the explanations aim to be extra beginner-friendly.

I see no point in going into details on potential false negatives.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not personally familiar with the Variant return types such as for type_convert() you brought up, but admittedly it not throwing a warning sounds more to me like it might be a bug on that side 😅

I have thought about having expandable sections that could go into more detail when necessary, but I don't recall if Godot's documentation supports such text sections, and we'd also want to have those details verified before asserting them in the documentation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I certainly hope Variant returns not throwing the warning is not a bug, because unless I'm mistaken, functions can "return void" as a valid Variant. E.g. with a function that returns a Variant, you can do return some_callable.callv(args), where some_callable can return -> void, so having the warning would be a problem in that scenario, and having to @warning_ignore the call would also be problematic.

But yeah, this is way out of scope for a document aimed at beginners.

40 changes: 40 additions & 0 deletions tutorials/scripting/gdscript/warnings/shadowed_variable.rst
Original file line number Diff line number Diff line change
@@ -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<class_ProjectSettings_property_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``.
35 changes: 35 additions & 0 deletions tutorials/scripting/gdscript/warnings/unassigned_variable.rst
Original file line number Diff line number Diff line change
@@ -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<class_ProjectSettings_property_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)
52 changes: 52 additions & 0 deletions tutorials/scripting/gdscript/warnings/unused_variable.rst
Original file line number Diff line number Diff line change
@@ -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<class_ProjectSettings_property_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.
Loading