Use Warning-Ignore To Selectively Ignore GDScript Warnings In Godot

Skip Directly to: A Cool Trick: Using #warning-ignore to Selectively Ignore GDScript Warnings

Click to jump to the Table of GDScript Warning Identifiers (Below)

At the beginning of the pandemic (of 2020), I sat down and read through quite a bit of documentation for a slightly lesser-known computer game engine/framework called Godot. In years past, I tried to get into more rapid game development using Unity (at least rapid prototyping) but always struggled with how Unity assembles everything. The whole package, from how big it is, how sometimes bloated it seemed, the sometimes backward-seeming component system, the necessity to use C# and .NET (or Mono) which is a bit of a dealbreaker, the licensing, and so on just always put me off. Even after I read a book on C# 5.0, it still honestly put me off. Perhaps I just had a bad tutorial?

What Impressed Me About Godot

Once I started reading the documentation for Godot, it blew me away by its entire structure, and at how flexible it all seemed. I’m not a shy programmer in the sense that I’m not afraid to get into the nuts and bolts (even assembler if I need to), so it wasn’t the presence of GDScript alone that impressed me. The following were my greatest impressions:

  • The fact that it’s self-contained
  • It’s well thought out (or seemed to be) from the ground up
  • It’s open-source (MIT licensed – a big deal to me), and thus extendable/hackable.

I could use C# if I really wanted/needed to, but I could also use Python, C, or any other language (even EcmaScript) I could fit into the GDNative API. The Tree-Node-Scene system reminded me of Flash/ActionScript (which I enjoyed) but without the Adobe flair, and the signaling system (sorta decoupled object communication using the Observer pattern) was right up my event-driven programming alley. Because GDScript is “based on” Python (but not fully Python) and rests on a lower foundation written in C it reminded me instantly of PyGame (for which you might remember I created the now-defunct PYGJS project.) But this… this is PyGame if it loaded up on steroids and became the RingFit villain:

Drageaux, the villain of RingFit for the Nintendo Switch (You can see me battle him here)

All of these elements (and analogies) enabled me to realize just how powerful a system like Godot was for a programmer with my skill. I sloughed off my initial impression (several years prior when it was only Godot 2.x) that it wasn’t “professional,” and since then have grown a distaste for Unity (and others like it). Programming in Godot is a breeze in my humble opinion, and I liken it to a souped up highly capable PyGame with a scenegraph. However, I quickly realized, after a week of programming in the built in editor/debugger, that I might need something a little more familiar (and robust). For example, Godot’s built-in debugger interface doesn’t have a step-out function, which, is kind of a pain. Luckily, Godot lets you use an external editor and an external debugger.

A Note About macOS and Interface Scaling (Does Your Mouse Seem Off?)

When I first started using Godot, my mouse seemed like it was off. I had to click either the top part of interface elements or even above interface elements for my click to register properly. I came to the conclusion that it was because something wasn’t being adjusted for interface scaling, which I was using (my interface on my machine is one step to the right of the default in the Display System Preferences). Here’s what I did to fix it on my machine (macOS Catalina 10.15.6):

  1. Find the Godot.app in the Applications folder (or wherever you’re running it from).
  2. Right-click on the app icon and select “Get Info”
  3. Check the option under the General section called “Open In Low Resolution”

Voila! Godot will now run in a lower interface resolution than your other apps, but, your mouse will also work correctly. To me, this wasn’t a big deal, since my interface scaling was already mild.

How I Code In Godot (With Visual Studio Code)

Kudos to the people making Godot that their Editor (I call it the IDE) comes with an integrated script editor and debugger. The editor even helps you auto-complete (with the help of optional type checking), which is a nice touch. I was able to easily start coding in GDScript in Godot right from the start inside the editor. There was no special set-up, it just worked.

After spending a week coding in Godot using the built-in script editor and debugger provided by the Godot editor (I call it an IDE) I realized there were a few short-comings. For one, I couldn’t figure out how to see the Output information at the same time as seeing the Debug information (call stack, etc.). In fact, anything separate at the bottom must be looked at separately, which was kind of a pain. Additionally, everything at the top of the Debug panel also was only viewable separately. I started realizing I needed a slightly more flexible layout. On top of that, the debugger interface (or some such) itself had a few strange quirks. There was no step-out button, which I found odd and inconvenient. As well, I ran across a strange bug in the debugger which caused the debugger to essentially crash (you can read about it here).

