Skip to content

Add GDScript warning pages#10635

Open
Meorge wants to merge 1 commit into
godotengine:masterfrom
Meorge:gdscript-warnings
Open

Add GDScript warning pages#10635
Meorge wants to merge 1 commit into
godotengine:masterfrom
Meorge:gdscript-warnings

Conversation

@Meorge

@Meorge Meorge commented Feb 7, 2025

Copy link
Copy Markdown
Contributor

Closes #10627.

This begins the implementation of pages describing each warning that can be given by GDScript. A page with all of the warnings can be found at /tutorials/scripting/gdscript/warnings/index.html or Manual > Scripting > GDScript > GDScript warnings.

This initial PR adds pages for six warnings commonly encountered by beginners:

  • GET_NODE_DEFAULT_WITHOUT_ONREADY
  • INTEGER_DIVISION
  • RETURN_VALUE_DISCARDED
  • SHADOWED_VARIABLE
  • UNASSIGNED_VARIABLE
  • UNUSED_VARIABLE

If this PR is successful, small batches of additional warning pages can be added in subsequent PRs, so that they can be reviewed and verified before being published.

Each page has the following sections:

  • An example of the warning message that appears in Godot, so that it can be easily found if someone pastes the message into a web search
  • An explanation of what causes the warning to appear, including sample code
  • Instructions on how to fix or suppress the warning

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.

@tetrapod00 tetrapod00 added enhancement content:new page Issues and PRs related to creation of new documentation pages for new or undocumented features topic:gdscript area:manual Issues and PRs related to the Manual/Tutorials section of the documentation labels Feb 7, 2025

@tetrapod00 tetrapod00 left a comment

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 have no complaints with the overall structure of the warning page. The example you've written already seems quite high quality, and you've matched the tone and style of the manual quite well already. I at least would be happy merging this more or less as-is.

The content reads as overall correct but I'm not a deep expert in GDScript so that will need another review.

I left several suggestions for style and minor structure changes, but I'm not certain about some of them. Feel free to disagree and push back on any of them.

For the manual, unlike the class reference, we currently wrap lines to between 80 and 100 characters, as described here. There are plugins that can do this automatically in your IDE too.

@@ -0,0 +1,41 @@
``GET_NODE_DEFAULT_WITHOUT_ONREADY``
====================================

@tetrapod00 tetrapod00 Feb 7, 2025

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.

Suggested change
Description
-----------

Perhaps?

The warning that appears when a node's default value is set to a location in the scene tree without using the ``@onready`` annotation.
The message will say something like:

.. code-block:: none

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's unfortunate that the error here is wider than the screen and requires scrolling with a code block. If there was a way to use word-wrapped code blocks we should do that. Otherwise we could consider using indented and maybe italicized or codestyle text, which is used elsewhere in the manual for quotes.

This may also be solvable with some custom CSS but that should be avoided if possible.

I'll look around and see if there's any better way here.

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.

What about manually inserting a line break?

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.

That might work, if there is a natural sentence break. We definitely should not manually wrap these to 80 characters or similiar.

In the engine these strings are on a single line, though, and you have to scroll horizontally there too. So maybe it's fine as-is.

------------------------
In GDScript, instance variables can be set by declaring them outside of a method. Additionally, they can be given a default value using ``=``::

extends Area2D

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.

Suggested change
extends Area2D

I'm not sure we need the extends Area2D here for the example to work, but maybe it increases clarity to keep in?

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.

Overall, I agree - it's not used in this example script, so it could be removed if need be. The main reason I kept it is so that it implies we're looking at an entire script, rather than just an isolated snippet.

In the later code blocks, in addition to serving that purpose, it also provides a practical reason for attempting to assign a node type variable (saving the CollisionShape2D of an Area2D seems like a likely thing to want to do).

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.

Let's favor keeping it in, then. I'd like opinions from other reviewers on this one.

We may want to add an empty line between extends and var, to follow the style guide.

@Mickeon Mickeon Mar 6, 2025

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 feel like this is not enough. You could make more obvious that it's an instance variable (basically a property) by declaring a method below that uses it.

It doesn't really matter that much, however. The examples below mitigate the ambiguity

Comment thread tutorials/scripting/gdscript/warnings/GET_NODE_DEFAULT_WITHOUT_ONREADY.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/GET_NODE_DEFAULT_WITHOUT_ONREADY.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/GET_NODE_DEFAULT_WITHOUT_ONREADY.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/GET_NODE_DEFAULT_WITHOUT_ONREADY.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/index.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/GET_NODE_DEFAULT_WITHOUT_ONREADY.rst Outdated
@tetrapod00

