View Format: Multi-Page

Simple Quest Forge

Generate Complete Quest Databases, Quest Chains, and Procedural Templates in Minutes.

Runtime API Reference

Simple Quest Forge provides 4 runtime classes and 3 data source interfaces for working with quest data at runtime. All types live in the SimpleQuestForge namespace.

SimpleQuestHelper

Static utility class with pure functions. Prerequisite checking, reward grouping, objective analysis, and cross-reference queries. No state, no MonoBehaviour.

SimpleQuestTracker

Plain C# class for runtime quest state. Handles activation, progress tracking, completion/failure, events, and save/load snapshots.

SimpleQuestChainTracker

Plain C# class that tracks chain progression, step completion, and branch choices. Can sync with SimpleQuestTracker for individual quest state.

SimpleProceduralQuestGenerator

Static class that generates concrete quest instances from procedural templates by resolving variable tokens. Returns SimpleGeneratedQuest structs.

SimpleQuestHelper

A static utility class with pure functions for quest data analysis. No state, no MonoBehaviour — just input data in, results out. Every method is a static function you can call from anywhere in your code.

Key pattern: Most SimpleQuestHelper methods take a SimpleQuestDefinition struct (the whole quest), not individual arrays. This keeps the API clean — you pass the quest, the helper extracts what it needs internally.

Prerequisite Checking

Use these methods to determine whether a player meets the requirements to accept a quest. Prerequisites compare a named value (like "PLAYER_LEVEL") against a threshold using a comparison operator (GreaterThan, LessThan, Equals, etc.).

CheckPrerequisite — Check a Single Prerequisite

Checks one prerequisite against a concrete float value. Use this when you already know the current value and just want a pass/fail result.

// Signature: // public static bool CheckPrerequisite(SimpleQuestPrerequisite prereq, float currentValue) // Example: Check if player level meets a prerequisite SimpleQuestPrerequisite levelReq = quest.prerequisites[0]; // e.g., "PLAYER_LEVEL >= 10" float playerLevel = 12f; bool met = SimpleQuestHelper.CheckPrerequisite(levelReq, playerLevel); // Returns true because 12 >= 10

CheckAllPrerequisites — Check All Prerequisites for a Quest

Checks every prerequisite on a quest using a delegate that looks up values by name. This is the method you will use most often — pass the whole quest struct and a function that returns the current value for any prerequisite code.

// Signature: // public static bool CheckAllPrerequisites( // SimpleQuestDefinition quest, // Func<string, float> valueProvider) // Example: Check if a player can accept "THE_DRAGONS_BANE" var quest = questDB.GetQuestByCode("THE_DRAGONS_BANE").Value; bool canAccept = SimpleQuestHelper.CheckAllPrerequisites(quest, code => { // This delegate is called once per prerequisite. // 'code' is the prerequisite's target (e.g., "PLAYER_LEVEL", "REPUTATION_WARRIORS_GUILD") // Return the player's current value for that code. switch (code) { case "PLAYER_LEVEL": return playerStats.Level; case "REPUTATION_WARRIORS_GUILD": return playerStats.GetReputation("WARRIORS_GUILD"); default: return 0f; } }); if (canAccept) Debug.Log("Player meets all prerequisites for The Dragon's Bane!");
What is Func<string, float>? It is a delegate — a reference to a function that takes a string parameter and returns a float. You can pass a lambda expression (code => ...), a method reference, or any function matching that signature. See Understanding Delegates at the bottom of this page.

EvaluatePrerequisites — Detailed Results per Prerequisite

When you need to show the player which prerequisites they pass and which they fail (for example, in a quest journal UI), use this method. It returns a list of PrerequisiteResult objects, each containing the original prerequisite, the current value, and whether it passed.

// Signature: // public static List<PrerequisiteResult> EvaluatePrerequisites( // SimpleQuestDefinition quest, // Func<string, float> valueProvider) // // PrerequisiteResult fields: // .prerequisite - the original SimpleQuestPrerequisite // .currentValue - the float returned by your valueProvider // .passed - true if the prerequisite is satisfied var quest = questDB.GetQuestByCode("THE_DRAGONS_BANE").Value; var results = SimpleQuestHelper.EvaluatePrerequisites(quest, code => { switch (code) { case "PLAYER_LEVEL": return 8f; // Below required 10 case "REPUTATION_WARRIORS_GUILD": return 50f; // Meets required 25 default: return 0f; } }); foreach (var r in results) { string status = r.passed ? "PASS" : "FAIL"; Debug.Log($"[{status}] {r.prerequisite.targetCode}: current={r.currentValue}"); } // Output: // [FAIL] PLAYER_LEVEL: current=8 // [PASS] REPUTATION_WARRIORS_GUILD: current=50

Reward Grouping

Quests can have required rewards (always granted on completion) and choice rewards (grouped by a choice group ID — the player picks one from each group). These methods help you separate and display them.

GetRequiredRewards — Always-Granted Rewards

// Signature: // public static List<SimpleQuestReward> GetRequiredRewards(SimpleQuestDefinition quest) // Example: Show guaranteed rewards in a quest accept dialog var quest = questDB.GetQuestByCode("WOLF_MENACE").Value; var guaranteed = SimpleQuestHelper.GetRequiredRewards(quest); foreach (var reward in guaranteed) Debug.Log($"Guaranteed: {reward.code} x{reward.amount}");

GetChoiceGroups — Grouped Reward Choices

// Signature: // public static Dictionary<int, List<SimpleQuestReward>> GetChoiceGroups(SimpleQuestDefinition quest) // Example: Build a reward selection UI var quest = questDB.GetQuestByCode("WOLF_MENACE").Value; var groups = SimpleQuestHelper.GetChoiceGroups(quest); // groups[1] = [Sword, Shield] -- player picks one from group 1 // groups[2] = [Gold Pouch, Gem] -- player picks one from group 2 foreach (var kvp in groups) { Debug.Log($"Choice Group {kvp.Key}:"); foreach (var reward in kvp.Value) Debug.Log($" - {reward.code} x{reward.amount}"); }

GetChoiceGroupIds — List of Choice Group IDs

// Signature: // public static List<int> GetChoiceGroupIds(SimpleQuestDefinition quest) // Example: Check how many reward choices the player needs to make var quest = questDB.GetQuestByCode("WOLF_MENACE").Value; var groupIds = SimpleQuestHelper.GetChoiceGroupIds(quest); Debug.Log($"Player must make {groupIds.Count} reward choice(s)");

Objective Utilities

Objectives are the tasks within a quest (kill 10 wolves, collect 5 herbs, talk to the elder). Each objective has a sortOrder, an isOptional flag, and a targetCount. These methods help you organize and evaluate them.

GetObjectivesBySort / GetRequiredObjectives / GetOptionalObjectives

// Signatures: // public static List<SimpleQuestObjective> GetObjectivesBySort(SimpleQuestDefinition quest) // public static List<SimpleQuestObjective> GetRequiredObjectives(SimpleQuestDefinition quest) // public static List<SimpleQuestObjective> GetOptionalObjectives(SimpleQuestDefinition quest) var quest = questDB.GetQuestByCode("WOLF_MENACE").Value; // Sorted by sortOrder (useful for display in quest journal) var sorted = SimpleQuestHelper.GetObjectivesBySort(quest); // Split into required vs. optional var required = SimpleQuestHelper.GetRequiredObjectives(quest); var optional = SimpleQuestHelper.GetOptionalObjectives(quest); Debug.Log($"Required: {required.Count}, Optional: {optional.Count}"); foreach (var obj in required) Debug.Log($" [{obj.code}] {obj.description} - Target: {obj.targetCount}");

AreRequiredObjectivesComplete — Check Completion

Determines if all required objectives have been fulfilled. Takes a delegate that maps each objective code to the player's current progress (an int).

// Signature: // public static bool AreRequiredObjectivesComplete( // SimpleQuestDefinition quest, // Func<string, int> progressProvider) var quest = questDB.GetQuestByCode("WOLF_MENACE").Value; // The delegate receives an objective CODE and should return current progress bool allDone = SimpleQuestHelper.AreRequiredObjectivesComplete(quest, objCode => { // Look up how much progress the player has made on this objective return questTracker.GetObjectiveProgress(questCode, objCode); }); if (allDone) Debug.Log("All required objectives complete! Quest can be turned in.");

GetCompletionPercentage — Overall Progress

// Signature: // public static float GetCompletionPercentage( // SimpleQuestDefinition quest, // Func<string, int> progressProvider) var quest = questDB.GetQuestByCode("WOLF_MENACE").Value; float pct = SimpleQuestHelper.GetCompletionPercentage(quest, objCode => { return questTracker.GetObjectiveProgress(questCode, objCode); }); Debug.Log($"Quest progress: {pct * 100f:F0}%"); // Output: "Quest progress: 70%"

Cross-Reference Queries

These methods search across an entire quest database to find relationships between quests. All of them take an ISimpleQuestDataSource (your generated database) as the first parameter, not raw arrays.

FindQuestsWithObjectiveTarget / FindQuestsWithRewardTarget

Find all quests that reference a specific target code in their objectives or rewards. Useful for building "related quests" UI or checking what quests involve a specific enemy/item.

// Signatures: // public static List<SimpleQuestDefinition> FindQuestsWithObjectiveTarget( // ISimpleQuestDataSource database, string targetCode) // public static List<SimpleQuestDefinition> FindQuestsWithRewardTarget( // ISimpleQuestDataSource database, string targetCode) // Example: Find all quests that involve wolves var wolfQuests = SimpleQuestHelper.FindQuestsWithObjectiveTarget(questDB, "WOLF"); Debug.Log($"Found {wolfQuests.Count} quests involving wolves"); // Example: Find all quests that reward gold var goldQuests = SimpleQuestHelper.FindQuestsWithRewardTarget(questDB, "GOLD"); Debug.Log($"Found {goldQuests.Count} quests that reward gold");

FindQuestsRequiringQuest / FindQuestsReferencingTarget

// Signatures: // public static List<SimpleQuestDefinition> FindQuestsRequiringQuest( // ISimpleQuestDataSource database, string questCode) // public static List<SimpleQuestDefinition> FindQuestsReferencingTarget( // ISimpleQuestDataSource database, string targetCode) // Find quests that depend on completing "WOLF_MENACE" first var dependents = SimpleQuestHelper.FindQuestsRequiringQuest(questDB, "WOLF_MENACE"); Debug.Log($"{dependents.Count} quests require WOLF_MENACE as a prerequisite"); // Find ALL quests that reference a target in any context (objectives, rewards, prerequisites) var allRefs = SimpleQuestHelper.FindQuestsReferencingTarget(questDB, "WOLF"); Debug.Log($"{allRefs.Count} quests reference WOLF somewhere");

GetPrerequisiteChain — Recursive Dependency Chain

Walks the prerequisite tree recursively to find the full chain of quests that must be completed before a given quest. Includes a circular dependency guard to prevent infinite loops.

// Signature: // public static List<SimpleQuestDefinition> GetPrerequisiteChain( // ISimpleQuestDataSource database, string questCode) // Example: Show the player what they need to do before "THE_DRAGONS_BANE" var chain = SimpleQuestHelper.GetPrerequisiteChain(questDB, "THE_DRAGONS_BANE"); Debug.Log("Prerequisite chain (in order):"); foreach (var q in chain) Debug.Log($" {q.code}: {q.name}");

GetUnlockedQuests — What Opens Up After Completion

Given a completed quest code and a value provider for prerequisite checking, returns all quests that become available as a result. Useful for "quest unlocked!" notifications.

