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
- Quest Forge:
- 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
.csfiles 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
.csfiles and the.assetif 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.csin 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
"questList"or"data"), the import will find zero items. Rename the key to match the expected name. - Quest Forge expects a
- 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
trueandfalse. 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, andtextValuesarrays 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
categoryValuesarray 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
.assetfiles. 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
.csfiles but no.assetfile, 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
ISimpleQuestDataSourceon 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.csexists 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
UnityEditorAPIs 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.csfile 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
.assetfiles 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
.assetfiles, not from wizard state. If your database has not completed Phase 2 generation (no.assetfile exists), the browser has nothing to display. - Check that the database has quests — If the
.assetexists 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 theGenerate()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. SetallowDuplicateTemplates: trueto 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.asmdeffile 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 checkProject Settings → Player → Scripting Define Symbolsto 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
.asmdeffiles 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
.assetfiles, not from wizard state. Make sure the companion package's database is fully generated (the.assetexists 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
.assetfile 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 yourStart()orAwake()method. Without initialization, all other methods silently do nothing. - Start the quest before updating progress — You must call
tracker.StartQuest(questCode)before callingtracker.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 callingLoadSnapshot(). 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.