Guide to the Godot game engine/Programming


The 3 languages

edit

Godot has 3 main programming (or scripting) languages, and a bonus fourth one if you have a version of Godot with Mono compiled. However, you can get unofficial languages or even make your own!

GDScript (".gd" file extension) is Godot's main language. It is a custom language that works with Godot's "scene" system. It is also quite simple to use. The developers of Godot say that you could learn GDScript in under an hour.

Example "Hello world!" program:

func _ready() -> void:
    # This is a comment. It isn't shown in the game.
    print("Hello world!")

I recommend using GDScript if you've never used Godot before since it is the easiest to use and also sports an auto-completion, which is very useful. GDScript is the language that will be used throughout this book.

 

Fun fact: Godot's developers experimented with Python and Swift before deciding to make a custom scripting language that better fit Godot. As a result, the language is pretty similar to the two.

For more information, please see the GDScript chapter.

VisualScript

edit

VisualScript (".vs" file extension) is Godot's visual language that uses a user-friendly interface to make code. It lacks many features in GDScript, but can be used to create, for example, a conversation tree.

 

However, this language is discontinued for Godot 4.x[1], as only 0.5% of users actually used the language. It is still available in Godot 3.x, and may be added to Godot 4 as an extension at a later date.


GDExtension (NativeScript before Godot 4.x)

edit

GDExtension allows you to run c and c++ code without recompiling it with the engine. This allows you to create super-fast code for things that are very computationally expensive.

GDExtension in Godot 4.1+ is forwards compatible, meaning GDExtensions made for 4.2 will work in 4.3, but not vice versa. However, this is not a guarantee since in the future compatibility might break in order to fix a bug and add a critical feature.

Unlike engine modules, GDExtension doesn't require compiling the engine's source code. It gives you access to most of the API available to GDScript and C#, allowing you to code game logic with full control with performance. It's ideal if you need fast code you'd like to distribute as an add-on in the asset library.

GDExtension can also use other languages, you're not limited to c and c++. If you want to use other languages you will need to install community-made bindings. They can be found on the official documentation pages.

If you have the mono version of Godot, you can write C# code. You can use it to make high-speed code to make modules or objects for your game. It can also be used to write tools.

 
Info:

Note: Godot itself is made with C++, and making direct modifications require you to recompile Godot's editor. Many Godot users have used this method to make custom Godot editors with custom tools.

How do I use these?

edit

GDScript, VisualScript and GDExtension (or NativeScript) can all be attached to a node, or used to create a custom one. In the mono build of Godot, C# can also be attached. C++ can only be used in Godot's existing engine. To do so, you will need to download a special version of Godot that has not been compiled into an application file.

To attach a script to a node, you first need a node to attach it too! Assuming you read the last chapter ("What is a node"), you can begin from the project you started last time.

Open Godot, and open your test project by double-clicking on it in the menu at the center of the screen. Open "Test UI.tscn" from the File System dock if it is not already open. Select your Test UI Control node. At the top of the Scene dock is a button that looks a little like paper with the edges of two sides rolled up. Press it.

Click the "Template" button and select "Empty" from the drop-down menu that appears. Press Create. Now a new screen should appear with a text edit area in the center of the screen, and the Test UI node should have that paper icon on it. You can click it whenever you want to reopen the script here. The script looks pretty boring right now:

extends Control

This is very important, however! The extends keyword (a very important piece of code, like pass) tells Godot that your script inherits the node type you place here. You may only attach a script to a node of that type, or a node that inherits that type.

Under extends Control, write the following code:

func _ready() -> void:
  print("Hello world!")

func tells Godot that you want to define a function. If you use Python a lot, you might think the print never gets called, as it is inside a function, which never get called automatically. The built-in function _ready() tells Godot to run the code when the node with the script is "ready", or that it has been fully loaded.

_init() runs before the node is ready. Use it to do self-contained pre-construction. _process(delta) runs every frame as fast as possible. delta is an argument for the function. It represents the time in seconds since the last frame. The value rises as the game lags. _physics_process(delta) is similar to _process, it runs every physics frame on a fixed time step, which is typically 60 frames per second. _exit_tree() is ran when the node exits the scene (to become an orphan or when it is "freed", or deleted) or the game closes.

Now, for some more complex code. This program will record the time that has passed in seconds since the game ran and show it when it ends.

var time: float = 0 # Or just "var time = .0"

# The "-> void" is optional

func _process(delta):
  # This increments time
  time += delta

func _exit_tree():
  print("Time passed: ",time)

Now, lets update this to automatically close the game after a random amount of time.

Add this code before _process:

const MAX_TIME = 10

const MIN_TIME = 5
onready var time_to_quit=randi() % (MAX_TIME-MIN_TIME) + MIN_TIME + 1

This will create a variable and set it during the call to _ready automatically. time_to_quit is a random number between 5 and 10. Add this code in the _process function:

if time >= time_to_quit:
  # Quit after a random amount of time.
  get_tree().quit()

One problem... The number is never different. Why? Because you need to call randomize() first.

Change the declaration of time_to_quit to var time_to_quit and add this to the _ready function:

randomize()
time_to_quit = randi()% (MAX_TIME-MIN_TIME) + MIN_TIME + 1

The + 1 is necessary since randi()%X returns a random number between 0 and {{Gdscript/string|X-1)).

This creates a number between 0 and MAX_TIME subtracted by MIN_TIME subtracted by 1. Adding the MIN_TIME and an extra 1 gets the result you need, a random number between MIN_TIME and MAX_TIME..

The randomize() makes randi() give a different stream of random numbers. Randomizing is based on time, and should not be called every frame for performance reasons. Once per node, called during _ready call, is enough.

What you have learned

edit
  1. The 3 (4 for Godot 3.x versions) types of currently supported script
  2. How to attach a script to a node
  3. How to record time with delta
  4. How to close a game
  5. How to make random numbers.

See also

edit

Godot documents -> scripting


Quiz

edit

1 NativeScript is the code the engine uses and requires recompiling the engine to use.

True
False

2 What language was discontinued for Godot 4?

Visual Script
GDScript
C++
C#
Python

3 GDScript is based on what other popular programming language(s)?

4 Which functions use delta as an argument?

_process
_physics_process
_ready
_exit_tree

5 Which of these process at a fixed time step?

_process
_physics_process
_second_process

6 The word "delta" is also a keyword:

True
False


References

edit

Guide to the Godot game engine

Getting started [edit]
Installation
What is a node?
Programming
Resources and importing
Signals and methods
Your first game
Making it work
Debugging
Input
Physics
Saving and loading
Multiplayer
Making it look good
UI skinning
Animation
Advanced help
Servers (singletons)
Platform specific
Optimisation
Encryption
Exporting
Plugins
Miscellaneous
Helpful links
Authors and contributors
Print version


<-- previous back to top next -->