View Format: Multi-Page

Simple Quest Forge

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

Troubleshooting

Solutions for common issues you may encounter when using Simple Quest Forge. Each section covers a specific area of the tool with detailed explanations and step-by-step fixes. If you encounter an issue not listed here, check the Unity Console for messages prefixed with [Simple Quest Forge] — these provide specific diagnostic information.

Generation Issues

Database asset not created after generation

Simple Quest Forge uses a two-phase generation process. This is the most common source of confusion for new users. Here is how it works and what can go wrong:

Phase 1 writes three C# scripts to your output folder: {Prefix}Type.cs (an enum of all quest codes), {Prefix}Database.cs (a ScriptableObject that holds your quest data), and {Prefix}DatabaseEditor.cs (a custom Inspector editor). After writing these files, the wizard calls AssetDatabase.Refresh(), which triggers Unity's script compilation. The wizard window closes at this point.

Phase 2 runs automatically after Unity finishes compiling. An [InitializeOnLoad] handler detects a SessionState flag, waits one frame via EditorApplication.delayCall, reads a temporary JSON file from the Temp/ folder, and creates the .asset file with all your quest data populated.

If the asset does not appear:

  • Wait for compilation to finish completely — After clicking Generate, watch for Unity's "Compiling Scripts" progress bar in the bottom-right corner. Do not interact with the editor until it finishes. Phase 2 cannot run until domain reload completes.
  • Check the Console for errors — Open the Console window (Window → General → Console) and look for errors with the [Simple Quest Forge] prefix. Common errors include type name conflicts or missing assembly references.
  • Check SessionState flags — Each wizard uses a unique flag to coordinate the two phases:
    • Quest Forge: SimpleQuestForge_WaitingForCompilation
    • Quest Chain Forge: SimpleQuestForge_QuestChain_WaitingForCompilation
    • Procedural Quest Forge: SimpleQuestForge_ProceduralQuest_WaitingForCompilation
    If Unity crashes or is force-closed during compilation, stale flags may remain. Restarting Unity clears all SessionState data. You can then re-run the wizard and generate again.
  • Check the temp file — Phase 2 reads from a temporary JSON file stored in Unity's Temp/ folder (at the project root, not inside Assets). If this file was deleted (by antivirus software, manual cleanup, or a Temp folder wipe), the asset cannot be created. The fix is to re-run the wizard and generate again.
  • Check your output folder — Open the folder you specified in the wizard's Step 1 (Setup). You should see 3 or 4 new files after successful generation. If only the .cs files exist but no .asset, Phase 2 failed — check the Console for the specific error.

Compilation errors after generation

If Unity reports compilation errors after the wizard writes its scripts, the .asset file will not be created because Phase 2 cannot run until all scripts compile successfully.

  • Duplicate type names — Every generated database must have a unique Class Prefix. If you generate two Quest Forge databases with the prefix "RPG", both will try to create RPGQuestType.cs, RPGQuestDatabase.cs, etc., causing duplicate type errors. Use distinct prefixes like "RPGQuest" and "RPGSide" for different databases.
  • Missing namespace — Generated code includes using SimpleQuestForge; at the top. If the SQF Runtime assembly is not accessible (for example, if you moved the generated files outside the SQF assembly's reach), you will see "namespace not found" errors. Keep generated files inside your Assets folder where they can reference the SQF assemblies.
  • Regenerate from scratch — If errors persist, delete all generated files for that database (the 3 .cs files and the .asset if it exists), then re-open the wizard and generate again. The wizard preserves your data between sessions.

Custom editor not showing in Inspector

When you select your generated .asset file in the Project window, the Inspector should show the custom split-panel editor with search, sort, pagination, and formatted quest entries. If instead you see Unity's default array view ("Element 0", "Element 1", etc.):

  • Check the editor file exists — Look for {Prefix}DatabaseEditor.cs in your output folder. This file must be inside an Editor folder or an Editor-only assembly. The wizard places it alongside the other generated files, which works if your output folder is already inside an Editor directory. If not, move just the editor file into an Editor folder.
  • Reimport the script — Right-click the editor script in the Project window and select "Reimport". This forces Unity to re-register the custom editor.
  • Toggle Inspector lock — Click the lock icon on the Inspector tab, then click it again. This forces a full refresh of the custom editor binding.
  • Restart Unity — In rare cases, Unity's editor cache gets stale. A restart resolves this.

Schema Import Issues

Import says "0 items imported"

When you use the schema import feature (in Step 2 of any wizard), a result popup shows how many items were imported, skipped, and any errors. If it says "0 imported":

  • Check the JSON top-level array name — The import parser looks for a specific key at the root of the JSON object:
    • Quest Forge expects a "quests" array
    • Quest Chain Forge expects a "chains" array
    • Procedural Quest Forge expects a "templates" array
    If your JSON uses a different key (e.g., "questList" or "data"), the import will find zero items. Rename the key to match the expected name.
  • Validate required fields — Every item needs at minimum a "code" (string, no spaces, valid C# identifier) and a "name" (display name). Items missing either field are skipped. The result popup lists skip reasons — read these carefully.
  • Check the result popup details — The popup shows separate counts for imported, skipped, and errored items. If items were skipped, the popup explains why (duplicate code, missing required field, invalid category index, etc.). Address the specific issues and re-import.

AI-generated JSON won't import

When using the AI workflow (exporting schema, having an AI generate quest data, then importing), the AI may produce JSON that does not match the expected format:

  • Always use Full JSON export — The Full JSON export includes the complete format example with every field name, type, and valid value range. Give this to the AI as reference. The Light JSON export omits linked data (enemy names, item names) and may cause the AI to guess field structures incorrectly.
  • Check the definitions section — A common AI mistake is using wrong field names for dynamic properties. Categories use "label" and "entries" (not "name" and "options"). Flags use "name" and "defaultValue". Numerics use "name", "isInteger", "min", "max". The exported schema includes a "definitions" section with exact field names — make sure the AI references it.
  • Strip markdown code fences — AIs often wrap JSON in ```json ... ``` markers. Remove these before pasting into the import field. The import parser expects raw JSON, not markdown.
  • Validate JSON syntax — Use a JSON validator (online or in your IDE) to check for missing commas, unmatched brackets, trailing commas (not allowed in strict JSON), or unescaped special characters in strings.
  • Check array nesting — Objectives and rewards must be arrays nested inside each quest object. A common AI mistake is flattening these into top-level arrays or merging objectives from different quests together.

Objective/reward data not mapping correctly

If items import but their objectives, rewards, or dynamic properties have wrong values:

  • Category values use integer indices — Categories are stored as 0-based integer indices into the entries array. If your "Difficulty" category has entries ["Easy", "Medium", "Hard"], then Easy=0, Medium=1, Hard=2. The AI may try to use strings ("Easy") instead of integers (0). Only integers are accepted.
  • Flag values must be true/false — Boolean flags accept only the JSON literals true and false. Values like 0/1, "yes"/"no", or "true"/"false" (as strings) are not accepted and will be ignored or defaulted.
  • Nested structures must be preserved — Objectives and rewards must be arrays within each quest object, not flattened. Each objective needs its own categoryValues, flagValues, numericValues, and textValues arrays matching the objective-level schema definitions. Similarly for rewards. If the AI flattened the structure, you need to re-nest it.
  • Array lengths must match definition counts — If you defined 3 categories, each quest's categoryValues array must have exactly 3 elements. Extra or missing elements may cause silent misalignment where values map to the wrong property.

Wizard Issues

Can't proceed to next step

Each wizard step validates your input before allowing you to proceed. If the Next button is disabled or shows a warning, check these common blockers:

  • Empty Class Prefix — Step 1 requires a non-empty Class Prefix. This prefix is prepended to all generated type names (e.g., prefix "RPG" generates RPGQuestDatabase).
  • Invalid Class Prefix — The prefix must be a valid C# identifier: start with a letter (not a digit), contain only letters and digits (no spaces, hyphens, or underscores), and not be a C# reserved keyword.
  • No output folder selected — Step 1 requires you to choose an output folder. Click the folder button to open a folder picker. The folder must be inside your Assets directory.
  • Duplicate codes — In the builder step, every quest (or chain, or template) must have a unique code. The wizard highlights duplicates in red. Rename them to proceed.
  • Empty codes or names — Every entry must have both a code and a display name. Entries with blank codes or names block generation.

Quest Chain shows 0 quest codes in dropdown

The Quest Chain Forge wizard needs access to your generated quest databases so it can populate dropdown menus with available quest codes. If the dropdowns are empty:

  • Link quest databases in Step 1 — Open the Quest Chain Forge wizard and look at Step 1 (Setup). There is a database list where you assign your generated quest database .asset files. Drag them into the list slots. Without linked databases, the wizard has no quest codes to display.
  • Generate the quest database first — The quest database must be fully generated (both Phase 1 and Phase 2 complete) before you can link it. If you only see .cs files but no .asset file, the database generation did not complete. Go back to the Quest Forge wizard and regenerate.
  • Check the database implements the interface — The wizard looks for ISimpleQuestDataSource on linked ScriptableObjects. If you accidentally assign a non-quest database (e.g., a chain database), it will be ignored.

Smart target code picker shows empty sections

The smart target code picker in objective definitions can pull codes from companion packages (Simple Enemy Forge, Simple Item Forge, Simple Attribute Forge) via reflection bridges:

  • Link the appropriate databases — Enemy codes require linked enemy databases (from SEF), item codes require linked item databases (from SIF), and so on. Assign these in Step 1 of the Quest Forge wizard.
  • Check bridge availability — If a companion package is not installed, its bridge returns empty arrays. This is expected behavior, not an error. Install the companion package to get full dropdown support. The Console will log bridge detection events on domain reload with the [Simple Quest Forge] prefix.
  • Manual entry always works — Even without companion packages, you can always type target codes manually into the text field. The smart picker is a convenience feature, not a requirement.

Data lost after domain reload

Unity's domain reload (triggered by script compilation, entering Play Mode, etc.) clears all non-serialized state. The wizard mitigates this but some edge cases exist:

  • Most wizard data survives domain reloads — The wizard uses Unity's serialization system to preserve state. Your quests, definitions, and settings should persist across reloads. However, some transient UI state (scroll positions, foldout states) may reset.
  • Always generate before closing Unity — If you have unsaved work in a wizard, generate your database before closing Unity. Wizard data is stored in the EditorWindow's serialized fields, which are lost when Unity exits.
  • Export schema as backup — Use the Full JSON export feature in Step 2 (Definitions) to save your schema to a file. This gives you a complete, portable backup that can be re-imported into a fresh wizard at any time.

Custom Editor Issues

Inspector shows "Element 0", "Element 1" instead of the custom editor

This means Unity is using its default array drawer instead of the generated custom editor. The custom editor provides a split-panel view with a quest list on the left, detail editing on the right, search, sort, filter, and pagination.

  • Missing editor file — Check that {Prefix}DatabaseEditor.cs exists in your output folder. If it is missing, re-open the wizard and regenerate. The wizard will overwrite existing files and recreate any missing ones.
  • Editor not in Editor assembly — The editor script uses UnityEditor APIs and must be in an Editor folder or Editor assembly. If your output folder is not inside an Editor directory, Unity will try to include the editor script in runtime builds and fail. Move the *Editor.cs file into an Editor folder.
  • Assembly mismatch — Keep all three generated files ({Prefix}Type.cs, {Prefix}Database.cs, {Prefix}DatabaseEditor.cs) in locations where they can see each other. The editor file needs access to both the database type and the enum type. If you split them across assemblies that do not reference each other, the custom editor will silently fail to bind.

Editor performance slow with many quests

Databases with 100+ quests can cause noticeable slowdown in the Inspector, especially if quests have many objectives and rewards with expanded foldouts:

  • Use pagination — In the generated custom editor, look for the "Show All" toggle at the top of the quest list. Toggle it off to enable pagination, then set a reasonable page size (10-25 quests per page). This limits the number of quest entries drawn per frame.
  • Collapse foldouts — Each quest entry has foldouts for objectives, rewards, and dynamic properties. When expanded, these render extensive nested UI with ReorderableLists. Keep foldouts collapsed for quests you are not actively editing.
  • Use search to narrow results — Instead of scrolling through hundreds of entries, type a search term to filter the list. The editor searches both codes and names.

Quest Browser Issues

Quest Browser shows "0 quests"

The Quest Browser window (Window → Simple Quest Forge → Quest Browser) is a read-only overview tool that displays quests from your generated databases. If it shows "0 quests" or an empty list:

  • Assign databases in the browser window — The Quest Browser has its own database assignment slots at the top of the window. These are separate from the wizard's database references. Drag your generated .asset files into the browser's database list. The browser will immediately populate with quests from the assigned databases.
  • Make sure the database is fully generated — The browser reads from .asset files, not from wizard state. If your database has not completed Phase 2 generation (no .asset file exists), the browser has nothing to display.
  • Check that the database has quests — If the .asset exists but the browser still shows 0, open the asset directly in the Inspector to verify it contains quest entries. An empty database (generated with no quests defined) will legitimately show 0.

Quest Dependency Window shows no connections

The Quest Dependency Window visualizes prerequisite relationships between quests. If no connections appear:

  • Assign the same databases — Like the Quest Browser, the Dependency Window needs database assignments. Assign the same databases you used in the browser.
  • Check that quests have prerequisites — If no quests in your database reference other quests as prerequisites, there are no dependency connections to display. Add prerequisite codes to quests in the wizard's builder step, regenerate, and refresh.

Procedural Generation Issues

Generated quests all look the same

If SimpleProceduralQuestGenerator.Generate() keeps producing quests that feel identical or very similar, the issue is usually insufficient variety in your template variables:

  • Widen numeric ranges — If a NumericRange variable has a range of 10-12, the generated value will always be 10, 11, or 12 — barely distinguishable. Widen the range to something meaningful (e.g., 5-50 for enemy kill counts, 100-1000 for gold rewards) to produce noticeably different quests each time.
  • Add more TextList options — TextList variables randomly pick one string from a list. If your "EnemyName" variable only has ["Goblin", "Wolf"], half of all generated quests will target Goblins and half will target Wolves. Add 10-20 options per TextList variable for meaningful variety. Think about different locations, NPC names, item types, and enemy types that make sense for your game.
  • Use more variables in your patterns — If your title pattern is "Kill {count} {enemy}" but your description is static text with no variables, every quest will have an identical description. Add variables to descriptions, objective targets, and reward quantities to maximize variety.
  • Create multiple templates — Instead of one template that generates all quest types, create separate templates for "kill quests", "fetch quests", "escort quests", etc. Then use GenerateBatch() to pick randomly from all templates.

Custom variables not resolving (tokens appear as literal text)

If your generated quest shows literal {variableName} tokens instead of resolved values:

  • Variable names must match exactly — The token in your pattern (e.g., {enemy}) must match a defined variable name exactly, including case. {Enemy} and {enemy} are different tokens. Check your variable definitions in the wizard.
  • Pass variablePools to Generate() for custom variables — If you are defining variables at runtime (outside the wizard), you need to pass a Dictionary<string, string[]> of variable pools to the Generate() method. Without this, the generator does not know how to resolve custom tokens. Each key should be the variable name (without braces) and the value should be an array of possible string values to pick from.
  • Check for typos in braces — Make sure you are using { and } (curly braces), not (/) (parentheses) or [/] (square brackets). Only curly braces are recognized as token delimiters.

Generate() returns SimpleGeneratedQuest, not SimpleQuestDefinition

This is a common point of confusion. SimpleProceduralQuestGenerator.Generate() returns a SimpleGeneratedQuest struct, not a SimpleQuestDefinition. These are intentionally different types:

  • SimpleQuestDefinition is a serialized struct stored inside your generated database ScriptableObject. It represents a hand-authored quest with fixed values.
  • SimpleGeneratedQuest is a lightweight runtime struct produced by the procedural generator. It contains resolved strings (title, description), resolved numeric values, and generated objective/reward data. It is not stored in any database — it exists only in memory.
  • To use a generated quest with SimpleQuestTracker, you do not need to convert it. The tracker can work with generated quests directly via the procedural API. See the Runtime API page for details on tracking procedurally generated quests.

GenerateBatch() returns fewer quests than requested

  • Check allowDuplicateTemplates parameter — If you call GenerateBatch(count, allowDuplicateTemplates: false) and request more quests than you have templates, the method can only produce as many quests as there are templates. Set allowDuplicateTemplates: true to allow the same template to be used multiple times, or reduce your count to match your template count.

Bridge / Integration Issues

Bridge not detecting companion package

SQF uses reflection bridges to integrate with companion packages (Simple Enemy Forge, Simple Item Forge, Simple Attribute Forge). Each bridge has an [InitializeOnLoad] detector that probes for specific types via Type.GetType() on domain reload. If a bridge is not detecting an installed companion:

  • Check assembly names — Bridges probe for specific assembly-qualified type names (e.g., "SimpleEnemyForge.ISimpleEnemyDataSource, SimpleEnemyForge.Runtime"). If the companion package uses a custom assembly name different from the default, detection will fail. Check the companion's .asmdef file to verify its assembly name matches what the bridge expects.
  • Trigger a domain reload — After installing a companion package, the bridge detection runs on the next domain reload. You can force a reload by making any script change, reimporting the SQF Editor assembly (right-click the .asmdef → Reimport), or restarting Unity.
  • Check the Console — Bridge detection events are logged with the [Simple Quest Forge] prefix. Look for messages like "SEFBridge: detected" or "SIFBridge: not found". These confirm whether detection succeeded or failed and can point to the specific type name that was not found.
  • Check define symbols — Each bridge detector sets a scripting define symbol when its companion is found (e.g., SIMPLE_ENEMY_FORGE). You can check Project Settings → Player → Scripting Define Symbols to see which bridges are active. However, note that SQF never uses these defines for conditional compilation — all bridge access is via reflection. The defines exist for informational purposes only.

Compilation errors after removing a companion package

Removing a companion package (e.g., uninstalling Simple Enemy Forge) should never cause compilation errors in SQF. All bridges use runtime reflection, not hard using statements or assembly references. If you do see errors after removal:

  • Check your own code — If you have written custom scripts that directly reference companion namespaces (e.g., using SimpleEnemyForge;), those references will break when the companion is removed. SQF itself never does this, but your project code might.
  • Check for stale assembly references — Open the SQF .asmdef files and check their references list. SQF should not have hard references to companion assemblies. If you manually added one, remove it.
  • Data is preserved — When a companion is removed, SQF preserves all existing data. Enemy codes, item codes, and other linked references stored as strings in your quest databases remain intact. When you reinstall the companion, those references become functional again. No data is lost during the removal/reinstallation cycle.

Bridge shows companion as detected but dropdowns are empty

If the Console confirms bridge detection but the smart target picker or database linker shows no entries:

  • Generate the companion's database first — The bridge reads data from generated .asset files, not from wizard state. Make sure the companion package's database is fully generated (the .asset exists and contains entries).
  • Link the companion's database in Step 1 — Each wizard's Setup step has database assignment slots for companion databases. Drag the companion's .asset file into the appropriate slot. Without an assigned database, the bridge has no data source to read from.

Runtime Issues

SimpleQuestTracker not updating

The SimpleQuestTracker manages quest state (inactive, active, completed, failed) and objective progress at runtime. If it is not responding to your calls:

  • Call Initialize() first — The tracker must be initialized with a quest database before any other operations. Call tracker.Initialize(questDatabase) in your Start() or Awake() method. Without initialization, all other methods silently do nothing.
  • Start the quest before updating progress — You must call tracker.StartQuest(questCode) before calling tracker.UpdateObjectiveProgress(). Only quests in the "Active" state accept progress updates. Quests that are still "Inactive", already "Completed", or "Failed" ignore progress calls.
  • Check the quest code — Quest codes are case-sensitive strings. Make sure the code you pass to StartQuest() exactly matches the code in your database. A typo will silently fail (no quest found to start).
  • Check objective indices — When calling UpdateObjectiveProgress(questCode, objectiveIndex, amount), the objective index is 0-based. If a quest has 3 objectives, valid indices are 0, 1, and 2. An out-of-range index is silently ignored.

SimpleQuestChainTracker not advancing

  • Complete the current step's quest first — The chain tracker advances to the next step only when the current step's linked quest is completed in the quest tracker. Make sure you are completing quests through SimpleQuestTracker, not just setting progress.
  • Check branch group requirements — If a step is in a branch group, the chain may require completing any one step in the group (or all, depending on your configuration) before advancing past the branch point.

Procedural generation producing identical quests

See the Procedural Generation Issues section above for detailed solutions. The most common causes are narrow numeric ranges and too few TextList options.

Save/Load snapshot not restoring correctly

SimpleQuestTracker supports saving and loading snapshots of the entire tracker state for save game systems. If restoration is not working correctly:

  • Same database required — Snapshots reference quest codes, not indices. If you regenerate your database with different codes between saving and loading, the snapshot will contain codes that no longer exist. The tracker will skip unrecognized codes during restoration. Always use the same database (or at least the same codes) when loading.
  • Initialize before loading — Call Initialize(questDatabase) before calling LoadSnapshot(). The tracker needs the database reference to validate incoming codes.
  • Snapshot format is JSON — If you are persisting snapshots to disk, make sure you are writing and reading the snapshot string without modification. Truncation, encoding issues, or accidental modification will corrupt the snapshot.

Performance Tips

Use Pagination for Large Databases

Generated custom editors and wizard builder steps both support pagination. For databases with 100+ quests, toggle off "Show All" and set a page size of 10-25. This dramatically reduces the number of UI elements drawn per frame, keeping the Inspector responsive. Pagination is available in all three wizard builder steps (Quest, Chain, Procedural) and in all generated database editors.

Collapse Foldouts in Inspector

Each quest entry in the generated editor has foldouts for objectives, rewards, dynamic properties (categories, flags, numerics, texts), and linked data. When all foldouts are expanded on a quest with 10 objectives and 5 rewards, the Inspector renders hundreds of individual UI controls. Collapse foldouts for entries you are not actively editing to reduce draw overhead. This is especially important when "Show All" is enabled on large databases.

GenerateBatch with Duplicate Control

When calling GenerateBatch(count, allowDuplicateTemplates), be aware that setting allowDuplicateTemplates: false with a count greater than your template count will result in fewer quests than requested (the method cannot produce more unique-template quests than templates exist). If you need a large batch, either set allowDuplicateTemplates: true or ensure you have enough templates. Setting allowDuplicateTemplates: false with count equal to template count is safe and guarantees exactly one quest per template.

Schema Export for Backup, Not Real-Time

Schema export (Full JSON, Light JSON, Markdown) serializes your entire wizard state to a string. For large databases, this can take a moment. Use it for backups and AI workflows, not as a real-time data exchange mechanism. The export is designed to run once when you need it, not on every frame or every Inspector draw.

General Tips

Check the Console

All SQF log messages are prefixed with [Simple Quest Forge]. Filter the Console by this prefix to see only SQF-related messages. This includes bridge detection events, generation progress, Phase 2 asset creation confirmations, and any warnings or errors encountered during import, export, or generation.

Export Before Experimenting

Before making major changes to definitions (adding/removing categories, renaming properties, restructuring objectives), export your schema as Full JSON from Step 2 of the wizard. This gives you a complete backup of your definitions, quests, and all linked data that can be re-imported into a fresh wizard session. It takes seconds and can save hours of rework.

Generate Incrementally

Start with Quest Forge alone. Get your quest database generated and working in the Inspector. Then add Quest Chain Forge to organize quests into sequences. Finally, add Procedural Quest Forge for random generation. Each forge generates independently — you do not need all three to use any one of them.

Use Templates as Starting Points

SQF includes 6 genre templates for Quest Forge (RPG, Action, Horror, Visual Novel, Simulation, Strategy) and 6 for Procedural Quest Forge. Loading a template populates the wizard with genre-appropriate definitions, sample quests or templates, and sensible defaults. Start with the closest template to your game and customize from there rather than building everything from scratch.