Every GDScript file is a class. Its member variables are the fields, its functions are the methods, and extends names the class it builds on. A script can also define classes inside it, which is how this example runs in one file:
slime alive: false
golem hp: 38
Enemy.new(...)creates an instance and calls_init()with the arguments.- Each instance has its own
kindandhp. - Inside a method, members are used by name.
self.hpmeans the same and is only needed when a local variable has the same name.
class_name: Naming a Script
In a real project you put a class in its own file and name it with class_name:
# enemy.gd
class_name Enemy
extends CharacterBody2D
@export var max_hp := 10
var hp: int
func _ready():
hp = max_hp
func take_damage(amount: int) -> void:
hp -= amount
if hp <= 0:
queue_free()
Now every script can use Enemy as a type: var target: Enemy, if body is Enemy:, and Enemy shows up in the Create Node dialog. Without class_name, you would load the script by path: const Enemy = preload("res://enemy.gd").
The two lines can also be written as one: class_name Enemy extends CharacterBody2D.
Nodes and Scenes Are Classes Too
A script that extends a node type is instantiated by Godot when it loads the scene, so you rarely call new() on it. You spawn a whole scene instead:
const EnemyScene = preload("res://enemy.tscn")
func spawn_enemy(at: Vector2) -> void:
var enemy: Enemy = EnemyScene.instantiate()
enemy.position = at
add_child(enemy)
Enemy.new() would create the bare script node with none of the scene's children, such as its sprite and collision shape. Use new() for plain data classes and nodes you build entirely in code.
Because scenes create nodes by calling _init() with no arguments, a node script's _init() should not require parameters.
Printing an Object
print() on an object shows its class and id. Define _to_string() to choose the text:
Sword (50 gold)
[Sword (50 gold), Shield (30 gold)]
Which Class to Extend
extends | Use it for | Freed by |
|---|---|---|
nothing, or RefCounted | plain data and logic | itself, when no variable points at it |
Resource | data you save, load and edit in the Inspector | itself, like RefCounted |
Node or any node type | things in the scene tree | queue_free() |
Object | rare, low-level objects | you, with free() |
A script with no extends line extends RefCounted. See resources for data classes the editor can show.
Checking an Object's Class
true
true
true Node
1 true
is works with engine classes and your own classes. get_class() returns the engine class name, which is the built-in base, not your script's name. in and get() look up a property by its name.
Classes build on each other with inheritance, and properties can run code when read or written with setters and getters.
Frequently Asked Questions
What does class_name do in Godot?
class_name Player registers the script as a global type named Player. Any script can then write var p: Player, Player.new() or body is Player, and the class appears in the editor's Create Node dialog. Without it you refer to the script by path with preload().
How do I write a constructor in GDScript?
Define func _init():. It runs when the object is created with new(), and it may take parameters: func _init(start_hp: int): is called by Enemy.new(40).
Should a node script's _init() take parameters?
Avoid it. Godot creates nodes from scenes by calling _init() with no arguments, so required parameters break loading the node from a scene. Give the parameters defaults, or set the values after instantiate().
Do I need to free objects in GDScript?
It depends on the base class. RefCounted objects (the default for a script with no extends, and every Resource) are freed automatically. A Node in the scene tree is freed with queue_free(). A plain Object or a node that is not in the tree must be freed with free(), or it leaks.