Visual Studio Code To The Rescue

So I decided, now that this was going to be my major go-to engine for all things awesome sauce development (mostly games), I’ll take the plunge of integrating it with a more feature-rich editor. My editor of choice for these kinds of things is the cross-platform Visual Studio Code. I really tried to use and love Atom from GitHub but two things happened. Atom was notoriously slow on my machines (I’d constantly have to tell Windows to “wait” on startup), buggy, and well, GitHub kinda contracts border security (not really my thing). So I tried another “hackable” Electron-based editor (yes, I know Electron is also GitHub) Visual Studio Code. I’ve been using it ever since.

Setting-Up Was A Breeze

It was super easy to set-up on my machine. I launched VSC and then searched plugins for Godot. I was happy to find godot-tools, which enabled me to have syntax highlighting, a connection to to the Godot IDE for opening files, and a connection to the debugger of a Godot instance. These are set-up through port connections with the default Godot settings already put in.

NOTE: One thing I did have to change from the default was to change the Gdscript_lsp_server_protocol under the settings from “tcp” to “ws” (WebSockets) because I was running Godot 3.2.1

UPDATE: Running Godot 3.2.1 and the latest godot-tools VSCode extension caused me to run into some funky debugger problems when debugging from Visual Studio. It would hang for no reason and cause all sort of problems. Updating to Godot 3.2.2 and changing my settings from “ws” back to “tcp” seems to have helped a great deal (though some quirks still remain). For anyone experiencing debugging issues from within Visual Studio try upgrading to the latest tools.

I followed the set-up directions (mainly what settings to put in the Godot editor, enabling an external editor, and external debugger) and it worked! It even polls my Godot language server connection when I boot or run VSC and offers a button in the warning that allows me to launch Godot automatically directed at my open project.

When I compare this to how much effort it took me to setup PHP language development when I was working on my MediaWiki/Wordpress integration, this was REALLY easy.

A Cool Trick: Using #warning-ignore to Selectively Ignore GDScript Warnings

And now the star of the show! When scripting in GDScript with Godot, it takes the time to notify us (if we have them enabled in the project settings) of possible warnings. There is one warning I always turn off, in my case, which is RETURN_VALUE_DISCARDED (see below). I write functions with returns that are optional but potentially useful all the time, and that becomes a burdensome error.

But what happens when Godot gives you a warning you know for sure is not really something to be concerned about?

That’s where the interpreter directive “warning-ignore” comes in! To use this directive you place code like the following in script files:

#warning-ignore:warning_identifier_here

There are several possibilities for this directive, according to this page, and they look like this:

  • warning-ignore:
    • Place this in a comment above the line that is triggering the warning. If the line of code is triggering multiple warnings you may have to place more than one (they work like a stack).
  • warning-ignore-all
    • Place this at the top of a script to ignore all warnings of a given type in that script.
  • warnings-disable
    • Place this tat the top of a script to just plain ignore all generated warnings in this script.

Of course you have to type the write idenfitifer in the place where I typed warning_identifier_here. But no fear, I explain exactly what those identifiers are, and even where to find them (if you’re using an external editor like myself) below!

My Table of GDScript Warning Identifiers

Although Godot Documentation has a page dedicated to using the “warning-ignore” directive, there are times when the identifier of a warning isn’t readily available to you. Not using the given Godot IDE script editor is one of those times. In that case, you could skip on over to the exact code that parses the warning identifiers on GitHub if you like to read straight-up code (like me), or…

… you could use my handy dandy nicely formatted table! Here is a snapshot (taken at the date of publishing or update above) of the warnings identifiers as gleaned from gdscript_warning.cpp:

UNASSIGNED_VARIABLE_OP_ASSIGN
Using assignment with operation but the variable ‘X’ was not previously assigned a value.
UNASSIGNED_VARIABLE
The variable ‘X’ was used but never assigned a value.
UNUSED_VARIABLE
The local variable ‘X’ is declared but never used in the block. If this is intended, prefix it with an underscore: ‘_X’
UNUSED_LOCAL_CONSTANT
The local constant ‘X’ is declared but never used in the block. If this is intended, prefix it with an underscore: ‘_X’
SHADOWED_VARIABLE
(The local variable ‘X’ is shadowing an already-declared variable ‘X’ at line #.)
SHADOWED_VARIABLE_BASE_CLASS
(The local variable ‘X’ is shadowing an already-declared ‘X’ at the base class “Y”.)
UNUSED_PRIVATE_CLASS_VARIABLE
The class variable ‘X’ is declared but never used in the script.
UNUSED_PARAMETER
The parameter ‘X’ is never used in the function “Y”. If this is intended, prefix it with an underscore: ‘_X’/
UNREACHABLE_CODE
Unreachable code (statement after return) in function “Y”.
UNREACHABLE_PATTERN
Unreachable pattern (pattern after wildcard or bind).
STANDALONE_EXPRESSION
Standalone expression (the line has no effect).
VOID_ASSIGNMENT
Assignment operation, but the function ‘Y()’ returns void.
NARROWING_CONVERSION
Narrowing convrsion (float is converted to int and loses precision).
INCOMPATIBLE_TERNARY
Values of the ternary conditional are not mutually compatible.
UNUSED_SIGNAL
The signal ‘X’ is declard but never emitted.
RETURN_VALUE_DISCARDED
The function ‘X()’ returns a value, but this value is never used.
PROPERTY_USED_AS_A_FUNCTION
The method ‘X()’ was not found in base ‘Y’ but there’s a property with the same name. Did you mean to access it?
CONSTANT_USED_AS_A_FUNCTION
The method ‘X()’ was not found in base ‘Y’ but htere’s a constant witj the same name. Did you mean to access it?
FUNCTION_USED_AS_PROPERTY
The property ‘X’ was not found in base ‘Y’ but there’s a method with the same name. Did you mean to access it?
INTEGER_DIVISION
Integer division, decimal part will be discarded.
UNSAFE_PROPERTY_ACCESS
The property ‘X’ is not present on the inferred type ‘Y’ (but may be present on a subtype).
UNSAFE_METHOD_ACCESS
The method ‘X’ is not present on the inferred type ‘Y’ (but may be present on a subtype).
UNSAFE_CAST
The value is cast to ‘X’ but has an unknown type.
UNSAFE_CALL_ARGUMENT
The argument ‘X’ of the function ‘Y’ requires the subtype ‘Z’ but the supertype ‘A’ was provided
DEPRECATED_KEYWORD
The ‘X’ keyword is deprecated and will be removed in a future release, please replace its uses by ‘…’
STANDALONE_TERNARY
Standalone ternary conditional operator: the return value is being discarded.
ASSERT_ALWAYS_TRUE
Assert statement is redundant because the expression is always true.
ASSERT_ALWAYS_FALSE
Assert statement will raise an error because the expression is always false.
REDUNDANT_AWAIT
(“await” keyword not needed in this case, because the expression isn’t a coroutine nor a signal.)

The idea here is of course that you’d put the term after the warning-ignore as such:

#warning-ignore:put_identifier_here

So to ignore a RETURN_VALUE_DISCARDED:

#warning-ignore:return_value_discarded

Photo by Robert Rubyan on Unsplash

Asher Wolfstein

Asher Wolfstein

I am a time-traveling wunk, a hybrid between wolf and skunk (of the male variety), currently stranded in the 21st century. In my travels, I’ve realized that of all the things I need to be, it is being true to myself that is the most important. With that, I am a gay-straight Lucifurryan transfuturist that lives by the seven virtues of rationality, integrity, productivity, honesty, independence, pride, and most important of all, justice. As an artist and intellectual, I appreciate everything from opera to Disney and take life and all its possibilities as they come. I continually write, craft, costume, read everything, program computers, invent, create, make, and even draw. Daily I don't have any plans, just coffee, and strangeness. With all that, let's all do our best okay?

Leave a Reply

%d bloggers like this: