Instruction路径 · instructions/godot-4-gdscript.instructions.md
godot-4-gdscript.instructions.md
Frontmatter
- applyTo
- **/*.gd
简介
防止在 Godot 4 项目中使用 Godot 3 语法:GDScript 2.0 注解、await、setter、@rpc、类型化信号与 Callable
机器翻译 · 已翻译 · 模型 default
正文
---
# Godot 4 GDScript 2.0 (no Godot 3 syntax)
## GDScript 2.0 syntax (never Godot 3)
| Godot 3 (wrong) | Godot 4 (use) |
|---|---|
| `export var speed = 5` / `export(int) var` | `@export var speed: float = 5.0` (`@export_range`, `@export_enum`, `@export_group`) |
| `onready var x = $X` | `@onready var x: Node2D = $X` |
| `tool` | `@tool` (first line) |
| `yield(get_tree().create_timer(1), "timeout")` | `await get_tree().create_timer(1.0).timeout` |
| `yield(obj, "signal")` | `await obj.signal_name` |
| `var x setget set_x, get_x` | `var x: int:` with `set(value):` / `get:` blocks |
| `puppet` funcs | `@rpc` (authority-only; Godot 4 default) |
| `remote` funcs | `@rpc("any_peer")` |
| `remotesync` funcs | `@rpc("any_peer", "call_local")` |
| `puppetsync` funcs | `@rpc("call_local")` |
| `master` funcs | no direct map; use `@rpc("any_peer")` + `multiplayer.get_remote_sender_id()` check |
| `funcref(obj, "m")` | `Callable(obj, "m")` or just `obj.m` |
| `PoolStringArray`, `PoolVector2Array` | `PackedStringArray`, `PackedVector2Array` |
- Use static typing everywhere: `var hp: int = 100`, `func hit(dmg: int) -> void:`. Use `:=` for inferred types.
- Lifecycle overrides (`_ready`, `_process`) no longer call the parent automatically; call `super()` when extending a scripted class.
- Use `StringName` literals `&"action"` for input actions/groups and `^"path"` NodePaths where it helps.
## Signals & Callables
- Declare typed signals: `signal health_changed(new_value: int)`.
- Connect with the Signal object: `button.pressed.connect(_on_button_pressed)`. Never use the Godot 3 form `connect("pressed", self, "_on_button_pressed")`.
- Bind extra args with `.bind()`: `enemy.died.connect(_on_enemy_died.bind(enemy))`. Flags: `connect(callable, CONNECT_ONE_SHOT)`.
- Emit with `health_changed.emit(hp)` rather than `emit_signal("health_changed", hp)`.
- Disconnect with `sig.disconnect(callable)`; check `sig.is_connected(callable)` first.
- Use lambdas for small handlers: `timer.timeout.connect(func(): queue_free())`.
- Prefer signals ("call down, signal up") over `get_parent().get_parent()` chains.