重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
godot-quest-system by thedivergentai/gd-agentic-skills
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-quest-system基于资源的数据、信号驱动的更新以及 AutoLoad 的协调,共同定义了可扩展的任务架构。
使用 Resource 进行数据驱动的任务定义,实现模块化目标和分支奖励。
集中式的 AutoLoad 协调器,用于跟踪活动任务并广播状态更新。
解耦的触发器逻辑,将游戏事件(敌人死亡)与任务系统连接起来。
响应式的 VBox UI,根据管理器信号动态添加和移除目标标签。
扩展的任务逻辑,用于处理多种结果和玩家驱动的叙事路径。
用于将 NPC 与任务系统集成的钩子,允许条件对话分支。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
用于序列化任务 ID 和进度计数以实现持久化保存状态的专家模式。
具有自动失败条件和 UI 信号的限时挑战模板。
用于秘密成就或不可见任务进度的后台目标跟踪器。
使用 tr() 键而非硬编码字符串来支持多语言任务文本的策略。
update_objective("kill_slimes") 中的拼写错误将导致静默失败。请使用 StringNames 或中央 ID 注册表 [21]。_process() 中轮询任务完成状态 — 每秒检查 60 次目标状态是浪费的。请使用信号驱动的方法(例如 on_enemy_died)[23]。all() 时不进行空值/类型检查 — 尝试在空的目标条目上检查完成状态将导致整个系统崩溃 [25]。EventBus 或 QuestTrigger 节点来将遭遇事件连接到 QuestManager。Quest 资源提供的内容。请将计算公式保留在 QuestManager 中。InventoryManager 或 EconomyManager 以实现解耦。# quest.gd
class_name Quest
extends Resource
signal progress_updated(objective_id: String, progress: int)signal completed
@export var quest_id: String
@export var quest_name: String
@export_multiline var description: String
@export var objectives: Array[QuestObjective] = []
@export var rewards: Array[QuestReward] = []
@export var required_level: int = 1
func is_complete() -> bool:
return objectives.all(func(obj): return obj.is_complete())
func check_completion() -> void:
if is_complete():
completed.emit()
# quest_objective.gd
class_name QuestObjective
extends Resource
enum Type { KILL, COLLECT, TALK, REACH }
@export var objective_id: String
@export var type: Type
@export var target: String # 敌人名称、物品 ID、NPC 名称、地点
@export var required_amount: int = 1
@export var current_amount: int = 0
func progress(amount: int = 1) -> void:
current_amount += amount
current_amount = mini(current_amount, required_amount)
func is_complete() -> bool:
return current_amount >= required_amount
# quest_manager.gd (AutoLoad)
extends Node
signal quest_accepted(quest: Quest)
signal quest_completed(quest: Quest)
signal objective_updated(quest: Quest, objective: QuestObjective)
var active_quests: Array[Quest] = []
var completed_quests: Array[String] = []
func accept_quest(quest: Quest) -> void:
if quest.quest_id in completed_quests:
return
active_quests.append(quest)
quest.completed.connect(func(): _on_quest_completed(quest))
quest_accepted.emit(quest)
func _on_quest_completed(quest: Quest) -> void:
active_quests.erase(quest)
completed_quests.append(quest.quest_id)
# 发放奖励
for reward in quest.rewards:
reward.grant()
quest_completed.emit(quest)
func update_objective(quest_id: String, objective_id: String, amount: int = 1) -> void:
for quest in active_quests:
if quest.quest_id == quest_id:
for obj in quest.objectives:
if obj.objective_id == objective_id:
obj.progress(amount)
objective_updated.emit(quest, obj)
quest.check_completion()
return
func get_active_quest(quest_id: String) -> Quest:
for quest in active_quests:
if quest.quest_id == quest_id:
return quest
return null
# 示例:击杀任务集成
# enemy.gd
func _on_died() -> void:
QuestManager.update_objective("kill_bandits", "kill_bandit", 1)
# 示例:收集任务集成
# item_pickup.gd
func _on_collected() -> void:
QuestManager.update_objective("gather_herbs", "collect_herb", 1)
# 示例:对话任务集成
# npc.gd
func interact() -> void:
DialogueManager.start_dialogue(dialogue_id)
QuestManager.update_objective("find_elder", "talk_to_elder", 1)
# quest_ui.gd
extends Control
@onready var quest_list := $QuestList
func _ready() -> void:
QuestManager.quest_accepted.connect(_on_quest_accepted)
QuestManager.objective_updated.connect(_on_objective_updated)
refresh_ui()
func refresh_ui() -> void:
for child in quest_list.get_children():
child.queue_free()
for quest in QuestManager.active_quests:
var quest_entry := create_quest_entry(quest)
quest_list.add_child(quest_entry)
func create_quest_entry(quest: Quest) -> Control:
var entry := VBoxContainer.new()
var title := Label.new()
title.text = quest.quest_name
entry.add_child(title)
for obj in quest.objectives:
var obj_label := Label.new()
obj_label.text = "%s: %d/%d" % [obj.target, obj.current_amount, obj.required_amount]
entry.add_child(obj_label)
return entry
godot-dialogue-system, godot-save-load-systems每周安装量
67
仓库
GitHub 星标数
59
首次出现
2026年2月10日
安全审计
安装于
opencode65
codex64
gemini-cli64
kimi-cli62
github-copilot62
amp62
Resource-based data, signal-driven updates, and AutoLoad coordination define scalable quest architectures.
Data-driven quest definition using Resources for modular objectives and branching rewards.
Centralized AutoLoad orchestrator for tracking active quests and broadcasting status updates.
Decoupled trigger logic that bridges game events (enemies dying) to the Quest System.
Reactive VBox UI that dynamically adds and removes objective labels based on manager signals.
Extended quest logic for handling multiple outcomes and player-driven narrative paths.
Hook for integrating NPCs with the quest system, allowing for conditional dialogue branches.
Expert patterns for serializing quest IDs and progress counts for persistent save states.
Template for time-limited challenges with automatic failure conditions and UI signals.
Background objective tracker for secret achievements or non-visible quest progress.
Strategy for supporting multi-language quest text using tr() keys instead of hardcoded strings.
update_objective("kill_slimes") will fail silently. Use StringNames or a central ID registry [21]._process() — Checking objectives 60 times a second is wasteful. Use a signal-driven approach (e.g. on_enemy_died) [23].all() on objective arrays without null/type checks — Attempting to check completion on a null objective entry will crash the entire system [25].EventBus or QuestTrigger node to bridge the encounter to the QuestManager.# quest.gd
class_name Quest
extends Resource
signal progress_updated(objective_id: String, progress: int)signal completed
@export var quest_id: String
@export var quest_name: String
@export_multiline var description: String
@export var objectives: Array[QuestObjective] = []
@export var rewards: Array[QuestReward] = []
@export var required_level: int = 1
func is_complete() -> bool:
return objectives.all(func(obj): return obj.is_complete())
func check_completion() -> void:
if is_complete():
completed.emit()
# quest_objective.gd
class_name QuestObjective
extends Resource
enum Type { KILL, COLLECT, TALK, REACH }
@export var objective_id: String
@export var type: Type
@export var target: String # Enemy name, item ID, NPC name, location
@export var required_amount: int = 1
@export var current_amount: int = 0
func progress(amount: int = 1) -> void:
current_amount += amount
current_amount = mini(current_amount, required_amount)
func is_complete() -> bool:
return current_amount >= required_amount
# quest_manager.gd (AutoLoad)
extends Node
signal quest_accepted(quest: Quest)
signal quest_completed(quest: Quest)
signal objective_updated(quest: Quest, objective: QuestObjective)
var active_quests: Array[Quest] = []
var completed_quests: Array[String] = []
func accept_quest(quest: Quest) -> void:
if quest.quest_id in completed_quests:
return
active_quests.append(quest)
quest.completed.connect(func(): _on_quest_completed(quest))
quest_accepted.emit(quest)
func _on_quest_completed(quest: Quest) -> void:
active_quests.erase(quest)
completed_quests.append(quest.quest_id)
# Give rewards
for reward in quest.rewards:
reward.grant()
quest_completed.emit(quest)
func update_objective(quest_id: String, objective_id: String, amount: int = 1) -> void:
for quest in active_quests:
if quest.quest_id == quest_id:
for obj in quest.objectives:
if obj.objective_id == objective_id:
obj.progress(amount)
objective_updated.emit(quest, obj)
quest.check_completion()
return
func get_active_quest(quest_id: String) -> Quest:
for quest in active_quests:
if quest.quest_id == quest_id:
return quest
return null
# Example: Kill quest integration
# enemy.gd
func _on_died() -> void:
QuestManager.update_objective("kill_bandits", "kill_bandit", 1)
# Example: Collection integration
# item_pickup.gd
func _on_collected() -> void:
QuestManager.update_objective("gather_herbs", "collect_herb", 1)
# Example: Talk integration
# npc.gd
func interact() -> void:
DialogueManager.start_dialogue(dialogue_id)
QuestManager.update_objective("find_elder", "talk_to_elder", 1)
# quest_ui.gd
extends Control
@onready var quest_list := $QuestList
func _ready() -> void:
QuestManager.quest_accepted.connect(_on_quest_accepted)
QuestManager.objective_updated.connect(_on_objective_updated)
refresh_ui()
func refresh_ui() -> void:
for child in quest_list.get_children():
child.queue_free()
for quest in QuestManager.active_quests:
var quest_entry := create_quest_entry(quest)
quest_list.add_child(quest_entry)
func create_quest_entry(quest: Quest) -> Control:
var entry := VBoxContainer.new()
var title := Label.new()
title.text = quest.quest_name
entry.add_child(title)
for obj in quest.objectives:
var obj_label := Label.new()
obj_label.text = "%s: %d/%d" % [obj.target, obj.current_amount, obj.required_amount]
entry.add_child(obj_label)
return entry
godot-dialogue-system, godot-save-load-systemsWeekly Installs
67
Repository
GitHub Stars
59
First Seen
Feb 10, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode65
codex64
gemini-cli64
kimi-cli62
github-copilot62
amp62
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
123,700 周安装
Quest resource provides. Keep formulas in the QuestManager.InventoryManager or EconomyManager via signals for decoupling.