tetrapod00 commented Feb 7, 2025

Copy link
Copy Markdown
Contributor

These warnings are also documented (rather briefly) in the project settings, for example https://docs.godotengine.org/en/latest/classes/class_projectsettings.html#class-projectsettings-property-debug-gdscript-warnings-get-node-default-without-onready. We may want to link from each new page to the projectsettings class reference too. Though unlike a lot of descriptions in the class reference projectsettings, these are very short and don't add all that much value

@Meorge

Meorge commented Feb 7, 2025

Copy link
Copy Markdown
Contributor Author

I like the idea of providing links to the class reference. Additionally, we could use the descriptions already written in the class reference as the short one-line descriptions for the new pages, before further sections go into more detail and provide examples.

@tetrapod00

tetrapod00 commented Feb 7, 2025

Copy link
Copy Markdown
Contributor

Using the existing short descriptions as placeholders makes sense; but let's wait to validate the overall structure before changing all the instances

@Meorge

Meorge commented Feb 7, 2025

Copy link
Copy Markdown
Contributor Author

I haven't added the short descriptions as placeholders, but I did paste in the warning message strings for each warning 😅 This way, if someone searches the warning message they receive, they'd hopefully find the associated page in the docs.

A big issue with this is that messages that have details filled in at runtime are tricky to include. For now, I've just kept them verbatim from the source code with %s where text is filled in.

@dalexeev

Copy link
Copy Markdown
Contributor

It would also be nice to mention the default level (Ignore, Warn, Error), in which cases it is recommended or not recommended to enable/disable/suppress the warning. For the warning message, we could use human-readable placeholders instead of %s.

Can we use snake_case or kebab-case for file names, while UPPER_CASE for warning names and TOC items?

@tetrapod00

tetrapod00 commented Feb 12, 2025

Copy link
Copy Markdown
Contributor

Can we use snake_case or kebab-case for file names, while UPPER_CASE for warning names and TOC items?

For RST filenames, snake case is currently idiomatic

@Meorge

Meorge commented Feb 12, 2025

Copy link
Copy Markdown
Contributor Author

I can certainly change the filenames to use snake case, and replace the instances of %s with something more natural.
Adding the default warning level also makes sense to me - I'll try to add these things to my prototype pages soon.


This is because ``assert(false)`` calls are often used in development to forcibly halt program execution and avoid strange errors later on.

See `issue #58087 <https://github.com/godotengine/godot/issues/58087>`_ for more information.

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.

Suggested change
See `issue #58087 <https://github.com/godotengine/godot/issues/58087>`_ for more information.
See `GH-58087 <https://github.com/godotengine/godot/issues/58087>`_ for more information.

Usually it's styled like this.

Linking to the original issue/PR from the docs seems like an antipattern though, usually we would rewrite the relevant content of the issue/PR into a form suitable for the manual. I'm not wholly against linking though

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 like the idea of linking the issue/PR, similar to how one might paraphrase a primary source in an essay and then provide a citation to the primary source itself, so the reader can look at it themselves if they so wish. But the reasoning provided in the issue might be general enough that it doesn't "need" a citation, and it could also make it unclear when it's appropriate to link to GitHub, resulting in the docs becoming more cluttered.

------------------------

The :ref:`assert() <class_@GDScript_method_assert>` keyword can be used to ensure that a given condition is met before allowing code execution to continue. If the first argument passed to it evaluates to ``true``, the rest of the function will run as expected; if it is ``false``, then the project will stop.
The :ref:`assert() <class_@GDScript_method_assert>` keyword can be used to ensure that a given condition is met before allowing code execution to continue. If the first argument passed to it is truthy, the rest of the function will run as expected; if it is falsy, then the project will stop.

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 would be nice if we defined truthy/falsy somewhere else in the GDScript docs that we could link to, see also #4408

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 agree. In general I'm nervous about even using the terms "truthy" and "falsy" right now, because neither of them currently appear in the docs at all from what I can see (searching either of them on the online docs turns up no results).

@Mickeon Mickeon Mar 6, 2025

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 wanted to do this in Variant's own class reference in godotengine/godot#95487 but I haven't had the time to retouch it considerably.

Note that a lot of Variant types describe what happens in "a boolean context" in their respective descriptions.

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.