// Signature: // public static List<SimpleQuestDefinition> GetUnlockedQuests( // ISimpleQuestDataSource database, // string completedQuestCode, // Func<string, float> valueProvider) // Example: After completing "WOLF_MENACE", find newly available quests var unlocked = SimpleQuestHelper.GetUnlockedQuests(questDB, "WOLF_MENACE", code => { switch (code) { case "PLAYER_LEVEL": return playerStats.Level; default: return 0f; } }); foreach (var q in unlocked) Debug.Log($"New quest available: {q.name}");

SimpleQuestTracker

A plain C# class that manages runtime quest state. Create it with new SimpleQuestTracker(database, valueProvider) and use it to start quests, track objective progress, detect completion/failure, and save/load state via snapshots.

Note: The code examples below are illustrative of the tracker's general API patterns. Consult the source code for the exact method signatures and parameters available in your version.

Setup

// Create a tracker with your generated database and an optional value provider var tracker = new SimpleQuestTracker(questDatabase, code => { // Value provider for prerequisite checking (optional) if (code == "PLAYER_LEVEL") return playerStats.Level; return 0f; });

Quest Lifecycle

// Start a quest (moves it from "available" to "active") tracker.StartQuest("WOLF_MENACE"); // Report objective progress (quest code, objective code, amount to add) tracker.ReportProgress("WOLF_MENACE", "KILL_WOLVES", 1); // killed 1 wolf // Get current progress for an objective int progress = tracker.GetObjectiveProgress("WOLF_MENACE", "KILL_WOLVES"); // Check quest status bool isActive = tracker.IsQuestActive("WOLF_MENACE"); bool isComplete = tracker.IsQuestComplete("WOLF_MENACE"); // required objectives done? bool isCompleted = tracker.IsQuestCompleted("WOLF_MENACE"); // quest turned in? bool isFailed = tracker.IsQuestFailed("WOLF_MENACE"); // Fail a quest (e.g., timer expired, NPC died) tracker.FailQuest("WOLF_MENACE");

Events

Subscribe to events to react to quest state changes in your UI, audio system, or game logic. All events fire after the state change has been applied.

// Subscribe to quest events tracker.OnQuestStarted += (questCode) => Debug.Log($"Started: {questCode}"); tracker.OnQuestCompleted += (questCode) => Debug.Log($"Completed: {questCode}"); tracker.OnQuestFailed += (questCode) => Debug.Log($"Failed: {questCode}"); tracker.OnObjectiveProgress += (questCode, objectiveCode, newCount) => Debug.Log($"{questCode} objective {objectiveCode}: {newCount}"); tracker.OnObjectiveCompleted += (questCode, objectiveCode) => Debug.Log($"{questCode} objective {objectiveCode} complete!"); // Practical example: Update quest HUD when objectives change tracker.OnObjectiveProgress += (questCode, objectiveCode, newCount) => { if (questCode == activeQuestCode) questHUD.RefreshObjective(objectiveCode, newCount); };

Save / Load

The tracker can serialize its entire state to a snapshot object and restore it later. Use this for save games, cloud saves, or scene transitions.

// Save current state to a snapshot object SimpleQuestTrackerSnapshot snapshot = tracker.CreateSnapshot(); // Serialize to JSON yourself for storage string json = JsonUtility.ToJson(snapshot); // Restore from a snapshot object tracker.RestoreFromSnapshot(snapshot); // Practical example: Save to PlayerPrefs PlayerPrefs.SetString("QuestState", JsonUtility.ToJson(tracker.CreateSnapshot())); PlayerPrefs.Save(); // Practical example: Load from PlayerPrefs string saved = PlayerPrefs.GetString("QuestState", ""); if (!string.IsNullOrEmpty(saved)) { var snap = JsonUtility.FromJson<SimpleQuestTrackerSnapshot>(saved); tracker.RestoreFromSnapshot(snap); }

SimpleQuestChainTracker

A plain C# class that tracks chain progression, step completion, and branch choices. Can sync with SimpleQuestTracker for individual quest state. A quest chain is a sequence of quests with optional branching paths.

Setup

