Godot

From Leo's Notes
Last edited on 14 November 2022, at 05:48.

Godot is a open source game engine with support for both 2D and 3D based games.

GDScript cheatsheet

Concept Example
Function definitions
# A basic function
func simple_func():
	do_something()

# With a return type
func simple_func2() -> void:
	do_something()

# Takes an argument
func simple_func3(v):
	do_something_with(v)

# Takes an argument of a specific type
func simple_func3(v: int):
	do_something_with(v)

# Takes an argument with a default value
func simple_func3(v = 1):
	do_something_with(v)
Static functions
class_name something

# This static function won't have access to any of something's members
# but you can call out as something.something(a, b)
static func something(a, b):
	return a + b
Signals, emitting
extends Node2D

signal state_changed()
signal state_changed_to(s)

func example():
	emit_signal("state_changed")
	emit_signal("state_changed_to", "argument1")
Signals, receiving
onready var something := $SomeNode

func _ready():
	something.connect("state_changed", self, "_on_state_changed")

func _on_state_changed():
	# something's state changed, so something
	pass
Getters and setters
# Both setter/getter
var type = Type.Blank setget _set_type, _get_type

# Just a getter, note the comma
var type2 = Type.Blank setget , _get_type2

# Just a setter
var type3 = Type.Blank setget _set_type3
Variables.
var n : int = 4
var i : float = 4.4
var name : String = "Hello"
var dict : Dictionary = {1: "Foo"}
var list : Array = [1, 2.2, "three"]
var isTrue : bool = false
Export variables

Documentation

export (int) var WorkTimeStart = 6 * 60
export (bool) var WorkHolidays = true
export (Texture)  var building_icon;
export var size :=  Vector2(1, 1)

## Hints. More in Godot documentation
export (int, 0, 20) var ZeroToTwenty = 0
Node tree navigation.

These are from base Node

Documentation

# Iterate over all children to look for a specific type
for c in get_children():
	if c is MyClass:
		c.visible = false

# Same for groups
var groups = get_groups()

# Get the 2nd child of this node (0 index)
var some_child = get_child(1)

# Get a node by name or path
var something = find_node("name")
var something_recursive = find_node("name", true)

# Get a specific node
var node = get_node("NodeName")
# Equivalent to:
var node = $NodeName
Arraays
var array = ["One", 2, 3, "Four"]

array.clear()
array.count()
array.empty()  # is empty?
array.has(something) # has something?
array.erase(something) # removes something
array.remove(index) # removes item at index
array.append(something) or array.push_back(something) # appends something


Godot concepts

File System

The filesystem that Godot provides is res:// for resources such as static game files or assets and user:// for dynamic data such as generated map data or game saves.

Addons should be placed in res://addons in your project. Any addons you place here should then be visible in the project settings under the Addons tab.

Objects

A Node is the building block of Godot; all scene objects in Godot are Nodes. Nodes have properties and functions and can emit signals which others can subscribe to. Nodes can be assigned as a child of another node and are arranged into a tree.

A tree of nodes is referred to as a Scene. Active scenes that are loaded and in use are part of a Scene Tree. In addition to the hierarchy/inheritance model, nodes can also be organized by groups (eg. as groups of Enemies, Collectables, etc. which can be retrieved with get_tree().get_nodes_in_group("enemies")).

A scene is saved to a TSCN (text-scene) file.

Scene Tree

Godot maintains an active set of scenes called a Scene Tree. When scenes are added to the scene tree, all its nodes will be added. Child nodes are added after their parent node. The root node of the Scene Tree is up to you but must be of a Node2D for 2D scenes or Spatial for 3D scenes.

Control nodes are used for user interfaces and behave differently from Node2D. Controls should be placed in a separate tree, under a CanvasLayer node.

Code can get the SceneTree by calling get_tree().

Nodes also receive a enter_tree notification. Only when all nodes have been added will they then be ready.

2D

The 2D coordinate system in Godot is such that:

  • X increases as you go left and decreases as you go right.
  • Y decreases as you go up and increases as you go down.

Sprite nodes are drawn in the order that they are traversed on the SceneTree. Traversal is done depth-first, meaning the first objects in the tree are drawn first. To switch the draw order, based on its Y position on the screen, use a YSort node.

Physics

The physics engine nodes are:

  • StaticBody - Non-moving solid physical obstacle.
  • RigidBody - Moving physical object. Managed by engine.
  • KinematicBody - Moving physical object. Managed by you the coder.
  • Area - Non-obstacle. Detects overlap with other physics bodies or areas.
  • VehicleBody - Simulate a moving vehicle with wheels. Includes drive and steering wheel functionality.
  • RayCast - Check along a directed line for any physics object; fast and effective check.

Objects belong to one collision layer but can collide with other objects in other layers by setting a collision mask. Objects that can collide can only be moved if they are a KinematicBody or if you manually change the position property of the object.

Tween to make position changes transition smooth?

Tilemap

Tilemap or Gridmap can be used to build out the game world. Each uses a Tileset or MeshLibrary (respectively) to build their tiles.

Observations

In Tux Builder, the main scene is the Master/Gameplay.gd. The UI is loaded with _load_node("res://Scenes/UI/LevelUI.tscn", "LevelUI"). Editor is similar.

Objects in the game are its own scene (tscn). The scene itself has _physics_process function that checks if it is affected by gravity, sets its velocity and direction to avoid out of bounds, or checks if it has reached a floor. It also checks if a player has collided with it. If he has, it plays a sound and stops its animation. The trampoline does more in a _on_Area2D_body_entered function which checks if the body is a player, enemy, or another trampoline. How a stack of trampolines interact with each other is handled here. The body that entered will have its velocity set.

Examples

Node

Example of signals

extends Node2D

signal got_hurt (damage)  

onready var hitpoints = 10 setget set_hitpoints

func set_hitpoints( new_hp ):
    var diff = new_hp - hitpoints
    if diff < 0:
        emit_signal("got_hurt", diff)
    hitpoints = new_hp

Questions & Answers

  1. How do we separate business logic from the presentation? It looks like we make models inherit Sprite so that they render so the MV (in MVC) is combined. How does this work if we want, say a 'headless' version of a game?
    • I suspect that everything even when it inherits a Sprite is treated as a model. Godot then renders everything separately when needed. This removes the dependency on graphical stuff if it isn't needed.

See Also