Thanks, I may use that wording instead to remain consistent!

@Meorge Meorge force-pushed the gdscript-warnings branch from fc41f4f to a2a6829 Compare March 24, 2025 04:54
@Meorge Meorge marked this pull request as ready for review May 13, 2025 02:19
@Meorge

Meorge commented May 13, 2025

Copy link
Copy Markdown
Contributor Author

I'm opening this PR for review now. My goal is to have at least a first version complete for all pages before merging, so that users don't go to look up a warning and just find "TODO". There's definitely a lot of work in writing the pages out, so perhaps that is too much to hope for. Regardless, it'll be very nice to have people reading and reviewing what's been written so far.

If there's a way to allow other people to contribute pages, that would be great too. I suppose they'd submit a PR on my fork?

@Mickeon Mickeon requested review from Mickeon and tetrapod00 May 14, 2025 10:04

@Mickeon Mickeon left a comment

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.

If this is accepted each page should also be linked in the corresponding setting in the class reference.

This is quite a lot to review at once, and yet, as of this swoop, it's quite nice. But oh boy

When this warning occurs
------------------------

The :ref:`assert() <class_@GDScript_method_assert>` keyword can be used to ensure that a given condition is met before allowing code execution to continue. If the first argument passed to it is truthy, the rest of the function will run as expected; if it is falsy, then the project will stop.

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.

The terms "truthy" and "falsy" never appear in the documentation before. We should consider spelling this out, like "is equivalent to true in a boolean context". I only say "boolean context" because a very common note in each Variant type's class reference says as much.

Not that I'm personally against mentioning "truthy" or "falsy", as it's a fairly common thing in programming, but it needs to be explained somewhere, and it's not done anywhere, nor is this the place to do it.

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.

As I recall, someone else made the same (or a similar) suggestion a while back, so this is definitely worth revising.

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've updated this document to use the "boolean context" phrasing - should be pushed soon, once I've made other adjustments.

Comment thread tutorials/scripting/gdscript/warnings/confusable_identifier.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/confusable_identifier.rst Outdated
Comment on lines +20 to +23
var engine_nаme = "Godot"
print(engine_name)

In this code snippet, the ``print`` statement would fail, because ``engine_name`` is actually not defined. The identifier in the ``print`` statement uses the Latin character "a" (U+0061), while the identifier in the variable declaration above uses the Cyrillic character "а" (U+0430).

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.

Oooo, this is nasty, is there any other letter that may be slightly more distinguishable?

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 can double-check later, but I recall going into the code to try and find the "look-alike" table that Godot may have been using to detect these, and was unable to find it (perhaps it was being processed by a third-party library?). The letters being indistinguishable might be helpful here, though. They look identical to each other, yet aren't the same, which is the point of the warning.

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 found this page that visualizes the Unicode confusable characters: https://util.unicode.org/UnicodeJsps/confusables.jsp

For this example, I could replace the Cyrillic character with ɑ (lowercase alpha), like so:

var engine_nɑme = "Godot"
print(engine_name)

There are a few other characters (α, ⍺, 𝐚, 𝑎, etc) that could also be used instead.

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 like this alternative. It's subtle but at least noticeable.

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'm not sure if we should make the intentionally confusable identifier less confusing, even for demonstration in documentation. The point is that some Unicode characters are visually indistinguishable from each other in most fonts. If someone doesn't know this, I think it's better for them to learn it here, rather than expecting characters to be similar but still slightly different.

Or we can clarify it separately, something like Moreover, some characters may have no visual differences at all in most fonts, like Latin "a" and Cyrillic "а"..


Assert statement will raise an error because the expression is always false.

The default warning level for this warning is **Warn**.

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.

There may be something in Sphinx's restructuredtext that may avoid having to copy and paste this every time. Putting a pin on that.

https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#substitutions

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.

Looks like I can define a series of substitutions like

.. |default_is_ignore| replace:: The default warning level for this warning is **Ignore**.
.. |default_is_warn| replace:: The default warning level for this warning is **Warn**.
.. |default_is_error| replace:: The default warning level for this warning is **Error**.

and then use them (like |default_is_warn|) to paste that message in. Automating the ProjectSettings links might take a bit more work, since it involves changing text within the reference link. I would really love to figure out a way to automate this well, since as you pointed out so much of the text is the same.

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.

