Godot
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 | 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 |
# 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
- 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.