Introducción: de las palabras clave a las anotaciones
Godot 4 sustituyó varias palabras clave de GDScript por anotaciones con el prefijo @. Esto formó parte de un esfuerzo mayor por hacer la sintaxis de GDScript más limpia y coherente. Los tres cambios más importantes son:
export→@exportonready→@onreadytool→@tool
Las anotaciones se colocan en la línea anterior (o en la misma línea) a la declaración que modifican. Godot 4 también introdujo muchas variantes de anotación nuevas como @export_range, @export_group y @export_category que no existían en Godot 3. Esta guía las cubre todas.
@export básico
La anotación @export expone una variable en el Inspector de Godot, permitiéndote configurar valores sin editar código. Godot elige automáticamente el widget de editor adecuado según el tipo de la variable.
@export var speed: float = 300.0
@export var player_name: String = "Player"
@export var health: int = 100
@export var color: Color = Color.WHITE
@export var texture: Texture2D
@export var scene: PackedScene
Consejo: añade siempre anotaciones de tipo a las variables exportadas. Esto garantiza que el Inspector muestre el widget correcto (por ejemplo, un selector de color para Color o una ranura de recurso para Texture2D).
@export_range — Deslizadores numéricos
@export_range restringe un valor numérico a un mínimo y un máximo, mostrando un deslizador en el Inspector. También puedes especificar un tamaño de paso y pistas como "or_greater" u "or_less".
@export_range(0, 100) var health: int = 100
@export_range(0.0, 1.0, 0.01) var volume: float = 0.8
@export_range(0, 1000, 1, "or_greater") var damage: int = 10
La pista "or_greater" permite escribir valores por encima del máximo manteniendo el rango del deslizador acotado. De forma similar, "or_less" permite valores por debajo del mínimo.
@export_enum — Menús desplegables
@export_enum crea un desplegable en el Inspector. Cuando se usa con String, se almacena el nombre de la opción seleccionada. Cuando se usa con int, puedes asignar valores explícitos.
# Stores the string name: "Warrior", "Mage", or "Rogue"
@export_enum("Warrior", "Mage", "Rogue") var character_class: String
# Stores the integer value: 0, 1, or 2
@export_enum("Easy:0", "Normal:1", "Hard:2") var difficulty: int = 1
@export_file y @export_dir — Rutas de archivo/directorio
@export_file muestra un diálogo de archivo en el Inspector. Puedes filtrar por extensión de archivo. @export_dir muestra un diálogo de selección de directorio.
@export_file("*.tscn") var next_level: String
@export_dir var save_directory: String
La cadena de filtro usa patrones glob. Se pueden separar varios filtros con comas: "*.png,*.jpg".
@export_multiline y @export_placeholder
@export_multiline proporciona una gran área de texto para cadenas de varias líneas (ideal para diálogos o descripciones). @export_placeholder muestra un texto de sugerencia dentro del campo cuando está vacío.
@export_multiline var description: String
@export_placeholder("Enter name...") var player_name: String
@export_group y @export_subgroup — Organizar las propiedades del Inspector
@export_group crea un encabezado de grupo plegable en el Inspector. Todas las variables @export que le siguen pertenecen a ese grupo hasta el siguiente grupo o categoría. @export_subgroup anida dentro del grupo actual.
@export_group("Movement")
@export var speed: float = 300.0
@export var jump_force: float = 400.0
@export_group("Combat")
@export var attack_damage: int = 10
@export var defense: int = 5
@export_subgroup("Ranged")
@export var projectile_speed: float = 500.0
Los grupos y subgrupos son puramente organizativos — no afectan al acceso a las variables en el código, solo a cómo aparecen las propiedades en el Inspector.
@export_category — Encabezados de categoría en negrita
@export_category crea un encabezado de categoría de nivel superior en negrita en el Inspector. A diferencia de los grupos, las categorías no se pueden plegar y actúan como un separador visual fuerte entre conjuntos de propiedades no relacionados.
@export_category("Player Stats")
@export var level: int = 1
@export var experience: int = 0
@export con referencias a nodos
Puedes exportar un NodePath para que los diseñadores elijan un nodo del árbol de escena. En Godot 4.2+, puedes exportar directamente una referencia a nodo tipada — sin necesidad de NodePath.
# Classic NodePath export
@export var target_path: NodePath
# Godot 4.2+: typed node export (direct reference, no NodePath needed)
@export var sprite: Sprite2D
@export var collision: CollisionShape2D
Las exportaciones de nodos tipados son el enfoque recomendado en el Godot 4 moderno. El Inspector muestra un selector de nodos filtrado al tipo especificado, y obtienes autocompletado completo en el editor de scripts.
@export_flags — Casillas de máscara de bits
@export_flags crea un conjunto de casillas donde cada opción corresponde a un bit de un entero. Godot también proporciona exportaciones de banderas integradas para las capas de física y de renderizado.
# Custom flags: Fire=1, Water=2, Earth=4, Wind=8
@export_flags("Fire", "Water", "Earth", "Wind") var elements: int
# Built-in physics layer flags
@export_flags_2d_physics var collision_layers: int
@export_flags_2d_render var render_layers: int
@export_flags_3d_physics var collision_layers_3d: int
@onready — Inicialización diferida
@onready difiere la inicialización de la variable hasta que el nodo entra en el árbol de escena (equivalente a asignarla en _ready()). Esto es esencial cuando se referencian nodos hijos con $, porque los hijos no están disponibles en tiempo de análisis.
# Godot 3 (old syntax):
# onready var sprite = $Sprite2D
# Godot 4:
@onready var sprite: Sprite2D = $Sprite2D
@onready var anim: AnimationPlayer = $AnimationPlayer
@onready var label: Label = $UI/ScoreLabel
Buena práctica: tipa siempre tus variables @onready. Esto habilita el autocompletado y detecta errores de tipo en tiempo de análisis en lugar de en tiempo de ejecución.
@tool — Ejecutar scripts en el editor
@tool hace que un script se ejecute dentro del editor de Godot (no solo en tiempo de ejecución). Es potente para crear vistas previas personalizadas, gizmos y propiedades que se actualizan en vivo. Colócalo justo al principio del script, antes de extends.
@tool
extends Node2D
@export var radius: float = 100.0:
set(value):
radius = value
queue_redraw() # Redraw in editor when value changes
func _draw() -> void:
draw_circle(Vector2.ZERO, radius, Color.WHITE)
Advertencia: ten cuidado con los scripts @tool. El código en _process() y _physics_process() se ejecutará en el editor. Usa Engine.is_editor_hint() para proteger la lógica exclusiva del juego.
Otras anotaciones
@icon
Establece un icono personalizado para el tipo de nodo del script en el panel de Escena y en el diálogo Crear nodo.
@icon("res://icons/enemy.svg")
extends CharacterBody2D
@warning_ignore
Suprime advertencias específicas de GDScript para la siguiente instrucción. Útil cuando sombreas intencionadamente una variable o tienes un parámetro sin usar.
@warning_ignore("unused_parameter")
func _on_body_entered(body: Node2D) -> void:
queue_free()
@warning_ignore("shadowed_variable")
var size: int = 10
@static_unload
Marca un script para que Godot pueda descargarlo de la memoria cuando no existan instancias. Esto puede reducir el uso de memoria en scripts que solo se usan temporalmente. El script no debe tener variables estáticas ni datos que necesiten persistir.
@static_unload
extends RefCounted
# This script can be safely unloaded when not in use
Buenas prácticas de tipado estático
Aunque no son anotaciones, las pistas de tipo estático están estrechamente relacionadas y se recomiendan encarecidamente en Godot 4. Mejoran el autocompletado, permiten la comprobación de errores en tiempo de compilación y pueden mejorar el rendimiento.
# Variable type annotations
var speed: float = 300.0
var player: CharacterBody2D = null
var items: Array[String] = []
var scores: Dictionary = {}
# Function return types and parameter types
func get_damage() -> int:
return attack - defense
func apply_force(direction: Vector2, strength: float) -> void:
velocity += direction * strength
# Type inference with :=
var pos := Vector2(100, 200) # Inferred as Vector2
Nota: ten cuidado con := en los bucles for al iterar sobre arrays sin tipar. Usa anotaciones de tipo explícitas en su lugar: for item: String in array.
Hoja de migración: de Godot 3 a 4
Referencia rápida para convertir la sintaxis de exportación de Godot 3 a las anotaciones de Godot 4:
| Godot 3 | Godot 4 | Notas |
|---|---|---|
export var x |
@export var x |
Exportación básica |
export(int, 0, 100) var hp |
@export_range(0, 100) var hp: int |
Rango con pista de tipo |
export(String, "A", "B") var x |
@export_enum("A", "B") var x: String |
Desplegable de enumeración |
export(String, FILE) var path |
@export_file var path: String |
Selector de archivos |
export(String, MULTILINE) var text |
@export_multiline var text: String |
Área de texto multilínea |
export(int, FLAGS, ...) var f |
@export_flags(...) var f: int |
Banderas de máscara de bits |
onready var x = $Node |
@onready var x: Type = $Node |
Inicialización diferida |
tool |
@tool |
Ejecución en el editor |
| N/D | @export_group("...") |
Nuevo en Godot 4 |
| N/D | @export_category("...") |
Nuevo en Godot 4 |
| N/D | @export_subgroup("...") |
Nuevo en Godot 4 |
Godot MCP Pro entiende todas las anotaciones @export
Godot MCP Pro puede crear scripts con exportaciones correctamente tipadas, leer y modificar anotaciones de exportación existentes e inspeccionar las propiedades exportadas de cualquier nodo de tu escena — todo a través de la IA.
- create_script
- edit_script
- read_script
- get_node_properties
- get_scene_exports
- update_property