Unless I'm mistaken I don't think this would work across multiple pages so there may still be a need to merge everything into one.

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 wouldn't let this narrow issue of substitutions determine if we make one page or multiple pages for these warnings. (FWIW a page for each warning seems natural to me, and there is prededent with the C# diagnostics, but this is a larger decision and it seems like other reviewers are leaning towards a single page)

  • It's likely not worth the effort to automate the class reference links, since that would involve dynamic replacement and IIRC that isn't straightforward with RST substitutions.

  • You can make a substitution accessible from all pages rst_epilog, we already use it at least once:

    godot-docs/conf.py

    Lines 289 to 298 in 6ae63dd

    rst_epilog = """
    .. |weblate_widget| image:: https://hosted.weblate.org/widgets/godot-engine/{image_locale}/godot-docs/287x66-white.png
    :alt: Translation status
    :target: https://hosted.weblate.org/engage/godot-engine{target_locale}/?utm_source=widget
    :width: 287
    :height: 66
    """.format(
    image_locale="-" if language == "en" else language,
    target_locale="" if language == "en" else "/" + language,
    )

However, we don't use that for cases like the upgrading pages or the class reference, where each page redefines the same substitions:

.. || replace:: :abbr:` (This API breaks compatibility.)`
.. |✔️| replace:: :abbr:`✔️ (This API does not break compatibility.)`
.. |✔️ with compat| replace:: :abbr:`✔️ (This API does not break compatibility. A compatibility method was added.)`

