Hoja de Trucos de GDScript
Última actualización
Lo básico y la salida
Un script extiende un tipo de nodo, y Godot llama a sus funciones por ti.
| Operación | Sintaxis |
|---|---|
| Asociar el script a un tipo de nodo | extends Node |
| Código que se ejecuta al iniciar el nodo | func _ready() -> void:
print("Hello, World!") |
| Imprimir valores sin separador | print("HP: ", hp) |
| Imprimir valores separados por espacios | prints("a", "b", 3) |
| Comentario | # This is a comment |
| Comentario de documentación | ## Shown in the editor's help |
| Cadena de varias líneas | var text := """Line one
Line two""" |
| Informar de un error | push_error("Health is negative") |
| Informar de una advertencia | push_warning("Old save file") |
Variables, constantes y tipos
Los tipos son opcionales. Añádelos para tener comprobaciones en el editor, autocompletado y código más rápido.
| Operación | Sintaxis |
|---|---|
| Variable (tipo dinámico) | var score = 0 |
| Variable con tipo estático | var speed: float = 200.0 |
| Inferir el tipo estático | var lives := 3 |
| Constante | const MAX_HP = 100 |
| Enum | enum State { IDLE, RUN, JUMP } |
| Usar un valor de un enum | var state: State = State.IDLE |
| Valores de vector y de color | var pos := Vector2(10, 20)
var tint := Color(1, 0, 0) |
| Referencia a objeto vacía | var target: Node = null |
| Convertir a texto, int o float | str(42), int("42"), float("3.5") |
| De float a int (descarta los decimales) | int(3.9) # 3 |
| Comprobar un tipo | value is int, node is Sprite2D |
| Convertir a un tipo (cast) | var sprite := node as Sprite2D |
Operadores
Las matemáticas de siempre, más palabras en inglés para la lógica.
| Operación | Sintaxis |
|---|---|
| Sumar, restar, multiplicar, dividir | a + b, a - b, a * b, a / b |
| División entera (int / int) | 7 / 2 # 3 |
| Resto | 7 % 3, fmod(7.5, 2.0) |
| Potencia | 2 ** 10 # 1024 |
| Asignación compuesta | x += 1, x -= 1, x *= 2, x /= 2 |
| Comparación | ==, !=, <, >, <=, >= |
| Lógica | a and b, a or b, not a |
| Lógica (con símbolos) | a && b, a || b, !a |
| If en línea | var label := "win" if score > 10 else "lose" |
| Está en una colección | "sword" in inventory |
| A nivel de bits | a & b, a | b, a ^ b, ~a, a << 1, a >> 1 |
Control de flujo
Los bloques se definen por la indentación, como en Python. Godot indenta con tabulaciones por defecto.
| Operación | Sintaxis |
|---|---|
| If, elif, else | if hp <= 0:
die()
elif hp < 20:
print("Low HP")
else:
print("OK") |
| If en una línea | if hp <= 0: die() |
| Recorrer un rango | for i in range(5):
print(i) # 0 to 4 |
| Rango con inicio, fin y paso | for i in range(10, 0, -2):
print(i) # 10, 8, 6, 4, 2 |
| Repetir n veces | for i in 3:
print(i) # 0, 1, 2 |
| Recorrer un array | for item in items:
print(item) |
| Variable de bucle con tipo (Godot 4.2+) | for n: String in names:
print(n.to_upper()) |
| Bucle while | while hp > 0:
hp -= 10 |
| Salir del bucle o saltar una vuelta | break, continue |
| Marcador de bloque vacío | pass |
Coincidencia de patrones (match)
match ejecuta la primera rama cuyo patrón encaja. No hay fallthrough.
| Operación | Sintaxis |
|---|---|
| Comparar valores | match state:
State.IDLE:
print("idle")
State.RUN:
print("run") |
| Varios valores en una rama | match key:
"w", "up":
move_up() |
| Rama por defecto (comodín) | match n:
0:
print("zero")
_:
print("other") |
| Asignar el valor a un nombre | match cmd:
"quit":
get_tree().quit()
var other:
print("Unknown: ", other) |
| Patrón de array | match pos:
[0, 0]:
print("origin")
[var x, 0]:
print("on the x axis at ", x) |
| Array con cualquier resto | match args:
["move", ..]:
print("move command") |
| Patrón de diccionario | match item:
{"type": "coin", "value": var v}:
gold += v |
| Condición con when (Godot 4.4+) | match score:
var s when s >= 90:
print("A")
var s when s >= 75:
print("B")
_:
print("C") |
Funciones y lambdas
Las funciones también son valores: guárdalas, pásalas y vincúlales argumentos.
| Operación | Sintaxis |
|---|---|
| Parámetros y retorno con tipo | func add(a: int, b: int) -> int:
return a + b |
| Sin valor de retorno | func reset() -> void:
score = 0 |
| Argumento por defecto | func greet(who := "player") -> void:
print("Hi, ", who) |
| Función estática | static func double(x: int) -> int:
return x * 2 |
| Lambda de una línea | var square := func(x): return x * x |
| Llamar a un Callable | square.call(4) # 16 |
| Función como valor | var on_done := reset
on_done.call() |
| Vincular argumentos | var add_ten := add.bind(10)
print(add_ten.call(5)) # 15 |
| Lambda de varias líneas | var greet_all := func(names: Array) -> void:
for n in names:
print("Hi, ", n) |
| Esperar a un temporizador | await get_tree().create_timer(1.0).timeout |
| Esperar a una corrutina | var data = await fetch_data() |
Cadenas
Los métodos de cadena devuelven una cadena nueva y nunca modifican la original.
| Operación | Sintaxis |
|---|---|
| Formatear con % | "%s has %d HP" % [name, hp] |
| Dos decimales | "%.2f" % 3.14159 # "3.14" |
| Formatear con marcadores con nombre | "{a} vs {b}".format({"a": 1, "b": 2}) |
| Unir con + | "Score: " + str(score) |
| Longitud | text.length() |
| Mayúsculas o minúsculas | text.to_upper(), text.to_lower() |
| Dividir en partes | "a,b,c".split(",") # ["a", "b", "c"] |
| Unir partes | ", ".join(["a", "b", "c"]) |
| Quitar espacios en blanco | " hi ".strip_edges() # "hi" |
| Reemplazar texto | text.replace("cat", "dog") |
| Buscar una posición | text.find("lo") # -1 if missing |
| Empieza o termina con | text.begins_with("Hi"), text.ends_with("!") |
| Subcadena | text.substr(0, 5) |
| Contiene | "ell" in "Hello" # true |
Arrays
Los arrays crecen y se reducen. Un array con tipo solo acepta su tipo de elemento.
| Operación | Sintaxis |
|---|---|
| Literal de array (tipos mezclados) | var items = [1, "two", 3.0] |
| Array con tipo | var scores: Array[int] = [10, 20, 30] |
| Leer por índice (los negativos cuentan desde el final) | scores[0], scores[-1] |
| Añadir al final | scores.append(40), scores.push_back(40) |
| Insertar en un índice | scores.insert(0, 5) |
| Quitar y devolver el último | var last = scores.pop_back() |
| Quitar por valor o por índice | scores.erase(20), scores.remove_at(0) |
| Contiene, índice de | scores.has(30), scores.find(30) |
| Longitud, comprobar si está vacío | scores.size(), scores.is_empty() |
| Ordenar | scores.sort() |
| Ordenar con tu propia regla | enemies.sort_custom(func(a, b): return a.hp < b.hp) |
| Map | scores.map(func(x): return x * 2) |
| Filter | scores.filter(func(x): return x > 15) |
| Reduce | scores.reduce(func(acc, x): return acc + x, 0) |
| Porción (sin incluir el final) | scores.slice(1, 3) |
Diccionarios
Pares de clave y valor. Las claves pueden ser de cualquier tipo; las cadenas son lo más habitual.
| Operación | Sintaxis |
|---|---|
| Literal de diccionario | var stats = {"hp": 100, "mp": 30} |
| Diccionario con tipo (Godot 4.4+) | var prices: Dictionary[String, int] = {"sword": 50} |
| Leer o escribir una clave | stats["hp"], stats["xp"] = 50 |
| Leer con un valor por defecto | stats.get("luck", 0) |
| Tiene una clave | stats.has("hp"), "hp" in stats |
| Quitar una clave | stats.erase("mp") |
| Claves y valores | stats.keys(), stats.values() |
| Número de entradas | stats.size() |
| Fusionar otro diccionario (true sobrescribe) | stats.merge({"luck": 5}), stats.merge(bonus, true) |
| Recorrer las claves | for key in stats:
print(key, " = ", stats[key]) |
Clases y anotaciones
Cada script es una clase. Las anotaciones empiezan con @.
| Operación | Sintaxis |
|---|---|
| Dar a la clase un nombre global | class_name Player
extends CharacterBody2D |
| Constructor | func _init(start_hp := 100) -> void:
hp = start_hp |
| Crear una instancia | var p := Player.new() |
| Clase interna | class Item:
var name := ""
var price := 0 |
| Llamar a la versión del padre de este método | func _ready() -> void:
super()
print("child ready") |
| Llamar a otro método del padre | super.take_damage(10) |
| Variable estática (Godot 4.1+) | static var count := 0 |
| Mostrar en el Inspector | @export var speed := 300.0 |
| Mostrar con un rango deslizante | @export_range(0, 100) var volume := 50 |
| Obtener un nodo hijo cuando esté listo | @onready var sprite: Sprite2D = $Sprite2D |
| Setter y getter | var hp := 100:
set(value):
hp = clampi(value, 0, 100)
get:
return hp |
| Ejecutar el script en el editor | @tool |
Señales
Las señales son de primera clase: decláralas y luego emítelas, conéctalas y espéralas directamente.
| Operación | Sintaxis |
|---|---|
| Declarar una señal | signal died |
| Señal con argumentos con tipo | signal health_changed(old_hp: int, new_hp: int) |
| Emitir | died.emit() |
| Emitir con argumentos | health_changed.emit(100, 80) |
| Conectar a un método | player.died.connect(_on_player_died) |
| Conectar una lambda | button.pressed.connect(func(): print("Clicked")) |
| Pasar argumentos extra | button.pressed.connect(_on_pressed.bind("start")) |
| Disparar solo una vez | timer.timeout.connect(_on_timeout, CONNECT_ONE_SHOT) |
| Desconectar | player.died.disconnect(_on_player_died) |
| Comprobar una conexión | player.died.is_connected(_on_player_died) |
| Esperar a una señal | await player.died |
Nodos y ciclo de vida
Los callbacks que Godot llama en tu nodo y las llamadas que haces al árbol de escena.
| Operación | Sintaxis |
|---|---|
| Objeto creado (antes del árbol) | func _init() -> void:
print("created") |
| El nodo y sus hijos están listos | func _ready() -> void:
print("ready") |
| En cada frame | func _process(delta: float) -> void:
position.x += 100.0 * delta |
| En cada paso de física | func _physics_process(delta: float) -> void:
velocity.y += 980.0 * delta
move_and_slide() |
| Entrada que la interfaz no usó | func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("jump"):
jump() |
| Obtener un nodo por ruta | get_node("Sprite2D"), $Sprite2D |
| Ruta con espacios, nombre único | $"UI/Health Bar", %HealthBar |
| Comprobar una acción de entrada | Input.is_action_pressed("move_right") |
| Crear una instancia de una escena | var enemy := preload("res://enemy.tscn").instantiate()
add_child(enemy) |
| Borrar un nodo de forma segura | queue_free() |
| Padre e hijos | get_parent(), get_children() |
| Cambiar de escena | get_tree().change_scene_to_file("res://main.tscn") |
La sintaxis de GDScript que necesitas mientras creas un juego en Godot, en una sola página. Esta hoja de trucos de GDScript es una referencia rápida para Godot 4: variables y tipos estáticos, operadores, control de flujo y match, funciones y lambdas, cadenas, arrays y diccionarios, clases, señales y los callbacks de nodo que Godot ejecuta en cada frame.
Todo lo que hay aquí es sintaxis de Godot 4, así que verás @export, @onready, died.emit() y await en lugar de las formas de Godot 3. Copia lo que necesites en tu script o prueba los fragmentos del lenguaje en vivo en el playground de GDScript: ponlos dentro de _ready() y ejecútalos en tu navegador, sin instalar Godot.
Preguntas frecuentes sobre la hoja de trucos de GDScript
¿Esta hoja de trucos de GDScript es gratis?
¿Esta hoja de trucos es para Godot 4 o Godot 3?
@export y @onready en lugar de las palabras clave export y onready, died.emit() y died.connect(callable) en lugar de emit_signal("died") y el connect basado en cadenas, await en lugar de yield, y super() en lugar de .method(). Las filas marcadas con 4.1+, 4.2+ o 4.4+ necesitan al menos esa versión de Godot.¿Cuál es la diferencia entre = y := en GDScript?
var x = 5 crea una variable dinámica que más adelante puede contener cualquier tipo. var x := 5 infiere el tipo a partir del valor (aquí int) y lo fija, así que asignarle después una cadena es un error. var x: int = 5 indica el tipo de forma explícita. Los tipos estáticos te dan errores en el editor, mejor autocompletado y código más rápido.¿Cómo funcionan las señales en GDScript?
signal died, envíala con died.emit() y reacciona a ella desde otro nodo con player.died.connect(_on_player_died). Puedes conectar una lambda en lugar de un método, vincular argumentos extra con .bind() o pausar una función hasta que se dispare la señal con await player.died.¿GDScript se parece a Python?
for ... in, if/elif/else y palabras en inglés como and, or y not. Pero GDScript es un lenguaje propio, creado para Godot. Tiene tipos estáticos opcionales, señales, anotaciones como @export y acceso directo a los nodos con $.¿Puedo practicar GDScript online?
_ready() se ejecuta una vez. Cuando quieras algo más estructurado, el curso interactivo gratuito de GDScript de Coddy te lleva paso a paso desde las variables y funciones hasta las clases y señales.