重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
godot by bfollington/terma
npx skills add https://github.com/bfollington/terma --skill godot专门指导使用 Godot Engine 开发游戏和应用程序,重点强调 LLM 编码助手与 Godot 独特文件结构之间的有效协作。
Godot 项目混合使用 GDScript 代码文件 (.gd) 和基于文本的资源文件 (.tscn 用于场景,.tres 用于资源)。虽然 GDScript 很直观,但资源文件有严格的格式要求,与 GDScript 语法有显著差异。本技能提供文件格式专业知识、经过验证的架构模式、验证工具、代码模板和调试工作流,以实现 Godot 项目的有效开发。
在以下情况下调用此技能:
GDScript (.gd) - 完整的编程语言:
extends Node
class_name MyClass
var speed: float = 5.0
const MAX_HEALTH = 100
func _ready():
print("Ready")
场景文件 (.tscn) - 严格的序列化格式:
[ext_resource type="Script" path="res://script.gd" id="1"]
[node name="Player" type="CharacterBody3D"]
script = ExtResource("1") # NOT preload()!
资源文件 (.tres) - 不使用 GDScript 语法:
[ext_resource type="Script" path="res://item.gd" id="1"]
[resource]
script = ExtResource("1") # NOT preload()!
item_name = "Sword" # NOT var item_name = "Sword"!
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
在 .tres/.tscn 文件中绝对不要使用:
preload() - 使用 ExtResource("id") 代替var, const, func - 这些是 GDScript 关键字Array[Type]([...]) 语法在 .tres/.tscn 文件中始终使用:
ExtResource("id") 用于外部资源SubResource("id") 用于内联资源Array[Resource]([...])将逻辑保留在 .gd 文件中,数据保留在 .tres 文件中:
src/
spells/
spell_resource.gd # 类定义 + 逻辑
spell_effect.gd # 效果逻辑
resources/
spells/
fireball.tres # 仅数据,引用脚本
ice_spike.tres # 仅数据
这使得 LLM 编辑更加安全和清晰。
将功能分解为小型、专注的组件:
Player (CharacterBody3D)
├─ HealthAttribute (Node) # 组件
├─ ManaAttribute (Node) # 组件
├─ Inventory (Node) # 组件
└─ StateMachine (Node) # 组件
├─ IdleState (Node)
├─ MoveState (Node)
└─ AttackState (Node)
优点:
使用信号实现松耦合:
# 组件发出信号
signal health_changed(current, max)
signal death()
# 父节点连接到信号
func _ready():
$HealthAttribute.health_changed.connect(_on_health_changed)
$HealthAttribute.death.connect(_on_death)
优点:
在 Godot 中测试之前验证 .tres 和 .tscn 文件,以便及早捕获语法错误。
验证 .tres 文件:
python3 scripts/validate_tres.py resources/spells/fireball.tres
验证 .tscn 文件:
python3 scripts/validate_tscn.py scenes/player/player.tscn
在以下情况下使用这些脚本:
需要时加载参考文件以获取详细信息:
references/file-formats.md - 深入探讨 .gd、.tscn、.tres 语法:
references/architecture-patterns.md - 经过验证的架构模式:
在以下情况下阅读这些参考:
使用模板作为常见模式的起点。模板位于 assets/templates/:
component_template.gd - 包含信号、导出变量、激活功能的基础组件:
# 复制并自定义以创建新组件
cp assets/templates/component_template.gd src/components/my_component.gd
attribute_template.gd - 数值属性(生命值、法力值、耐力值):
# 用于任何具有最小/最大值的数值属性
cp assets/templates/attribute_template.gd src/attributes/stamina_attribute.gd
interaction_template.gd - 交互组件基类:
# 扩展以创建自定义交互(拾取、门、开关等)
cp assets/templates/interaction_template.gd src/interactions/lever_interaction.gd
spell_resource.tres - 带有效果的法术示例:
# 用作创建新法术数据的参考
cat assets/templates/spell_resource.tres
item_resource.tres - 物品资源示例:
# 用作创建新物品数据的参考
cat assets/templates/item_resource.tres
示例:为敌人添加生命值系统。
步骤:
阅读架构模式参考:
# 检查类似模式
Read references/architecture-patterns.md
# 查找“属性系统”部分
使用模板创建基类:
cp assets/templates/attribute_template.gd src/attributes/attribute.gd
# 自定义基类
创建专门的子类:
# 创建继承自 attribute.gd 的 health_attribute.gd
# 添加生命值特定的信号(damage_taken, death)
通过编辑 .tscn 添加到场景:
[ext_resource type="Script" path="res://src/attributes/health_attribute.gd" id="4_health"]
[node name="HealthAttribute" type="Node" parent="Enemy"]
script = ExtResource("4_health")
value_max = 50.0
value_start = 50.0
立即在 Godot 编辑器中测试
如果有问题,验证场景文件:
python3 scripts/validate_tscn.py scenes/enemies/base_enemy.tscn
示例:创建新法术。
步骤:
参考模板:
cat assets/templates/spell_resource.tres
使用正确的结构创建新的 .tres 文件:
[gd_resource type="Resource" script_class="SpellResource" load_steps=3 format=3]
[ext_resource type="Script" path="res://src/spells/spell_resource.gd" id="1"]
[ext_resource type="Script" path="res://src/spells/spell_effect.gd" id="2"]
[sub_resource type="Resource" id="Effect_1"]
script = ExtResource("2")
effect_type = 0
magnitude_min = 15.0
magnitude_max = 25.0
[resource]
script = ExtResource("1")
spell_name = "Fireball"
spell_id = "fireball"
mana_cost = 25.0
effects = Array[ExtResource("2")]([SubResource("Effect_1")])
测试前验证:
python3 scripts/validate_tres.py resources/spells/fireball.tres
修复验证器报告的任何错误
在 Godot 编辑器中测试
当用户报告“资源加载失败”或类似错误时。
步骤:
读取错误中报告的文件:
# 检查文件语法
Read resources/spells/problem_spell.tres
运行验证脚本:
python3 scripts/validate_tres.py resources/spells/problem_spell.tres
检查常见错误:
preload() 而不是 ExtResource()var, const, func 关键字如果需要,阅读文件格式参考:
Read references/file-formats.md
# 关注“资源文件 (.tres)”部分
# 检查“常见错误参考”
修复错误并重新验证
当实现已知模式(交互系统、状态机等)时。
步骤:
阅读相关模式:
Read references/architecture-patterns.md
# 查找特定模式(例如,“基于组件的交互系统”)
复制相关模板:
cp assets/templates/interaction_template.gd src/interactions/door_interaction.gd
自定义模板:
_perform_interaction()按照模式创建场景结构:
[node name="Door" type="StaticBody3D"]
script = ExtResource("base_interactable.gd")
[node name="DoorInteraction" type="Node" parent="."]
script = ExtResource("door_interaction.gd")
interaction_text = "Open Door"
逐步测试
使用 GUT(Godot 单元测试)来测试纯逻辑——任何不依赖于场景树的 RefCounted 或 Resource 类都是很好的候选对象。卡牌系统、计分、状态机、地图生成器、挑战逻辑等。
addons/gut/ 放入你的项目.gutconfig.json:{
"dirs": ["res://test/unit"],
"prefix": "test_",
"suffix": ".gd",
"log_level": 1
}
测试位于 test/unit/,文件以 test_ 为前缀,继承自 GutTest:
extends GutTest
func test_score_calculation() -> void:
var scoring := Scoring.new()
assert_eq(scoring.calculate(3, 0), 100, "Base score for 3 moves")
assert_gt(scoring.calculate(2, 0), scoring.calculate(3, 0), "Fewer moves = higher score")
func test_deck_shuffle() -> void:
var rng := RandomNumberGenerator.new()
rng.seed = 42
var deck := CardSystem.create_shuffled_deck(rng)
assert_eq(deck.size(), 52, "Full deck")
关键约定:
test_ 开头_ 前缀(不会被识别为测试)before_each() / after_each() 进行设置/清理assert_eq, assert_ne, assert_true, assert_false, assert_gt, assert_lt, assert_null, assert_not_null# 运行所有测试(通过时返回退出码 0,失败时返回 1)
godot -d -s --path "$PWD" addons/gut/gut_cmdln.gd -gexit
# 运行特定的测试文件
godot -d -s --path "$PWD" addons/gut/gut_cmdln.gd -gtest=res://test/unit/test_scoring.gd -gexit
# 运行匹配模式的测试
godot -d -s --path "$PWD" addons/gut/gut_cmdln.gd -gdir=res://test/unit -gselect=weekly -gexit
优先测试继承自 RefCounted 或 Resource 的纯逻辑类:
避免在单元测试中测试依赖于场景树的代码(渲染、UI、输入处理)。
问题:
# ❌ 错误
script = preload("res://script.gd")
var items = [1, 2, 3]
解决方案:
# ✅ 正确
[ext_resource type="Script" path="res://script.gd" id="1"]
script = ExtResource("1")
items = Array[int]([1, 2, 3])
预防措施: 测试前运行验证脚本。
问题:
[resource]
script = ExtResource("1_script") # 未声明!
解决方案:
[ext_resource type="Script" path="res://script.gd" id="1_script"]
[resource]
script = ExtResource("1_script")
检测方法: 验证脚本会捕获此错误。
问题: 修改实例化场景的子节点可能在编辑器重新保存时被破坏。
解决方案:
问题:
effects = [SubResource("Effect_1")] # 缺少类型
解决方案:
effects = Array[Resource]([SubResource("Effect_1")])
预防措施: 验证脚本会警告此问题。
问题: 实例化场景时,忘记覆盖子节点属性。实例使用默认值(通常是 null),导致静默错误。
# level.tscn
[node name="KeyPickup" parent="." instance=ExtResource("6_pickup")]
# 糟糕!PickupInteraction.item_resource 是 null - 拾取将无法工作!
解决方案: 始终使用 index 语法配置实例化场景的属性:
[node name="KeyPickup" parent="." instance=ExtResource("6_pickup")]
[node name="PickupInteraction" parent="KeyPickup" index="0"]
item_resource = ExtResource("7_key")
检测方法:
references/file-formats.md 中的“实例属性覆盖”部分以获取详细信息预防措施: 实例化任何带有可配置子节点(PickupInteraction、DoorInteraction 等)的场景后,始终验证关键属性是否已被覆盖。
问题: 在 CPUParticles3D 上设置 color_ramp,但粒子仍显示为白色或不显示渐变颜色。
[node name="CPUParticles3D" type="CPUParticles3D" parent="."]
mesh = SubResource("SphereMesh_1")
color_ramp = SubResource("Gradient_1") # 设置了渐变但不起作用!
根本原因: 网格需要一个材质,且 vertex_color_use_as_albedo = true,才能将粒子颜色应用到网格表面。
解决方案: 向网格添加一个启用了顶点颜色的 StandardMaterial3D:
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
vertex_color_use_as_albedo = true
[sub_resource type="SphereMesh" id="SphereMesh_1"]
material = SubResource("StandardMaterial3D_1")
radius = 0.12
height = 0.24
[node name="CPUParticles3D" type="CPUParticles3D" parent="."]
mesh = SubResource("SphereMesh_1")
color_ramp = SubResource("Gradient_1") # 现在可以工作了!
预防措施: 创建带有 color 或 color_ramp 的 CPUParticles3D 时,始终向网格添加一个 vertex_color_use_as_albedo = true 的材质。
遇到问题时,查阅参考文档:
references/common-pitfalls.md - 常见的 Godot 陷阱和解决方案:
references/godot4-physics-api.md - 物理 API 快速参考:
PhysicsRayQueryParameters3D)在以下情况下加载这些文档:
python3 scripts/validate_tres.py path/to/file.tres
python3 scripts/validate_tscn.py path/to/file.tscn
不要从零开始编写组件 - 改编模板:
cp assets/templates/component_template.gd src/my_component.gd
不确定语法时,加载参考文档:
Read references/file-formats.md
优先使用信号而非直接方法调用:
# ✅ 良好 - 松耦合
signal item_picked_up(item)
item_picked_up.emit(item)
# ❌ 避免 - 紧耦合
get_parent().get_parent().add_to_inventory(item)
每次更改后:
使配置可见且可编辑:
@export_group("Movement")
@export var speed: float = 5.0
@export var jump_force: float = 10.0
@export_group("Combat")
@export var damage: int = 10
godot 命令行工具可用于运行游戏和执行各种操作,而无需打开编辑器。
运行当前项目:
godot --path . --headless
运行特定场景:
godot --path . --scene scenes/main_menu.tscn
使用调试标志运行:
# 显示碰撞形状
godot --path . --debug-collisions
# 显示导航调试视觉效果
godot --path . --debug-navigation
# 显示路径线
godot --path . --debug-paths
仅检查 GDScript 语法而不运行:
godot --path . --check-only --script path/to/script.gd
运行无头测试(用于自动化测试):
godot --path . --headless --quit --script path/to/test_script.gd
导入资源而不打开编辑器:
godot --path . --import --headless --quit
导出项目:
# 导出发布版本
godot --path . --export-release "Preset Name" builds/game.exe
# 导出调试版本
godot --path . --export-debug "Preset Name" builds/game_debug.exe
工作流程:快速测试运行
# 运行项目并在测试后退出
godot --path . --quit-after 300 # 运行 300 帧后退出
工作流程:自动化资源导入
# 导入所有资源并退出(在 CI/CD 中有用)
godot --path . --import --headless --quit
工作流程:脚本验证
# 提交前验证 GDScript 文件
godot --path . --check-only --script src/player/player.gd
工作流程:无头服务器
# 作为专用服务器运行(无渲染)
godot --path . --headless --scene scenes/multiplayer_server.tscn
--path . 当从项目目录运行时,以确保 Godot 能找到 project.godot--headless 用于 CI/CD 和自动化测试(无窗口,无渲染)--quit 或 --quit-after N 在任务完成后自动退出--check-only 和 --script 快速验证 GDScript 语法--debug-collisions, --debug-navigation)在开发期间可视化系统#!/bin/bash
# 提交前验证所有更改的 .gd 文件
for file in $(git diff --cached --name-only --diff-filter=ACM | grep '\.gd$'); do
if ! godot --path . --check-only --script "$file" --headless --quit; then
echo "GDScript validation failed for $file"
exit 1
fi
done
编写游戏逻辑? → 使用 .gd 文件
存储数据(物品属性、法术配置)? → 使用 .tres 文件
创建场景结构? → 使用 .tscn 文件(复杂结构优先使用 Godot 编辑器)
在 .gd 文件中: 完整的 GDScript - var, func, preload(), 等。 ✅
在 .tres/.tscn 文件中:
preload() ❌ → 使用 ExtResource("id") ✅var, const, func ❌ → 仅使用属性值 ✅[1, 2, 3] ❌ → Array[int]([1, 2, 3]) ✅validate_tres.py - 用于资源文件:
validate_tscn.py - 用于场景文件:
file-formats.md - 当:
architecture-patterns.md - 当:
通过以下方式有效地处理 Godot 项目:
关键见解:当你尊重 GDScript 和资源序列化格式之间的语法差异时,Godot 的基于文本的文件对 LLM 是友好的。
每周安装次数
54
仓库
GitHub 星标数
38
首次出现时间
2026年1月22日
安全审计
已安装于
gemini-cli42
codex41
claude-code38
opencode37
github-copilot33
cursor32
Specialized guidance for developing games and applications with Godot Engine, with emphasis on effective collaboration between LLM coding assistants and Godot's unique file structure.
Godot projects use a mix of GDScript code files (.gd) and text-based resource files (.tscn for scenes, .tres for resources). While GDScript is straightforward, the resource files have strict formatting requirements that differ significantly from GDScript syntax. This skill provides file format expertise, proven architecture patterns, validation tools, code templates, and debugging workflows to enable effective development of Godot projects.
Invoke this skill when:
GDScript (.gd) - Full Programming Language:
extends Node
class_name MyClass
var speed: float = 5.0
const MAX_HEALTH = 100
func _ready():
print("Ready")
Scene Files (.tscn) - Strict Serialization Format:
[ext_resource type="Script" path="res://script.gd" id="1"]
[node name="Player" type="CharacterBody3D"]
script = ExtResource("1") # NOT preload()!
Resource Files (.tres) - NO GDScript Syntax:
[ext_resource type="Script" path="res://item.gd" id="1"]
[resource]
script = ExtResource("1") # NOT preload()!
item_name = "Sword" # NOT var item_name = "Sword"!
NEVER use in .tres/.tscn files:
preload() - Use ExtResource("id") insteadvar, const, func - These are GDScript keywordsArray[Type]([...]) syntaxALWAYS use in .tres/.tscn files:
ExtResource("id") for external resourcesSubResource("id") for inline resourcesArray[Resource]([...])Keep logic in .gd files, data in .tres files:
src/
spells/
spell_resource.gd # Class definition + logic
spell_effect.gd # Effect logic
resources/
spells/
fireball.tres # Data only, references scripts
ice_spike.tres # Data only
This makes LLM editing much safer and clearer.
Break functionality into small, focused components:
Player (CharacterBody3D)
├─ HealthAttribute (Node) # Component
├─ ManaAttribute (Node) # Component
├─ Inventory (Node) # Component
└─ StateMachine (Node) # Component
├─ IdleState (Node)
├─ MoveState (Node)
└─ AttackState (Node)
Benefits:
Use signals for loose coupling:
# Component emits signals
signal health_changed(current, max)
signal death()
# Parent connects to signals
func _ready():
$HealthAttribute.health_changed.connect(_on_health_changed)
$HealthAttribute.death.connect(_on_death)
Benefits:
Validate .tres and .tscn files before testing in Godot to catch syntax errors early.
Validate .tres file:
python3 scripts/validate_tres.py resources/spells/fireball.tres
Validate .tscn file:
python3 scripts/validate_tscn.py scenes/player/player.tscn
Use these scripts when:
Load reference files when needed for detailed information:
references/file-formats.md - Deep dive into .gd, .tscn, .tres syntax:
references/architecture-patterns.md - Proven architectural patterns:
Read these references when:
Use templates as starting points for common patterns. Templates are in assets/templates/:
component_template.gd - Base component with signals, exports, activation:
# Copy and customize for new components
cp assets/templates/component_template.gd src/components/my_component.gd
attribute_template.gd - Numeric attribute (health, mana, stamina):
# Use for any numeric attribute with min/max
cp assets/templates/attribute_template.gd src/attributes/stamina_attribute.gd
interaction_template.gd - Interaction component base class:
# Extend for custom interactions (pickup, door, switch, etc.)
cp assets/templates/interaction_template.gd src/interactions/lever_interaction.gd
spell_resource.tres - Example spell with effects:
# Use as reference for creating new spell data
cat assets/templates/spell_resource.tres
item_resource.tres - Example item resource:
# Use as reference for creating new item data
cat assets/templates/item_resource.tres
Example: Adding a health system to enemies.
Steps:
Read architecture patterns reference:
# Check for similar patterns
Read references/architecture-patterns.md
# Look for "Attribute System" section
Create base class using template:
cp assets/templates/attribute_template.gd src/attributes/attribute.gd
# Customize the base class
Create specialized subclass:
# Create health_attribute.gd extending attribute.gd
# Add health-specific signals (damage_taken, death)
Add to scene via .tscn edit:
[ext_resource type="Script" path="res://src/attributes/health_attribute.gd" id="4_health"]
[node name="HealthAttribute" type="Node" parent="Enemy"]
script = ExtResource("4_health")
value_max = 50.0
value_start = 50.0
Test immediately in Godot editor
If issues, validate the scene file:
Example: Creating a new spell.
Steps:
Reference the template:
cat assets/templates/spell_resource.tres
Create new .tres file with proper structure:
[gd_resource type="Resource" script_class="SpellResource" load_steps=3 format=3]
[ext_resource type="Script" path="res://src/spells/spell_resource.gd" id="1"]
[ext_resource type="Script" path="res://src/spells/spell_effect.gd" id="2"]
[sub_resource type="Resource" id="Effect_1"]
script = ExtResource("2")
effect_type = 0
magnitude_min = 15.0
magnitude_max = 25.0
[resource]
script = ExtResource("1")
spell_name = "Fireball"
spell_id = "fireball"
mana_cost = 25.0
effects = Array[ExtResource("2")]([SubResource("Effect_1")])
Validate before testing:
python3 scripts/validate_tres.py resources/spells/fireball.tres
Fix any errors reported by validator
Test in Godot editor
When user reports "resource failed to load" or similar errors.
Steps:
Read the file reported in error:
# Check file syntax
Read resources/spells/problem_spell.tres
Run validation script:
python3 scripts/validate_tres.py resources/spells/problem_spell.tres
Check for common mistakes:
preload() instead of ExtResource()var, const, func keywordsRead file format reference if needed:
When implementing a known pattern (interaction system, state machine, etc.).
Steps:
Read the relevant pattern:
Read references/architecture-patterns.md
# Find the specific pattern (e.g., "Component-Based Interaction System")
Copy relevant template:
cp assets/templates/interaction_template.gd src/interactions/door_interaction.gd
Customize the template:
_perform_interaction()Create scene structure following pattern:
[node name="Door" type="StaticBody3D"]
script = ExtResource("base_interactable.gd")
[node name="DoorInteraction" type="Node" parent="."]
script = ExtResource("door_interaction.gd")
interaction_text = "Open Door"
Test incrementally
Use GUT (Godot Unit Testing) for testing pure logic — any RefCounted or Resource class that doesn't depend on the scene tree is a good candidate. Card systems, scoring, state machines, map generators, challenge logic, etc.
addons/gut/ in your project.gutconfig.json at project root:{
"dirs": ["res://test/unit"],
"prefix": "test_",
"suffix": ".gd",
"log_level": 1
}
Tests live in test/unit/, files prefixed test_, extending GutTest:
extends GutTest
func test_score_calculation() -> void:
var scoring := Scoring.new()
assert_eq(scoring.calculate(3, 0), 100, "Base score for 3 moves")
assert_gt(scoring.calculate(2, 0), scoring.calculate(3, 0), "Fewer moves = higher score")
func test_deck_shuffle() -> void:
var rng := RandomNumberGenerator.new()
rng.seed = 42
var deck := CardSystem.create_shuffled_deck(rng)
assert_eq(deck.size(), 52, "Full deck")
Key conventions:
test__ prefix (not discovered as tests)before_each() / after_each() for setup/teardownassert_eq, assert_ne, assert_true, assert_false, assert_gt, assert_lt, assert_null, # Run all tests (returns exit code 0 on pass, 1 on fail)
godot -d -s --path "$PWD" addons/gut/gut_cmdln.gd -gexit
# Run a specific test file
godot -d -s --path "$PWD" addons/gut/gut_cmdln.gd -gtest=res://test/unit/test_scoring.gd -gexit
# Run tests matching a pattern
godot -d -s --path "$PWD" addons/gut/gut_cmdln.gd -gdir=res://test/unit -gselect=weekly -gexit
Prefer testing pure logic classes that extend RefCounted or Resource:
Avoid testing scene-tree-dependent code in unit tests (rendering, UI, input handling).
Problem:
# ❌ WRONG
script = preload("res://script.gd")
var items = [1, 2, 3]
Solution:
# ✅ CORRECT
[ext_resource type="Script" path="res://script.gd" id="1"]
script = ExtResource("1")
items = Array[int]([1, 2, 3])
Prevention: Run validation script before testing.
Problem:
[resource]
script = ExtResource("1_script") # Not declared!
Solution:
[ext_resource type="Script" path="res://script.gd" id="1_script"]
[resource]
script = ExtResource("1_script")
Detection: Validation script will catch this.
Problem: Modifying instanced scene children can break when editor re-saves.
Solution:
Problem:
effects = [SubResource("Effect_1")] # Missing type
Solution:
effects = Array[Resource]([SubResource("Effect_1")])
Prevention: Validation script warns about this.
Problem: When instancing a scene, forgetting to override child node properties. The instance uses default values (often null), causing silent bugs.
# level.tscn
[node name="KeyPickup" parent="." instance=ExtResource("6_pickup")]
# Oops! PickupInteraction.item_resource is null - pickup won't work!
Solution: Always configure instanced scene properties using the index syntax:
[node name="KeyPickup" parent="." instance=ExtResource("6_pickup")]
[node name="PickupInteraction" parent="KeyPickup" index="0"]
item_resource = ExtResource("7_key")
Detection:
references/file-formats.md "Instance Property Overrides" section for detailsPrevention: After instancing any scene with configurable children (PickupInteraction, DoorInteraction, etc.), always verify critical properties are overridden.
Problem: Setting color_ramp on CPUParticles3D, but particles still appear white or don't show the gradient colors.
[node name="CPUParticles3D" type="CPUParticles3D" parent="."]
mesh = SubResource("SphereMesh_1")
color_ramp = SubResource("Gradient_1") # Gradient is set but doesn't work!
Root Cause: The mesh needs a material with vertex_color_use_as_albedo = true to apply particle colors to the mesh surface.
Solution: Add a StandardMaterial3D to the mesh with vertex color enabled:
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
vertex_color_use_as_albedo = true
[sub_resource type="SphereMesh" id="SphereMesh_1"]
material = SubResource("StandardMaterial3D_1")
radius = 0.12
height = 0.24
[node name="CPUParticles3D" type="CPUParticles3D" parent="."]
mesh = SubResource("SphereMesh_1")
color_ramp = SubResource("Gradient_1") # Now works!
Prevention: When creating CPUParticles3D with color or color_ramp, always add a material with vertex_color_use_as_albedo = true to the mesh.
When encountering issues, consult the reference documentation:
references/common-pitfalls.md - Common Godot gotchas and solutions:
references/godot4-physics-api.md - Physics API quick reference:
PhysicsRayQueryParameters3D)Load these when:
python3 scripts/validate_tres.py path/to/file.tres
python3 scripts/validate_tscn.py path/to/file.tscn
Don't write components from scratch - adapt templates:
cp assets/templates/component_template.gd src/my_component.gd
When unsure about syntax, load the reference:
Read references/file-formats.md
Prefer signals over direct method calls:
# ✅ Good - Loose coupling
signal item_picked_up(item)
item_picked_up.emit(item)
# ❌ Avoid - Tight coupling
get_parent().get_parent().add_to_inventory(item)
After each change:
Make configuration visible and editable:
@export_group("Movement")
@export var speed: float = 5.0
@export var jump_force: float = 10.0
@export_group("Combat")
@export var damage: int = 10
The godot command-line tool is available for running the game and performing various operations without opening the editor.
Run the current project:
godot --path . --headless
Run a specific scene:
godot --path . --scene scenes/main_menu.tscn
Run with debug flags:
# Show collision shapes
godot --path . --debug-collisions
# Show navigation debug visuals
godot --path . --debug-navigation
# Show path lines
godot --path . --debug-paths
Check GDScript syntax without running:
godot --path . --check-only --script path/to/script.gd
Run headless tests (for automated testing):
godot --path . --headless --quit --script path/to/test_script.gd
Import resources without opening editor:
godot --path . --import --headless --quit
Export project:
# Export release build
godot --path . --export-release "Preset Name" builds/game.exe
# Export debug build
godot --path . --export-debug "Preset Name" builds/game_debug.exe
Workflow: Quick Test Run
# Run the project and quit after testing
godot --path . --quit-after 300 # Runs for 300 frames then quits
Workflow: Automated Resource Import
# Import all resources and exit (useful in CI/CD)
godot --path . --import --headless --quit
Workflow: Script Validation
# Validate a GDScript file before committing
godot --path . --check-only --script src/player/player.gd
Workflow: Headless Server
# Run as dedicated server (no rendering)
godot --path . --headless --scene scenes/multiplayer_server.tscn
--path . when running from project directory to ensure Godot finds project.godot--headless for CI/CD and automated testing (no window, no rendering)--quit or --quit-after N to exit automatically after task completion--check-only with --script to validate GDScript syntax quickly--debug-collisions, --debug-navigation) to visualize systems during development#!/bin/bash
# Validate all changed .gd files before committing
for file in $(git diff --cached --name-only --diff-filter=ACM | grep '\.gd$'); do
if ! godot --path . --check-only --script "$file" --headless --quit; then
echo "GDScript validation failed for $file"
exit 1
fi
done
Writing game logic? → Use .gd file
Storing data (item stats, spell configs)? → Use .tres file
Creating scene structure? → Use .tscn file (prefer Godot editor for complex structures)
In .gd files: Full GDScript - var, func, preload(), etc. ✅
In .tres/.tscn files:
preload() ❌ → Use ExtResource("id") ✅var, const, func ❌ → Just property values ✅[1, 2, 3] ❌ → Array[int]([1, 2, 3]) ✅validate_tres.py - For resource files:
validate_tscn.py - For scene files:
file-formats.md - When:
architecture-patterns.md - When:
Work with Godot projects effectively by:
The key insight: Godot's text-based files are LLM-friendly when you respect the syntax differences between GDScript and resource serialization formats.
Weekly Installs
54
Repository
GitHub Stars
38
First Seen
Jan 22, 2026
Security Audits
Gen Agent Trust HubPassSocketFailSnykPass
Installed on
gemini-cli42
codex41
claude-code38
opencode37
github-copilot33
cursor32
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
123,700 周安装
ARM 模板转 Pulumi 代码迁移指南:完整工作流程与成功要求
1,500 周安装
Claude插件文档自动更新技能:Jinja2模板驱动,同步智能体、技能、插件文档
1,500 周安装
Railway 服务管理:检查状态、更新属性与高级创建指南
1,600 周安装
资深 Next.js 14+ 全栈开发专家 | App Router、服务器组件、SEO 与性能优化
1,700 周安装
App Store Connect ID 解析器 - 快速映射应用、构建、版本等ID,提升开发效率
1,600 周安装
代币集成分析器 - 智能合约安全审计工具,检测ERC20/ERC721漏洞与奇怪代币风险
1,600 周安装
python3 scripts/validate_tscn.py scenes/enemies/base_enemy.tscn
Read references/file-formats.md
# Focus on "Resource Files (.tres)" section
# Check "Common Mistakes Reference"
Fix errors and re-validate
assert_not_null