.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
.. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`
.. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`
.. |static| replace:: :abbr:`static (This method doesn't need an instance to be called, so it can be called directly using the class name.)`
.. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`
.. |bitfield| replace:: :abbr:`BitField (This value is an integer composed as a bitmask of the following flags.)`
.. |void| replace:: :abbr:`void (No return value.)`

There might be a compile time increase when using rst_epilog, which is why it's not used more. I haven't looked closely at this, though.

There's also .. include (docs) which could be used to only include the substitutions on the pages that use it (and therefore reduce compile times if using rst_epilog is too heavy). We don't currently use .. include, but it's usage looks relatively straightforward.

(I still have to do a deeper review of the rest of this later)

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.

Using an RST file and .. include is how I implemented the test on my end.

warning_page_substitutions.rst:

.. |default_is_ignore| replace:: The default warning level for this warning is **Ignore**.
.. |default_is_warn| replace:: The default warning level for this warning is **Warn**.
.. |default_is_error| replace:: The default warning level for this warning is **Error**.

assert_always_false.rst:

ASSERT_ALWAYS_FALSE
=======================

The warning message is:

.. code-block:: none

    Assert statement will raise an error because the expression is always false.

|default_is_warn|
To modify it, see :ref:`ProjectSettings.debug/gdscript/warnings/assert_always_false<class_ProjectSettings_property_debug/gdscript/warnings/assert_always_false>`.

.. include:: warning_page_substitutions.rst

With this, we'd only have to edit or translate the sentences once in warning_page_substitutions.rst and they'd apply everywhere, which is nice. Dynamic substitution would be very helpful for this, but as you said it sounds like it would be quite involved.

Comment thread tutorials/scripting/gdscript/warnings/standalone_expression.rst Outdated
# Will give warning STATIC_CALLED_ON_INSTANCE.
var result = my_math_funcs.subtract_two(5)

When a function is *static*, it belongs to the class as a whole, not any one specific instance of the class. This can be quite handy for writing functions that you want to access from anywhere, without needing a class instance.

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.

It's true, it is handy, but this doesn't explain why this warning exists. Most warnings exist because the code may not be working as intended, but this one is mainly to avoid confusion when reading.

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.

Very good point. I think my intent here was to explain what "static" even meant to someone who perhaps wasn't familiar with the term, but I see here that I neglected to follow up that description with a discussion of the warning itself 😅

I think I might remember there being a section in the GDScript docs that describes static functions/methods; perhaps it could be linked from here. This will certainly need more discussion of why calling a static method on an instance is questionable, though.

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.

For reference, the warning was implemented in godotengine/godot#67365 :

The purpose of this warning is to avoid the silent failure resulting from functions which have become static recently

And it is a notable pitfall, too.

I think I might remember there being a section in the GDScript docs that describes static functions/methods

https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html#static-variables and https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html#static-functions

Comment thread tutorials/scripting/gdscript/warnings/unassigned_variable.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/unreachable_code.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/unsafe_call_argument.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/assert_always_false.rst Outdated
@Meorge Meorge force-pushed the gdscript-warnings branch from bef0269 to 9279a62 Compare May 31, 2025 19:23
@Meorge Meorge force-pushed the gdscript-warnings branch from 9279a62 to c9f2aa0 Compare June 10, 2025 21:43
@Meorge Meorge force-pushed the gdscript-warnings branch from c9f2aa0 to 6a08136 Compare June 29, 2025 23:52
@Meorge

Meorge commented Jun 29, 2025

Copy link
Copy Markdown
Contributor Author

During one of the previous GDScript meetings, we discussed only including a small subset of the GDScript warnings in the initial PR. This way, they'd be easier for others to thoroughly review and approve before merging.

I think it'd make sense, then, to try and choose the most common warnings first, so that they're the most likely to help people. The more obscure warnings can get pages later.

Based on what I've seen from people in online help communities, I think these pages could make for a good initial batch:

  • GET_NODE_DEFAULT_WITHOUT_ONREADY
  • INTEGER_DIVISION
  • RETURN_VALUE_DISCARDED
  • SHADOWED_VARIABLE
  • UNASSIGNED_VARIABLE
  • UNUSED_VARIABLE

Are there any other warnings that would be good to include? On the flip-side, are any of the ones I've listed here unnecessary to start with? Once I have a solid response/consensus on that, I can work on editing the PR's contents to just include those warning pages.

Comment thread tutorials/scripting/gdscript/warnings/unassigned_variable_op_assign.rst Outdated

When a function is *static*, it belongs to the class as a whole, not any one specific instance of the class. See :ref:`Static variables <doc_gdscript_basics_static_variables>` and :ref:`Static functions <doc_gdscript_basics_static_functions>` for more information.

There is often no need to call a static function on an instance of a class. In the example above, the function ``subtract_two()`` will always perform the same operation; one instance of the ``MathFuncs`` class would never return a different value than another instance. As such, when the user tries to call ``subtract_two()`` from an instance of ``MathFuncs``, it suggests the user may not understand what the function does.

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.

one instance of the MathFuncs class would never return a different value than another instance

This is not necessarily true, only assuming all other conditions are the same, static does not mean stateless, so it might be good to qualify here

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.

In this case, I think I was specifically referring to the subtract_two() function I defined here. Since it only uses its input argument and a constant to calculate its result, all MathFuncs instances would give the same output. However this could probably be made clearer, and/or the example as a whole reworked.

Comment thread tutorials/scripting/gdscript/warnings/int_as_enum_without_match.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/confusable_identifier.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/confusable_identifier.rst Outdated
@Meorge Meorge force-pushed the gdscript-warnings branch from 93b92e3 to 0b93260 Compare July 1, 2025 17:02
@Meorge

Meorge commented Sep 19, 2025

Copy link
Copy Markdown
Contributor Author

This PR has been updated to only contain warning pages for the six warnings listed above:

  • GET_NODE_DEFAULT_WITHOUT_ONREADY
  • INTEGER_DIVISION
  • RETURN_VALUE_DISCARDED
  • SHADOWED_VARIABLE
  • UNASSIGNED_VARIABLE
  • UNUSED_VARIABLE

We can start adding more pages soon, but hopefully this will make for a good initial batch.

Comment on lines +24 to +31
.. code-block:: gdscript

extends Area2D

var my_num = 3

The property ``my_num`` will always start out with a value of ``3`` in each instance of this class.
GDScript also has methods to retrieve specific nodes from the scene tree: namely the :ref:`get_node() <class_Node_method_get_node>` method, and its shorthand versions ``$`` (and ``%`` for unique nodes). Thus, if you want to have a property's default value be a particular child node, it may be tempting to write something like the following:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'm not sure we need to explain the concept of member variable initialization within this document. I think we can assume that the reader is familiar with it by the time they reach here.

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's a good point. Originally, my thought was that the target audience for these docs is new programmers who could be confused by the warning messages themselves. They may be following tutorials and pasting code without fully understanding it, so having the full thought process leading to the code that causes the warning explained could help them.

That being said, explaining the basics of member variable initialization like this might be a bit too much background. This could be simplified to just the get_node() (and shorthand) methods, as well as how member variable initialization happens before building the scene tree. If there's a guide elsewhere in the docs that explains member variables for newcomers, we could link it here.

@Meorge

Meorge commented Sep 25, 2025

Copy link
Copy Markdown
Contributor Author

I've tried to refine the GET_NODE_DEFAULT_WITHOUT_ONREADY page, bringing it more in line with the other, later-written pages as well as removing unnecessary background information.

@Calinou Calinou left a comment

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.

Adjust underline lengths to avoid Sphinx build warnings:

Comment thread tutorials/scripting/gdscript/warnings/get_node_default_without_onready.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/integer_division.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/return_value_discarded.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/shadowed_variable.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/unassigned_variable.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/unused_variable.rst Outdated

@Calinou Calinou left a comment

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.

Looks good to me.

However, several of the pages added here contain extraneous blank lines at the end. There should only be one newline at the end of each file (as added by most text editors). On GitHub, it should look like there are no newlines at the end of each file (but no red warning sign should appear either).

@Meorge Meorge force-pushed the gdscript-warnings branch from 92b97f2 to 3958170 Compare March 16, 2026 20:47
@Meorge

Meorge commented Mar 16, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review! The files should hopefully now be fixed to have the correct endings.

@Meorge Meorge force-pushed the gdscript-warnings branch from 3958170 to 700ab14 Compare April 9, 2026 17:55

@Calinou Calinou left a comment

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.

Looks good to me.

@Meorge Meorge force-pushed the gdscript-warnings branch from 700ab14 to f2b458c Compare April 18, 2026 03:45
Comment thread tutorials/scripting/gdscript/warnings/get_node_default_without_onready.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/get_node_default_without_onready.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/index.rst Outdated

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 🙂

@Meorge Meorge force-pushed the gdscript-warnings branch from f2b458c to 31ab172 Compare April 20, 2026 23:42
@Meorge Meorge force-pushed the gdscript-warnings branch 2 times, most recently from f079002 to 7a64264 Compare June 5, 2026 16:38
@Meorge Meorge force-pushed the gdscript-warnings branch from 7a64264 to fe00c6b Compare June 23, 2026 05:53
@Meorge Meorge force-pushed the gdscript-warnings branch from fe00c6b to 57b8ed4 Compare July 8, 2026 21:53
Comment on lines +41 to +42
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.

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.

@HolonProduction HolonProduction left a comment

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'm not exactly on top of the discussion, so that might have been discussed already. But I'm wondering whether it wouldn't be more helpful to beginners to expand the documentation on the settings with code samples. That way we could probably link to it directly from within the editor.

Comment thread tutorials/scripting/gdscript/warnings/get_node_default_without_onready.rst Outdated
Comment thread tutorials/scripting/gdscript/warnings/get_node_default_without_onready.rst Outdated
Comment on lines +4 to +19
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>`.

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.