Create the chain tracker with a chain database. Integration with the quest tracker is done via the SyncFromQuestTracker method.

var chainTracker = new SimpleQuestChainTracker(chainDatabase);

Chain Progression

// Start a chain chainTracker.StartChain("THE_DRAGON_SAGA"); // Mark a step as completed chainTracker.MarkStepCompleted("THE_DRAGON_SAGA", "WOLF_MENACE"); // Choose a branch (selects one quest from a branch group) // Note: branchGroup is a STRING, not an int chainTracker.ChooseBranch("THE_DRAGON_SAGA", "BRANCH_1", "HELP_THE_VILLAGE"); // Get currently active quest codes for a chain List<string> activeQuests = chainTracker.GetActiveQuestCodes("THE_DRAGON_SAGA"); // Check chain completion bool chainDone = chainTracker.IsChainCompleted("THE_DRAGON_SAGA"); // Get branch choice history (returns the chosen quest code for a branch group) string chosenQuest = chainTracker.GetBranchChoice("THE_DRAGON_SAGA", "BRANCH_1");
Important: The branchGroup parameter is a string, not an integer. Branch groups are identified by name (e.g., "BRANCH_1", "MORAL_CHOICE") to keep them readable in your quest chain definitions.

Sync with Quest Tracker

The chain tracker manages chain state only. To sync with a quest tracker, call SyncFromQuestTracker to propagate quest completion into chain progress:

// Sync chain state from quest tracker progress chainTracker.SyncFromQuestTracker(questTracker); // Example: Full chain workflow chainTracker.StartChain("THE_DRAGON_SAGA"); // Player completes objectives through questTracker... tracker.ReportProgress("WOLF_MENACE", "KILL_WOLVES", 10); // Sync chain state after quest progress chainTracker.SyncFromQuestTracker(questTracker); // At a branch point, player chooses chainTracker.ChooseBranch("THE_DRAGON_SAGA", "MORAL_CHOICE", "SAVE_THE_VILLAGE");

SimpleProceduralQuestGenerator

A static class that generates concrete quest instances from procedural templates by resolving variable tokens (like {ENEMY} and {COUNT}). Returns SimpleGeneratedQuest structs — not SimpleQuestDefinition.

Important: The Generate method takes a single SimpleProceduralQuest struct, not a database + code string. You must first retrieve the template from your database, then pass it to Generate.

The SimpleGeneratedQuest Return Type

Generated quests are returned as a lightweight struct containing the resolved text and data:

public struct SimpleGeneratedQuest { public string templateCode; // Code of the source template public string resolvedName; // Name with variables resolved public string resolvedDescription; // Description with variables resolved public Dictionary<string, string> resolvedVariables; // All resolved variable values public SimpleQuestObjective[] objectives; // Objectives from the template public SimpleQuestReward[] rewards; // Rewards from the template }

Generate — Single Quest from a Template

Retrieve a template from your procedural quest database, then pass it to Generate. The generator resolves all {VARIABLE} tokens in the template's name, description, and other text fields.

// Signature: // public static SimpleGeneratedQuest Generate( // SimpleProceduralQuest proceduralQuest, // Dictionary<string, string[]> variablePools = null, // System.Random random = null) // Step 1: Get the template from your database var template = proceduralDB.GetProceduralQuestByCode("KILL_BOUNTY").Value; // Step 2: (Optional) Define variable pools for randomization var pools = new Dictionary<string, string[]> { { "ENEMY", new[] { "Wolf", "Bear", "Bandit", "Skeleton" } }, { "COUNT", new[] { "5", "10", "15" } }, { "LOCATION", new[] { "Dark Forest", "Mountain Pass", "Ruined Keep" } } }; // Step 3: Generate a quest SimpleGeneratedQuest generated = SimpleProceduralQuestGenerator.Generate(template, pools); // Step 4: Use the result Debug.Log($"Quest: {generated.resolvedName}"); // Output: "Quest: Hunt 10 Wolves" (randomized from pools) Debug.Log($"Description: {generated.resolvedDescription}"); // Output: "A bounty has been posted for 10 Wolves near the Dark Forest." // Access the resolved variables to see what was chosen foreach (var kvp in generated.resolvedVariables) Debug.Log($" {kvp.Key} = {kvp.Value}"); // Output: // ENEMY = Wolf // COUNT = 10 // LOCATION = Dark Forest

GenerateBatch — Multiple Quests at Once

Generate multiple quests from an array of templates. Useful for populating a quest board with random daily quests.

// Signature: // public static SimpleGeneratedQuest[] GenerateBatch( // SimpleProceduralQuest[] proceduralQuests, // int count, // bool allowDuplicateTemplates = false, // Dictionary<string, string[]> variablePools = null, // System.Random random = null) // Get all templates from the database SimpleProceduralQuest[] allTemplates = proceduralDB.GetProceduralQuests(); // Generate 5 unique quests (no duplicate templates) var pools = new Dictionary<string, string[]> { { "ENEMY", new[] { "Wolf", "Bear", "Bandit" } }, { "COUNT", new[] { "5", "10", "15" } } }; SimpleGeneratedQuest[] batch = SimpleProceduralQuestGenerator.GenerateBatch( allTemplates, count: 5, allowDuplicateTemplates: false, variablePools: pools ); // Display on a quest board foreach (var quest in batch) Debug.Log($"[{quest.templateCode}] {quest.resolvedName}");

ResolveTemplate — Manual Token Replacement

A lower-level utility that replaces {KEY} tokens in a string with provided values. Useful when you want to format text outside the full generation pipeline.

// Signature: // public static string ResolveTemplate( // string template, // Dictionary<string, string> resolvedVariables) string result = SimpleProceduralQuestGenerator.ResolveTemplate( "Hunt {COUNT} {ENEMY}s in the {LOCATION}", new Dictionary<string, string> { { "COUNT", "12" }, { "ENEMY", "Wolf" }, { "LOCATION", "Dark Forest" } } ); // Result: "Hunt 12 Wolfs in the Dark Forest"

Practical Example: Daily Quest Board

// Complete workflow: procedural database -> generated quests -> quest tracker public class DailyQuestBoard : MonoBehaviour { public ScriptableObject proceduralDatabase; // Assign in Inspector public SimpleQuestTracker questTracker; void GenerateDailyQuests() { var db = proceduralDatabase as ISimpleProceduralQuestDataSource; var templates = db.GetProceduralQuests(); var pools = new Dictionary<string, string[]> { { "ENEMY", new[] { "Wolf", "Bear", "Bandit", "Skeleton" } }, { "COUNT", new[] { "3", "5", "8" } } }; // Generate 3 daily quests using a seeded random for reproducibility var today = new System.Random(System.DateTime.Today.GetHashCode()); var dailies = SimpleProceduralQuestGenerator.GenerateBatch( templates, 3, false, pools, today); foreach (var daily in dailies) Debug.Log($"Daily Quest: {daily.resolvedName}"); } }

Data Source Interfaces

All generated databases implement one of these interfaces for polymorphic access. This means you can write code that works with any quest database, regardless of what prefix or name you chose in the wizard. Cast your ScriptableObject to the interface:

// Your generated database is a ScriptableObject that implements the interface var questDB = myDatabaseAsset as ISimpleQuestDataSource; var quests = questDB.GetQuestDefinitions();

ISimpleQuestDataSource

Implemented by every generated quest database. Provides access to quest definitions, metadata arrays, and filtering methods.

Method / PropertyReturnsDescription
GetQuestDefinitions()SimpleQuestDefinition[]All quest definitions in the database
GetQuestByCode(string)SimpleQuestDefinition?Single quest by code (nullable — returns null if not found)
GetQuestCodes()string[]All quest codes (e.g., "WOLF_MENACE", "THE_DRAGONS_BANE")
GetQuestNames()string[]All quest display names
QuestCountintTotal number of quests (property, not method)
HasQuest(string)boolCheck if a quest code exists in this database
Quest-Level Metadata
GetCategoryLabels()string[]Quest-level category labels (e.g., "Quest Type", "Region")
GetCategoryEntries(int)string[]Entries for a quest-level category by index
GetFlagNames()string[]Quest-level flag names (e.g., "Is Repeatable", "Is Hidden")
GetNumericNames()string[]Quest-level numeric names (e.g., "Recommended Level", "Time Limit")
GetTextNames()string[]Quest-level text names (e.g., "Flavor Text", "Completion Dialog")
Objective-Level Metadata
GetObjectiveCategoryLabels()string[]Objective-level category labels
GetObjectiveCategoryEntries(int)string[]Entries for an objective-level category by index
GetObjectiveFlagNames()string[]Objective-level flag names
GetObjectiveNumericNames()string[]Objective-level numeric names
GetObjectiveTextNames()string[]Objective-level text names
Filtering
GetQuestsByCategory(int, int)SimpleQuestDefinition[]Filter quests by category index and entry value
GetQuestsByFlag(int, bool)SimpleQuestDefinition[]Filter quests by flag index and value

ISimpleQuestChainDataSource

Implemented by every generated quest chain database.

Method / PropertyReturnsDescription
GetChains()SimpleQuestChainDefinition[]All chain definitions
GetChainByCode(string)SimpleQuestChainDefinition?Single chain by code (nullable)
GetChainCodes()string[]All chain codes
ChainCountintTotal number of chains (property)
HasChain(string)boolCheck if a chain code exists
Chain-Level Metadata
GetCategoryLabels()string[]Chain-level category labels
GetCategoryEntries(int)string[]Entries for a chain-level category by index
GetFlagNames()string[]Chain-level flag names
GetNumericNames()string[]Chain-level numeric names
GetTextNames()string[]Chain-level text names

ISimpleProceduralQuestDataSource

Implemented by every generated procedural quest database.

Method / PropertyReturnsDescription
GetProceduralQuests()SimpleProceduralQuest[]All procedural quest templates
GetProceduralQuestByCode(string)SimpleProceduralQuest?Single template by code (nullable)
GetProceduralQuestCodes()string[]All template codes
ProceduralQuestCountintTotal number of templates (property)
HasProceduralQuest(string)boolCheck if a template code exists

Understanding the Delegate Pattern

Several SimpleQuestHelper methods accept delegate parameters — functions you pass as arguments. If you are new to C# delegates, here is a quick primer.

What is Func<string, float>?

Func<string, float> is a built-in C# delegate type that represents any function taking a string parameter and returning a float. Simple Quest Forge uses this pattern so the helper methods do not need to know how your game stores player data — you provide the lookup logic.

// Three equivalent ways to pass a Func<string, float>: // 1. Lambda expression (most common, inline) bool met = SimpleQuestHelper.CheckAllPrerequisites(quest, code => GetPlayerValue(code)); // 2. Method reference (when you have a matching method) bool met = SimpleQuestHelper.CheckAllPrerequisites(quest, GetPlayerValue); // 3. Explicit delegate variable Func<string, float> lookup = (string code) => { if (code == "PLAYER_LEVEL") return 15f; if (code == "GOLD") return 500f; return 0f; }; bool met = SimpleQuestHelper.CheckAllPrerequisites(quest, lookup);

What is Func<string, int>?

Same concept, but returns an int instead of a float. Used by the objective methods (AreRequiredObjectivesComplete, GetCompletionPercentage) because objective progress is tracked as integer counts.

// The delegate maps objective codes to current progress (int) float pct = SimpleQuestHelper.GetCompletionPercentage(quest, objCode => { // Return how much progress the player has on this objective return tracker.GetObjectiveProgress(questCode, objCode); // returns int });
Why delegates? They keep the quest system decoupled from your game's data storage. Whether you store player stats in a Dictionary, PlayerPrefs, a custom class, or a database, the quest helper does not care — you just provide the translation function.