godot-gdscript
Skill7 starsChanged 5 months agoMITView on GitHub
写 Godot(GDScript/C#)时使用。节点树、signal、场景、性能规范。
4 other projects use a version of this.
Adopted by
Most recently taken up by
- MindsMaster/godot-claude-code-skillstheir own version, first seen Oct 25, 2026
- gamedev-skills/awesome-gamedev-agent-skillstheir own version, first seen Oct 23, 2026
- gosomea/dsh-godot-aitheir own version, first seen Oct 8, 2026
- fetasty/godot-skillstheir own version, first seen May 16, 2026
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 4
- gamedev-skills/awesome-gamedev-agent-skills★ 6.4ksame name
- fetasty/godot-skills★ 29same name
- gosomea/dsh-godot-ai★ 9same name
- MindsMaster/godot-claude-code-skills★ 3same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository47 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- api-designSkill
- chinese-commitSkill
- ci-cd-pipelineSkill
- cocos2dx-luaSkill
- cocos-creator-adaptationSkill
- cocos-creator-bundleSkill
- cocos-creator-drawcallSkill
- cocos-creator-hotupdateSkill
- cocos-creatorSkill
- cocos-creator-tween-animSkill
- cocos-creator-ui-listSkill
- code-review-selfSkill
- concurrency-safetySkill
- core-disciplineSkill
- database-safetySkill
- docker-best-practicesSkill
- domestic-stackSkill
- error-handlingSkill
- frontend-best-practicesSkill
- game-assets-memorySkill
- game-mathSkill
- game-netcodeSkill
- game-performanceSkill
- gameplay-architectureSkill
- go-idiomsSkill
- input-validationSkill
- integration-testingSkill
- large-repo-refactorSkill
- legacy-safe-editSkill
- naming-thingsSkill
- node-best-practicesSkill
- performance-profilingSkill
- pr-descriptionSkill
- python-idiomsSkill
- requirement-deliverySkill
- rust-safetySkill
- secrets-handlingSkill
- security-reviewSkill
- shell-scripting-safeSkill
- systematic-debuggingSkill
- test-data-managementSkill
- test-drivenSkill
- unity-csharpSkill
- unreal-cppSkill
- writing-docsSkill
The file
Files
Godot
何时用
- 新建或修改任何 GDScript 脚本或 C# 组件脚本时。
- 节点间通信方式有疑问(是用 get_node、直接引用还是 signal)时。
_process和_physics_process里的逻辑越写越多、帧率下降时。- 场景实例化、资源加载/释放方式不确定时。
- 遇到内存泄漏、孤立节点、信号未断开等问题时。
核心规则
1. 节点与场景:@onready 缓存,场景实例化代替继承
规则: 节点引用用 @onready 在 _ready() 阶段一次性缓存;不在 _process 里反复 get_node();复用结构用场景实例化,而不是多层继承。
为什么——真实会犯的错:
在 _process(delta) 里每帧写 $AnimationPlayer.play("run"),GDScript 每次都要解析节点路径字符串、在节点树里做查找,场景节点数量一多(几百个)帧率肉眼可见地跌。另一个常见错误:用继承堆叠 Enemy → FlyingEnemy → BossEnemy → FinalBoss,四层下来 _ready 调用顺序、信号连接变得极难追踪,改一层上面全乱。
怎么做:
- 节点引用用
@onready var anim: AnimationPlayer = $AnimationPlayer,只在_ready()时解析一次路径,后续直接用变量。 - 逻辑上独立、可复用的结构拆成独立场景(
.tscn),用instantiate()生成,而不是靠继承叠加。 get_node()只在_ready()、事件回调里调用,不放进_process或_physics_process。
2. signal 解耦:通信走信号,连接必须断开
规则: 节点间跨层通信用 signal;子节点不直接持有父节点引用;场景卸载或节点销毁前断开信号连接,防止内存泄漏和空引用回调。
为什么——真实会犯的错:
Enemy 脚本里写了 get_parent().get_node("HUD").show_damage(damage),这条路径硬绑了节点树结构,一旦 HUD 改了层级或名称,运行时立刻报 null,且错误信息只提示"尝试调用 null 上的方法",找来找去才发现是节点路径变了。另一个事故:动态生成的子弹连接了 GameManager 的信号,子弹 queue_free() 后没有断开,GameManager 还保持对已销毁节点的引用,触发回调时崩溃或静默错误。
怎么做:
- 子节点向上通信 → 发射
signal,父节点监听,子节点不引用父节点。 - 跨系统通信 → 用 Autoload(单例)中转,或通过 signal bus。
- 动态节点连接信号时,在
_exit_tree()或queue_free()前调用signal.disconnect(callback)断开。 - 用
connect(..., CONNECT_ONE_SHOT)处理只触发一次的事件,自动断开更安全。
3. _process vs _physics_process:物理归物理,能事件驱动就不轮询
规则: 涉及物理体、碰撞、速度的逻辑一律放 _physics_process(delta);纯表现层更新可放 _process(delta);能用信号/事件触发的逻辑不轮询。
为什么——真实会犯的错:
在 _process 里移动 CharacterBody2D,与物理引擎以不同频率运行,出现抖动和碰撞穿透,在低帧机器上更明显。另一个方向:把大量 UI 状态检测("玩家血量是否低于 20%")放在 _physics_process 里每帧判断,不必要地占用物理线程。还有把"按下攻击键"的检测放在 _process 里,输入延迟和物理帧不对齐,打击感差。
怎么做:
move_and_slide()、碰撞查询、刚体速度赋值 → 全进_physics_process。- 摄像机插值、粒子参数更新等纯视觉逻辑 → 可放
_process。 - 玩家输入 →
_unhandled_input()或_input()回调,不在_process里 pollInput.is_action_pressed()(除非需要持续检测,如长按移动)。 - 状态变化通知(血量减少 → 更新 UI)→ 发射 signal,不在
_process里每帧比对旧值。
4. 静态类型:GDScript 2.0 类型注解全开
规则: 所有变量、函数参数、返回值都加类型注解;避免用 Variant 做中间传递;禁止用字符串做类型名传给 get_node()、is_class() 等。
为什么——真实会犯的错:
var speed = 5 写成动态类型,Godot 运行时每次访问都要推断类型,100 个敌人 × 每帧访问数十次,性能损耗可测量。更常见的问题是可读性:func deal_damage(target, amount) 两个参数都是 Variant,调用方传错类型(把 Node 传给了期望 float 的 amount),运行时才报错,且错误提示不友好。用了字符串类 get_node("Player").has_method("take_hit") 这种动态查找,重构时改了方法名但字符串没改,静默失效。
怎么做:
- 变量:
var speed: float = 5.0,var health: int = 100。 - 函数:
func deal_damage(target: CharacterBody2D, amount: float) -> void:。 - 节点引用:
@onready var player: CharacterBody2D = $Player,有类型后能享受 IDE 补全和静态检查。 - 回调和信号连接的函数签名也要与信号声明的参数类型一致,不用
Variant兜底。
5. 资源释放:queue_free 正确时机,避免循环引用
规则: 动态生成的节点用 queue_free() 释放,不用 free();preload 预加载静态资源,load 按需加载动态资源;Resource 之间不能循环引用。
为什么——真实会犯的错:
在回调函数中直接调 node.free(),如果此帧还有其他代码持有该节点的引用并继续调用其方法,立刻崩溃报 freed object。用 queue_free() 则会等本帧所有逻辑跑完再安全删除。另一个常见问题:两个 Resource(如 WeaponData 和 AbilityData)互相持有对方引用,GDScript 的引用计数无法回收,内存随关卡切换不断增长。
怎么做:
- 销毁节点一律用
queue_free(),不用free()(除非你清楚知道当前帧没有其他引用)。 - 场景启动时就需要的资源(UI 图、常用音效)→
preload("res://...")编译期绑定。 - 按关卡动态加载的大资源 →
ResourceLoader.load_threaded_request()异步加载,避免卡主线程。 - Resource 设计时保证单向依赖,用 NodePath 或 StringName 做弱引用替代直接持有对方 Resource 对象。
正例 / 反例
反例:get_node 在 _process 里 + 硬引用父节点 + 无类型注解
# ❌ 反例 — 每帧解析路径;硬引用父节点;无类型注解
extends Node
func _process(delta):
# 每帧都在节点树里查找路径字符串,性能差
$AnimationPlayer.play("idle")
# 子节点直接拿父节点的子节点,耦合严重
get_parent().get_node("HUD").update_hp(get_parent().get_node("Player").hp)
func take_damage(amount): # 参数无类型,调用方传错不报错
get_parent().get_node("Player").hp -= amount正例:@onready 缓存 + signal 解耦 + 静态类型
# ✅ 正例 — onready 缓存;signal 向上通信;全类型注解
extends CharacterBody2D
signal health_changed(new_hp: int) # 信号携带类型
@onready var anim: AnimationPlayer = $AnimationPlayer # 一次缓存
var hp: int = 100
func _ready() -> void:
anim.play("idle") # 直接用缓存变量,无路径查找
func take_damage(amount: float) -> void:
hp -= int(amount)
health_changed.emit(hp) # 发信号,不直接引用 HUD
func _on_died() -> void:
queue_free() # 安全释放,不用 free()自查清单
- 节点引用全部用
@onready缓存,_process/_physics_process里没有get_node()调用。 - 跨节点通信用 signal,子节点没有直接引用父节点或兄弟节点。
- 物理/碰撞逻辑在
_physics_process,纯表现逻辑在_process,状态变化用 signal 通知而非每帧轮询。 - 所有变量、函数参数、返回值都有 GDScript 2.0 类型注解,没有裸
Variant。 - 动态节点销毁用
queue_free(),信号连接在节点退出树前断开。 - Resource 之间无循环引用;大资源用异步加载,不阻塞主线程。
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

