godot-composition-apps by thedivergentai/gd-agentic-skills
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-composition-apps此技能在 Godot 的节点系统中强制执行单一职责原则。无论是构建 RPG 还是 SaaS 仪表板,规则始终如一:一个脚本 = 一项工作。
在编写脚本之前,请自问:"如果我把这个脚本附加到一块真正的石头上,它还能正常工作吗?"
AuthComponent 允许石头登录。(与上下文无关)LoginForm 脚本试图获取石头没有的文本字段。(耦合)停止通过扩展基类来添加功能。将根节点视为一个空的背包。
SubmitButton 继承 AnimatedButton 继承 BaseButton。广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
SubmitButtonAnimationComponentNetworkRequestComponent严格执行此通信流程以防止"意大利面条式代码":
| 方向 | 源 → 目标 | 方法 | 原因 |
|---|---|---|---|
| 向下 | 协调器 → 组件 | 函数调用 | 管理者拥有工作者;知道它们存在。 |
| 向上 | 组件 → 协调器 | 信号 | 工作者是盲目的;它们只是大喊"我完成了!" |
| 横向 | 组件 A ↔ 组件 B | 禁止 | 兄弟组件绝不能直接对话。 |
横向解决方案: 组件 A 向协调器发送信号;协调器调用组件 B 上的函数。
根节点脚本(例如,LoginScreen.gd、UserProfile.gd)现在是一个协调器。
| 概念 | 应用/用户界面示例 |
|---|---|
| 协调器 | UserProfile.gd |
| 组件 1 | AuthValidator(逻辑) |
| 组件 2 | FormListener(输入) |
| 组件 3 | ThemeManager(视觉) |
全局定义组件。切勿为核心架构使用动态类型。
# auth_component.gd
class_name AuthComponent extends Node
切勿使用 get_node("Path/To/Child")。路径是脆弱的。始终使用类型化导出并在检查器中拖放。
# 协调器脚本
@export var auth: AuthComponent
@export var form_ui: Control
如果协调器在场景内进行内部引用是绝对必要的,请使用 % 唯一名称功能。
@onready var submit_btn = %SubmitButton
组件应处理提供给它们的数据。
NetworkComponent 自己查找用户名文本字段。NetworkComponent 有一个函数 login(username, password)。协调器将文本字段数据传递给该函数。@export 注入或通过函数调用传递。ComponentA 绝不能调用 ComponentB 上的函数。高耦合使得重构不可能。始终向上发送信号到协调器。get_node("Child/Subchild/Node") 在你移动单个节点时就会失效。使用 @export 和检查器。_on_signal 方法,这些方法将任务委托给其他组件。Context 资源或全局自动加载。HealthComponent 要求其父节点是 CharacterBody2D,它就未通过"石头测试"。CombatComponent 绝不应该调用 AnimationPlayer.play()。它应该发射 attack_performed 信号,由 Syncer 或 Orchestrator 处理视觉响应。clipboard_copier.gdclass_name ClipboardCopier extends Node
signal copy_success
signal copy_failed(reason)
func copy_text(text: String) -> void:
if text.is_empty():
copy_failed.emit("Text empty")
return
DisplayServer.clipboard_set(text)
copy_success.emit()
share_menu.gdextends Control
# 通过检查器连接
@export var copier: ClipboardCopier
@export var link_label: Label
func _ready():
# 向下通信
%CopyButton.pressed.connect(_on_copy_button_pressed)
# 向上通信监听
copier.copy_success.connect(_on_copy_success)
func _on_copy_button_pressed():
# 协调器委托
copier.copy_text(link_label.text)
func _on_copy_success():
# 协调器根据信号管理用户界面状态
%ToastNotification.show("Link Copied!")
信号委托和组件连接的中心枢纽。无逻辑的管理器。
具有类型安全信号和自动分组注册的基础组件。
与上下文无关的生命值/伤害逻辑,适用于玩家、敌人或木桶。
基于区域的碰撞接口,将物理命中桥接到 HealthComponent。
动态能力管理器,通过统一接口执行子'Ability'节点。
后期绑定配置加载器,用于通过资源(.tres)热交换行为。
专家级注入模式,用于在不使用 get_node 的情况下将引用传递给动态组件。
用于模块化节点持久化的自动保存/加载注册。
解耦代理,将游戏逻辑状态同步到视觉动画/视觉效果。
架构验证器,确保组件真正解耦。
每周安装数
73
代码仓库
GitHub 星标数
68
首次出现
2026年2月9日
安全审计
安装于
gemini-cli70
codex69
opencode69
kimi-cli67
github-copilot67
amp67
This skill enforces the Single Responsibility Principle within Godot's Node system. Whether building an RPG or a SaaS Dashboard, the rule remains: One Script = One Job.
Before writing a script, ask: "If I attached this script to a literal rock, would it still function?"
AuthComponent on a rock allows the rock to log in. (Context Agnostic)LoginForm script on a rock tries to grab text fields the rock doesn't have. (Coupled)Stop extending base classes to add functionality. Treat the Root Node as an empty Backpack.
SubmitButton extends AnimatedButton extends BaseButton.SubmitButton (Root) HAS-A AnimationComponent and HAS-A NetworkRequestComponent.Strictly enforce this communication flow to prevent "Spaghetti Code":
| Direction | Source → Target | Method | Reason |
|---|---|---|---|
| Downward | Orchestrator → Component | Function Call | Manager owns the workers; knows they exist. |
| Upward | Component → Orchestrator | Signals | Workers are blind; they just yell "I'm done!" |
| Sideways | Component A ↔ Component B | FORBIDDEN | Siblings must never talk directly. |
The Sideways Fix: Component A signals the Orchestrator; Orchestrator calls function on Component B.
The Root Node script (e.g., LoginScreen.gd, UserProfile.gd) is now an Orchestrator.
| Concept | App/UI Example |
|---|---|
| Orchestrator | UserProfile.gd |
| Component 1 | AuthValidator (Logic) |
| Component 2 | FormListener (Input) |
| Component 3 | ThemeManager (Visual) |
Define components globally. Never use dynamic typing for core architecture.
# auth_component.gd
class_name AuthComponent extends Node
NEVER use get_node("Path/To/Child"). Paths are brittle. ALWAYS use Typed Exports and drag-and-drop in the Inspector.
# Orchestrator script
@export var auth: AuthComponent
@export var form_ui: Control
If internal referencing within a scene is strictly necessary for the Orchestrator, use the % Unique Name feature.
@onready var submit_btn = %SubmitButton
Components should process the data given to them.
NetworkComponent finds the username text field itself.NetworkComponent has a function login(username, password). The Orchestrator passes the text field data into that function.@export or passed into a function call.ComponentA must never call functions on ComponentB. High-coupling makes refactoring impossible. Always signal up to the Orchestrator.get_node("Child/Subchild/Node") breaks when you move a single node. Use @export and the Inspector._on_signal methods that delegate to other components.Context Resource or the Global Autoload for cross-scene state.HealthComponent requires its parent to be a CharacterBody2D, it fails the "Rock Test."CombatComponent should never call AnimationPlayer.play(). It emits attack_performed, and a Syncer or Orchestrator handles the visual response.clipboard_copier.gdclass_name ClipboardCopier extends Node
signal copy_success
signal copy_failed(reason)
func copy_text(text: String) -> void:
if text.is_empty():
copy_failed.emit("Text empty")
return
DisplayServer.clipboard_set(text)
copy_success.emit()
share_menu.gdextends Control
# Wired via Inspector
@export var copier: ClipboardCopier
@export var link_label: Label
func _ready():
# Downward communication
%CopyButton.pressed.connect(_on_copy_button_pressed)
# Upward communication listening
copier.copy_success.connect(_on_copy_success)
func _on_copy_button_pressed():
# Orchestrator delegation
copier.copy_text(link_label.text)
func _on_copy_success():
# Orchestrator managing UI state based on signal
%ToastNotification.show("Link Copied!")
Central hub for signal delegation and component wiring. Logic-free manager.
Foundational component with type-safe signals and auto-group registration.
Context-agnostic health/damage logic that works on players, enemies, or barrels.
Area-based collision interface that bridges physical hits to the HealthComponent.
Dynamic ability manager that executes child 'Ability' nodes via unified interfaces.
Late-binding configuration loader for hot-swapping behavior via Resources (.tres).
Expert injection pattern for passing refs to dynamic components without get_node.
Automated save/load registration for modular node persistence.
Decoupling agent that syncs gameplay logic state to visual animations/VFX.
Architectural validator to ensure components are truly decoupled.
Weekly Installs
73
Repository
GitHub Stars
68
First Seen
Feb 9, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
gemini-cli70
codex69
opencode69
kimi-cli67
github-copilot67
amp67
Android 整洁架构指南:模块化设计、依赖注入与数据层实现
1,400 周安装
平台工程师指南:构建内部开发者平台与黄金路径模板,优化开发者体验
102 周安装
React 19、Next.js 16、Vue 3.5 前端开发专家 - 现代Web应用与组件架构模式
100 周安装
CLAUDE.md 架构师技能:为软件项目生成和优化 AI 项目指令文件,提升 Claude 代码效率
100 周安装
2025年API设计模式指南:REST、GraphQL、tRPC决策与最佳实践
99 周安装
供应商管理插件:AI驱动的供应商评估、风险分析与绩效监控工具
99 周安装
Wagmi 3.x 以太坊 React Hooks 使用指南 - 配置、连接器与核心Hooks详解
100 周安装