godot-quest-system

安装量: 57
排名: #12976

安装

npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-quest-system

Quest System Resource-based data, signal-driven updates, and AutoLoad coordination define scalable quest architectures. Available Scripts quest_manager.gd Expert AutoLoad quest tracker with objective progression and reward distribution. quest_graph_manager.gd Runtime manager for graph-based quests. Tracks objectives and node progression. NEVER Do in Quest Systems NEVER store quest data in nodes — Quest progress in player.gd variables? Loss on scene reload. Use Resource-based Quests OR AutoLoad singleton. NEVER use strings for quest IDs without registry — update_objective("kil_bandts", ...) typo = silent failure. Use constants OR validate IDs against registry. NEVER forget to disconnect signals — Quest completed but signal still connected? Quest completes again on next update = duplicate rewards. Disconnect in _on_quest_completed() . NEVER poll for objective updates — Checking if enemy_count == 10 every frame = wasteful. Use signals: enemy.died.connect(quest_manager.on_enemy_killed) . NEVER skip save/load for quests — Player completes quest 5, game restarts, quest resets? Frustration. MUST persist active_quests + completed_quests arrays. NEVER use all() for objectives without null check — objectives.all(func(obj): return obj.is_complete()) with null objectives? Crash. Validate array contents first.

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 Objectives

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

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 Quest Triggers

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

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 Best Practices Signal-Driven - Emit events, systems listen Save Progress - Track completed quests Validation - Check prerequisites before accepting Reference Related: godot-dialogue-system , godot-save-load-systems Related Master Skill: godot-master

返回排行榜