@Meorge Meorge force-pushed the gdscript-warnings branch from 57b8ed4 to a264154 Compare July 9, 2026 15:38
@Meorge

Meorge commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the reviews!

I'm wondering whether it wouldn't be more helpful to beginners to expand the documentation on the settings with code samples. That way we could probably link to it directly from within the editor.

I recall this may have been discussed a while ago (or something similar – perhaps one page for all warning descriptions), but I felt that having all of the warnings' content on one page would lead to a massive page and/or force each warning's description to be too short. For me, only having one warning's content on a page gives the content more room to breathe and be on the longer side if that's necessary to help people understand the warning.

Linking to it directly from within the editor would be great, but I'm not sure that putting it in the class reference under the settings is a strict requirement for that. The current built-in class reference for Godot already contains links to manual pages which open in the user's web browser when clicked:

CleanShot 2026-07-09 at 08 45 36@2x

If there was a clean way to include these manual pages in the offline download, that'd be even better. Perhaps we could look into a way to add a section to the class reference for GDScript warnings...? Otherwise though, I think manual pages linked to from the class reference would be sufficient.

@HolonProduction

Copy link
Copy Markdown
Member

Otherwise though, I think manual pages linked to from the class reference would be sufficient.

The audience this is targeting is not going to go to the class ref. If we want to link it, it needs to be from the warning panel.

But thinking about it, I think the shader editor also links directly to online documentation. So I guess we are fine with linking to the online docs from editor UI.

@Meorge

Meorge commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Yep, I think linking to it from the warning panel would be great. When the code actions PR is merged and this docs PR is merged as well, I've also been thinking of doing a follow-up PR that lets users access the warning page from the code actions menu itself. But that's still a ways away 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:manual Issues and PRs related to the Manual/Tutorials section of the documentation content:new page Issues and PRs related to creation of new documentation pages for new or undocumented features enhancement topic:gdscript

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add documentation for GDScript warnings

9 participants