Use Warning-Ignore To Selectively Ignore GDScript Warnings In Godot
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
- How I Code In Godot (With Visual Studio Code)
- A Cool Trick: Using #warning-ignore to Selectively Ignore GDScript Warnings
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:
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):
- Find the Godot.app in the Applications folder (or wherever you’re running it from).
- Right-click on the app icon and select “Get Info”
- 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:
There are several possibilities for this directive, according to this page, and they look like this:
- 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).
- Place this at the top of a script to ignore all warnings of a given type in that script.
- 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:
- Using assignment with operation but the variable ‘X’ was not previously assigned a value.
- The variable ‘X’ was used but never assigned a value.
- The local variable ‘X’ is declared but never used in the block. If this is intended, prefix it with an underscore: ‘_X’
- The local constant ‘X’ is declared but never used in the block. If this is intended, prefix it with an underscore: ‘_X’
- (The local variable ‘X’ is shadowing an already-declared variable ‘X’ at line #.)
- (The local variable ‘X’ is shadowing an already-declared ‘X’ at the base class “Y”.)
- The class variable ‘X’ is declared but never used in the script.
- The parameter ‘X’ is never used in the function “Y”. If this is intended, prefix it with an underscore: ‘_X’/
- Unreachable code (statement after return) in function “Y”.
- Unreachable pattern (pattern after wildcard or bind).
- Standalone expression (the line has no effect).
- Assignment operation, but the function ‘Y()’ returns void.
- Narrowing convrsion (float is converted to int and loses precision).
- Values of the ternary conditional are not mutually compatible.
- The signal ‘X’ is declard but never emitted.
- The function ‘X()’ returns a value, but this value is never used.
- The method ‘X()’ was not found in base ‘Y’ but there’s a property with the same name. Did you mean to access it?
- The method ‘X()’ was not found in base ‘Y’ but htere’s a constant witj the same name. Did you mean to access it?
- 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, decimal part will be discarded.
- The property ‘X’ is not present on the inferred type ‘Y’ (but may be present on a subtype).
- The method ‘X’ is not present on the inferred type ‘Y’ (but may be present on a subtype).
- The value is cast to ‘X’ but has an unknown type.
- The argument ‘X’ of the function ‘Y’ requires the subtype ‘Z’ but the supertype ‘A’ was provided
- The ‘X’ keyword is deprecated and will be removed in a future release, please replace its uses by ‘…’
- Standalone ternary conditional operator: the return value is being discarded.
- Assert statement is redundant because the expression is always true.
- Assert statement will raise an error because the expression is always false.
- (“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:
So to ignore a