3D RPG Quest System linking

Godot Version

4.5.1 Stable Mac OS

Question

So I’m starting to figuring out how could be quest stored, displayed and updated .

First I figure out to store quests in .tres , and then create manager, but not sure how to pass progress and completion to not be pickable again.


extends Resource
class_name Quest


@export var quest_id: int
@export var name_npc: String
@export var quest_title: String
@export var quest_description: String
@export var quest_objective: String
@export var quest_reward: float
@export var quest_state: bool = false

What should I be aware of ?
Here is functionality how it should works :

Your best bet is to just start building it and see where it goes.

2 Likes

For animals to be killed , how could I track their count to be only relatable to this specific animal not other?

There are as many ways to do this as there are programmers.

Me, off the top of my head, I would use the player as the repository of quests that were accepted, refused and completed. As each NPC is created, I’d fill each of them with the potential quests they’d have to offer the PC in accordance with the quest info the player holds. If none is found to be relevant for that character, I would just turn interaction off for that NPC, either until they have a new quest or some other dialog reason. And go on from there.

You could also use a singleton or a class that would be your quest manager. As I said, there are multiple ways of doing this.

Try things. Have fun. :smiley:

Edit: specificity and more clear

2 Likes

One way of doing that is that on death, you can tell your system what died. If your quest manager, or whatever you use, find that useful, you do what you have to do with it. Count +1, etc.

1 Like

For stats like that, I would personally create an Autoload singleton to track that. That way you can just call a signal.

#Stats Autoload
signal increase_kill_count(count: int, category: String

var kills: Dictionary


func _ready() -> void:
	increase_kill_count.connect(_increase_kill_count)


func _increase_kill_count(count: int, category: String) -> void:
	kills[category] = count + kills.get(category, 0)
#fox.gd
const FOX = "Fox"

func death() -> void:
	#1 will be added to the kill count of "Fox"
	Stats.increase_kill_count.emit(1, FOX) 
1 Like

Remove quest prefix from your properties. What’s the use of it? The context is Quest class. You don’t need to repeat that in every property. Always make your names as short as possible while taking care they’re expressive enough.

You don’t really need a “manager”. The two possible “managers” already exist and those are the quest giver and the player.

The goal is to know your problem and to represent it with data structures. The Quest class is not the only data structure you need to think of. You also need several containers (in GDScript those will typically be arrays or dictionaries): The queue of npc’s quests, and the list of player’s active quests. Both can be implemented as arrays.

In your Quest class you’re not constrained only to binary flags. You can have multistate flags aka enums. Those are basically named integers:

enum{KILL_MOBS, ESCORT, FIND_ARTEFACT}
var type: int = KILL_MOBS 

In more complex situations enums can be typed:

enum Type{KILL_MOBS, ESCORT, FIND_ARTEFACT}
var type: Type = Type.KILL_MOBS 

You can use those for multiple things. Another example would be quest state:

enum{AT_NPC, IN_PROGRESS, OBJECTIVE_MET, DONE}
var state = AT_NPC

You can use the same Quest object to store quest’s initial parameters as well as quest progress. Before the quest is given, it’s stored in npc’s queue. When the quest is accepted, a duplicate of Quest object can be created and added to player’s active quests list. Npc’s object can be deleted and removed from queue or if it’s recyclable, its parameters can be scaled up and it can go to the end of the queue or into some random position in the queue

The Quest object can have tracking properties for multiple quest types and use only ones that are applicable for its current type. In more complex versions you can have a different sub-resource that tracks data for each quest type and store its reference in the Quest object

The game can emit a signal whenever something relevant to quests happen (mob killed for example) and player’s quest object can connect to relevant signals depending on the quest type and trace its progress by itself. When the objectives are met it can send completion signal to the player and/or to the npc

3 Likes

@normalized @dharhix @dragonforge-dev

Thank you all for input , it was very helpful .

The core functionality now do opening dialogue, removing yes no on change of state, after completing kills quest is not shown .

For me big success :slight_smile:

4 Likes

Updated functionality, added OK button and on progress state are removed Yes and No button ,progress text , finnishing text ,

2 Likes