Build Your Skill System
Stop hand-coding skill databases and writing boilerplate ScriptableObject editors. Simple Skill Forge gives you 4 interconnected wizard tools that generate production-ready databases with custom editors, type-safe enums, runtime trackers, and AI-assisted content generation — all from a guided, step-by-step interface inside the Unity Editor.
Whether you are building an ARPG with hundreds of hand-crafted abilities, a MOBA with precise skill loadouts, or a soulslike with deep talent trees, Simple Skill Forge handles the infrastructure so you can focus on game design.
Why Simple Skill Forge?
Complete Package
All 4 forges, all runtime components, all 6 genre templates, and full documentation included. No hidden tiers, no premium upgrades, no paywalls. One purchase, everything included.
Two-Level Properties
The Skill Forge defines dynamic properties at both skill-level AND rank-level. Define Categories, Flags, Numerics, and Texts independently for skills and their individual ranks — giving you unmatched flexibility without touching code.
AI-First Design
Schema export in 3 formats (Full JSON, Light JSON, Markdown) with embedded AI instructions for bulk content generation. Export your schema, hand it to ChatGPT or Claude, and import hundreds of skills back into your database in seconds.
Deep Cross-Forge Integration
12 cross-forge reference fields connect skills to items (weapon requirements, reagent costs, crafted items), enemies (summons, trainers, faction effectiveness), quests (unlock conditions, rewards), and attributes (modifiers, class restrictions). All via safe reflection — zero hard dependencies.
Zero Dependencies
Works standalone out of the box. Optional companion integrations with Simple Attribute Forge, Simple Item Forge, Simple Enemy Forge, and Simple Quest Forge are detected and enabled automatically when installed.
6 Genre Templates
Start with pre-built property schemas for ARPG, MOBA, MMO, Turn-Based, Action, or Roguelike games. Each template provides genre-appropriate Categories, Flags, Numerics, and Texts — customize them freely or start from scratch.
The Four Forges
Skill Forge
The main forge. Define skills with two-level dynamic properties (skill-level + rank-level), multi-rank progression with upgrade costs, prerequisites, SAF modifier assets, and 12 cross-forge reference fields for items, enemies, quests, and factions.
Skill Tree Forge
Build talent trees with grid-based node layouts, parent-child connections, branch groups, point costs, level requirements, and single-level dynamic properties. Nodes reference skills from any Skill Forge database.
Skill Set Forge
Create loadout templates with typed slots, skill assignments, and threshold-based set bonuses (equip 3/5 for bonus effects). Supports SAF modifier assets on bonuses. Single-level properties.
Skill Combo Forge
Define skill sequences with ordered steps (required/optional), alternate skill choices, timing windows, branch groups, and threshold rewards with modifier effects. Single-level properties.
Utility Windows
Database Export
Export any generated database as clean JSON with resolved property names. Supports all 4 database types. Ideal for AI workflows, data sharing, and backups.
Window > Living Failure > Simple Skill Forge > Export Database
Batch Icon Assignment
Scan a sprite folder and auto-match sprites to skill/tree/set/combo codes by normalized filename. Preview matches, manually override, and apply in one click.
Window > Living Failure > Simple Skill Forge > Batch Icon Assignment
What Gets Generated
Each forge generates 4 files per database:
| File | Description |
|---|---|
{Prefix}Type.cs |
Type-safe enum of all entry codes (e.g., ARPGSkillsType.FIREBALL) |
{Prefix}Database.cs |
ScriptableObject class implementing the forge's interface (e.g., ISimpleSkillDataSource) |
{Prefix}DatabaseEditor.cs |
Custom inspector that mirrors the wizard's builder UI with search, sort, filter, and pagination |
{Prefix}Database.asset |
The actual ScriptableObject instance with all your data baked in |
Runtime Components
SimpleSkillHelper
Static utility class for prerequisite checking, cross-reference queries, skill lookups by item/enemy/quest code, and resource affordability checks.
SimpleSkillTreeTracker
Runtime state tracker for skill tree node unlocks. Tracks points spent, validates unlock requirements, supports cascade reset, and provides event callbacks and serializable snapshots.
SimpleSkillBarManager
Runtime manager for skill set loadouts. Handles equip/unequip to typed slots, tracks threshold-based set bonuses, and provides events and snapshots.
SimpleSkillComboTracker
Runtime tracker for active skill combos with timing windows. Tracks combo progress across all defined combos simultaneously, fires events on progression/completion/drops, and awards threshold rewards.
Plus SimpleSkillComboEvaluator — a static utility for evaluating combo progress, getting next valid skills, and checking timing windows without instantiating a tracker.
Getting Started
Window > Living Failure > Simple Skill Forge > Skill Forge
(or Tree/Set/Combo Forge).
See Quick Start for a complete walkthrough.
Interconnected Ecosystem
Simple Skill Forge is part of the Simple Forge Ecosystem — a family of Unity tools that work independently but become more powerful together:
| Package | What It Does | How It Connects to SSF |
|---|---|---|
| Simple Attribute Forge | Character stats, modifiers, and class templates | Modifier assets on skills/ranks/bonuses, attribute prerequisites, character class restrictions |
| Simple Item Forge | Items, loot tables, crafting, shops, item sets | Skill books, weapon requirements, reagent costs, produced items |
| Simple Enemy Forge | Enemies, factions, squads, spawns, waves | Summon skills, NPC trainers, learned-from enemies, faction effectiveness |
| Simple Quest Forge | Quests, quest chains, procedural quests | Quest-gated skill unlocks, quest-rewarded skills |
All integrations use safe reflection — no hard dependencies, no compile errors if companion packages are not installed. Install them when you need them.
See Integration for details on each cross-forge connection.
Package Manager (UPM)
The recommended way to install Simple Skill Forge is through Unity's Package Manager using a Git URL. This approach makes updates easy and keeps the package outside your Assets folder.
Option A — Git URL
Option B — manifest.json
You can also add the package directly to your project's Packages/manifest.json file:
Save the file and return to Unity. The package will be resolved automatically.
#v1.0.0 (or any tag/branch) to the Git URL.
Asset Store
Simple Skill Forge is available on the Unity Asset Store.
The package will be placed under Assets/SimpleSkillForge/.
Manual Import
If you received Simple Skill Forge as a .unitypackage file:
.unitypackage file and select it.
.asmdef) files after import.
They define the SimpleSkillForge.Runtime and SimpleSkillForge.Editor assemblies
and must remain in their original locations for compilation to succeed.
Verifying Installation
After installation, verify that everything is working correctly:
Window > Living Failure > Simple Skill Forge.
You should see 4 forge entries: Skill Forge, Skill Tree Forge,
Skill Set Forge, and Skill Combo Forge, plus the utility windows.
Window > General > Console). A clean installation produces zero errors.
If you encounter issues, see Troubleshooting.
Optional Companions
Simple Skill Forge works standalone with zero dependencies. However, it integrates with 4 companion packages from the Simple Forge Ecosystem. When a companion is detected, SSF automatically enables additional features via safe reflection — no configuration required.
| Package | UPM Name | What It Unlocks in SSF |
|---|---|---|
| Simple Attribute Forge | com.livingfailure.simple-attribute-forge |
Modifier assets on skills, ranks, and set bonuses. Attribute names for prerequisites. Character class restrictions via Character Template integration. |
| Simple Item Forge | com.livingfailure.simple-item-forge |
Item-skill relationships: skill books (grantedByItemCode), weapon requirements
(requiredEquipmentCode), crafted items (producesItemCode), and
reagent costs (reagentCosts[]). |
| Simple Enemy Forge | com.livingfailure.simple-enemy-forge |
Enemy-skill relationships: summon skills (summonEnemyCode), NPC trainers
(taughtByNPCCode), learned-from enemies (learnedFromEnemyCode),
faction effectiveness (effectiveAgainstFactions[]), and faction restrictions
(restrictedToFactionCode). |
| Simple Quest Forge | com.livingfailure.simple-quest-forge |
Quest-skill relationships: quest-gated unlocks (unlockedByQuestCode) and
quest-rewarded skills (rewardedByQuestCodes[]). |
Installing Companions
Install companion packages the same way you installed SSF (UPM, Asset Store, or manual import). Once imported, SSF detects them automatically on the next domain reload. No restart or manual configuration is needed.
Detection Mechanism
SSF uses two detection methods that work together:
- UPM detection: The
.asmdeffiles containversionDefinesentries that set scripting defines (e.g.,SIMPLE_ATTRIBUTE_FORGE,SIMPLE_ITEM_FORGE) when companion packages are present in the Package Manager. - Reflection detection: Bridge classes (
SAFBridge,SIFBridge,SEFBridge,SQFBridge) probe for companion types at runtime usingType.GetType(). This handles non-UPM installations (Asset Store, manual import).
Assembly Definitions
Simple Skill Forge uses two assembly definitions to keep runtime and editor code properly separated:
| Assembly | Namespace | Contents |
|---|---|---|
SimpleSkillForge.Runtime |
SimpleSkillForge |
All runtime types: definitions (skill, tree, set, combo), interfaces
(ISimpleSkillDataSource, etc.), helpers, trackers, evaluators, bridges |
SimpleSkillForge.Editor |
SimpleSkillForge.Editor |
All editor types: wizard windows, wizard steps, wizard data, code generators, templates, schema export, utility windows |
Referencing SSF in Your Code
If your project uses assembly definitions, add a reference to SimpleSkillForge.Runtime
in your runtime .asmdef to access SSF types:
For editor scripts that need SSF editor types, reference both assemblies:
Version Defines
The runtime assembly's .asmdef includes versionDefines for all companion packages.
When a companion is installed via UPM, Unity automatically sets the corresponding scripting define symbol:
| Companion Package | Define Symbol |
|---|---|
com.livingfailure.simple-attribute-forge |
SIMPLE_ATTRIBUTE_FORGE |
com.livingfailure.simple-item-forge |
SIMPLE_ITEM_FORGE |
com.livingfailure.simple-enemy-forge |
SIMPLE_ENEMY_FORGE |
com.livingfailure.simple-quest-forge |
SIMPLE_QUEST_FORGE |
These defines gate #if blocks in SSF source code so that companion-specific features
compile only when the companion is present.
Your First Skill Database
This guide walks you through creating a complete skill database using the Skill Forge — from opening the wizard to using the generated database in your game code. The entire process takes about 5 minutes.
By the end, you will have:
- A type-safe enum of all your skill codes
- A ScriptableObject database with a custom inspector
- Runtime-ready data you can query from any script
Step 1: Setup
Open the Skill Forge wizard:
The wizard opens to Step 1: Setup. Configure these fields:
Database Name
Enter a name for your database, e.g., RPGSkills. This determines the generated class names:
| Field | Example |
|---|---|
| Database Name | RPGSkills |
| Generated Enum | RPGSkillsType |
| Generated Database | RPGSkillsDatabase |
| Generated Editor | RPGSkillsDatabaseEditor |
Namespace
Optionally set a namespace for the generated code. Leave blank if your project does not use namespaces.
Template
Select a genre template to pre-populate property definitions. For this walkthrough, choose ARPG — it provides a solid set of categories (Skill Type, Element, Target Type), flags (Is Passive, Is Ultimate), numerics (Mana Cost, Cooldown, Cast Time), and texts (Tooltip, Lore) at both skill-level and rank-level.
Linked Databases
If you have companion packages installed (SAF, SIF, SEF, SQF), you can drag-and-drop their generated database assets here. This enables searchable dropdowns for cross-forge reference fields in Step 3 (e.g., selecting an item code from your SIF database instead of typing it manually).
For this walkthrough, you can skip linked databases. They are entirely optional.
Click Next to proceed to Step 2.
Step 2: Definitions
This is where you define the dynamic property schema for your skills. The Skill Forge uses a two-level property system:
- Skill-Level Properties — apply to the skill as a whole (e.g., Skill Type, Element, Is Passive)
- Rank-Level Properties — apply to each individual rank of a skill (e.g., Damage, Mana Cost, Area of Effect)
If you chose the ARPG template, you will see pre-populated definitions at both levels. You can customize them freely.
Property Types
There are 4 types of dynamic properties, available at both skill-level and rank-level:
| Type | What It Stores | Example |
|---|---|---|
| Category | Selection from a list of named entries | Skill Type: [Attack, Buff, Debuff, Heal, Summon] |
| Flag | Boolean (true/false) | Is Passive, Is Ultimate, Requires Line of Sight |
| Numeric | Float or integer value (optionally a range) | Mana Cost, Cooldown, Cast Time, Base Damage |
| Text | String value (single or multi-line) | Tooltip, Lore Text, VFX Path |
Adding a Property
To add a new property, expand the relevant section (e.g., Skill-Level Categories) and click the + button at the bottom of the list. Fill in the label/name and any additional settings (entries for categories, constraints for numerics, line count for texts).
Removing or Reordering
Use the - button to remove a property, or drag entries in the ReorderableList to reorder them. All existing skill entries are automatically synced when you add, remove, or reorder definitions.
JSON Schema Export
At the bottom of Step 2, you will find the JSON Schema section. This lets you export your property definitions in 3 formats (Full JSON, Light JSON, Markdown) for AI-assisted bulk content generation. You can also import skills from JSON. See AI Workflow for details.
Click Next to proceed to Step 3.
Step 3: Builder
The builder is a split-panel editor where you create and edit individual skill entries.
Left Panel — Skill List
The left panel shows all your skills in a scrollable list with:
- Search bar — filter by name or code
- Category filter — show only skills of a specific type
- Sort — alphabetical, by code, or by category
- Pagination — handles large lists efficiently
- Bulk operations — select multiple skills for delete or duplicate
- + / - buttons — add or remove skills
Click any skill in the list to select it and edit its details in the right panel.
Right Panel — Skill Editor
The right panel displays all editable fields for the selected skill, organized into foldout sections:
- Identity — Code (SCREAMING_SNAKE_CASE), display name, description, icon
- Categories — dropdown selectors for each skill-level category
- Flags — toggle checkboxes for each skill-level flag
- Numeric Properties — value fields for each skill-level numeric
- Text Properties — text fields for each skill-level text
- Ranks — a list of ranks, each with its own rank-level properties, upgrade costs (resource code + amount), and optional SAF modifier assets
- Prerequisites — conditions that must be met to learn/use the skill (e.g., "FIREBALL at least rank 3")
- Skill Modifiers — SAF modifier assets attached to the skill itself (requires Simple Attribute Forge)
- Cross-Forge References — 12 fields linking to items, enemies, quests, and factions from companion forges
Creating Your First Skill
FIREBALL and the Display Name
to Fireball. Add a description like Hurls a ball of fire at the target.
Repeat to add more skills. Use Duplicate to clone an existing skill as a starting point.
Click Next to proceed to Step 4.
Step 4: Settings
Configure where and how the database is generated.
Output Path
Set the folder where generated files will be placed. The default is Assets/GeneratedSkillDatabases/.
Click Browse to choose a different location.
Custom Paths
Enable Use Custom Paths to specify separate output folders for scripts (.cs files)
and assets (.asset files). Useful if you want scripts in a Scripts/ folder
and assets in a Data/ folder.
Generation Toggles
- Generate Enum — produces the
{Prefix}Type.csenum file. Disable if you want to manage skill identifiers differently. - Generate Database — produces the
{Prefix}Database.csScriptableObject and{Prefix}DatabaseEditor.cscustom inspector. Almost always left enabled.
File Preview
The bottom of Step 4 shows a preview of all files that will be generated, including their full paths. Review this before proceeding.
Click Next to proceed to Step 5.
Step 5: Generate
The final step shows a summary of your database and a Generate button.
Summary
Review the summary to confirm everything is correct: database name, number of skills, number of properties, output paths, and enabled generation options.
Generation Process
Click Generate to start the two-phase generation:
.cs files
(enum, database class, custom editor) to your output folder. Unity then triggers a domain reload
to compile the new scripts.
.asset ScriptableObject and populates it with all your
skill data. A log message confirms completion.
[InitializeOnLoad] handler that runs after
the domain reload to complete Phase 2.
Generated Files
After generation completes, you will find these files in your output folder:
.asset file in the Project window and inspect it.
The custom editor displays your skills in the same split-panel layout as the wizard's builder.
Using Your Database at Runtime
The generated database implements ISimpleSkillDataSource, giving you a clean API
to query skill data from any script.
Assigning the Database
Add a ScriptableObject field to your MonoBehaviour and drag the generated .asset
file onto it in the Inspector:
Querying Skills
Use the interface methods to access your data:
Reading Dynamic Properties
Access the dynamic properties you defined in Step 2 using index-based accessors. The index corresponds to the order you defined them (0-based):
Property Definition Labels
To get human-readable labels for your properties (useful for UI), query the data source:
Filtering
Query skills by property values:
Using SimpleSkillHelper
The static helper class provides utility functions without needing a tracker instance:
Next Steps
You have created your first skill database. Here is where to go from here:
Skill Forge Deep Dive
Learn about all features: rank progression, prerequisites, cross-forge references, and the two-level property system in detail.
Build Skill Trees
Create talent trees with grid-based node layouts that reference your skills. Nodes have point costs, level requirements, and parent-child connections.
Create Skill Sets
Design loadout templates with typed slots and threshold-based set bonuses. "Equip 3 fire skills for +20% fire damage."
Define Combos
Build skill sequences with timing windows and threshold rewards. "Fireball, Ice Bolt, Lightning within 2 seconds = Elemental Burst."
AI-Assisted Content
Export your schema to JSON or Markdown, feed it to an AI assistant, and import hundreds of generated skills back into your database.
Cross-Forge Integration
Connect to Simple Attribute Forge, Simple Item Forge, Simple Enemy Forge, and Simple Quest Forge for deep cross-system references.
Overview
The Skill Forge is the primary forge in Simple Skill Forge. It generates complete
skill databases as ScriptableObjects with type-safe enums, custom inspectors, and a runtime interface
(ISimpleSkillDataSource) for querying skill data from game code.
What makes the Skill Forge unique among the four forges is its two-level dynamic property system. You define properties at two independent levels:
- Skill-Level Properties (Level 1) — apply to the skill as a whole. Examples: Skill Type, Element, Is Passive, Mana Cost, Tooltip.
- Rank-Level Properties (Level 2) — apply to each individual rank within a skill. Examples: Damage, Healing Amount, Area of Effect, Duration.
On top of the two-level property system, each skill supports:
- Multi-rank progression with per-rank upgrade costs and SAF modifier assets
- Prerequisites for skill unlock conditions
- 12 cross-forge reference fields linking skills to items (SIF), enemies (SEF), quests (SQF), and attributes/modifiers (SAF)
- Character class restrictions via SAF Character Templates
Open the Skill Forge wizard from the Unity menu:
The 5-Step Wizard
The Skill Forge follows the standard 5-step wizard pattern shared across all Living Failure forges.
Step 1: Setup
Configure the foundational settings for your skill database:
| Field | Description |
|---|---|
| Database Name | The name prefix for all generated files (e.g., ARPGSkills generates
ARPGSkillsType.cs, ARPGSkillsDatabase.cs, etc.) |
| Namespace | Optional C# namespace for generated code. Leave blank if your project does not use namespaces. |
| Class Prefix | Optional prefix for generated class names. Defaults to the database name. |
| Template | Genre template (ARPG, MOBA, MMO, TurnBased, Action, Roguelike, or None) to pre-populate property definitions at both skill-level and rank-level. |
| Linked Databases | Drag-and-drop ScriptableObject database assets from companion forges (SAF, SIF, SEF, SQF) to enable searchable dropdowns for cross-forge reference fields in Step 3. Also supports SAF Character Template assets for class restrictions. |
Step 2: Definitions
Define the dynamic property schema for your skills. This is where the two-level system comes into play. You define properties separately for:
- Skill-Level — Categories, Flags, Numerics, and Texts that apply to the skill as a whole
- Rank-Level — Categories, Flags, Numerics, and Texts that apply to each individual rank
Each property type is managed via a ReorderableList. Add, remove, reorder, and configure properties with full control. All existing skill entries are automatically synced when definitions change.
Step 2 also includes a JSON Schema section for AI-assisted content generation. Export your schema in 3 formats (Full JSON, Light JSON, Markdown) and import skills from JSON. See AI Workflow for details.
Step 3: Builder
The builder is a split-panel editor for creating and editing individual skills.
Left Panel — a scrollable list of all skills with:
- Search bar (filter by name or code)
- Category filter dropdown
- Sort options (alphabetical, by code, by category)
- Pagination for large lists
- Bulk select, delete, and duplicate
- Category type indicator badge (
[TypeName]) - + / - buttons for adding and removing skills
Right Panel — detail editor for the selected skill, organized into foldout sections:
- Identity — code (
SCREAMING_SNAKE_CASE), display name, description, icon (Sprite) - Categories — dropdown selectors for each skill-level category
- Flags — toggle checkboxes for each skill-level flag
- Numeric Properties — value fields for each skill-level numeric
- Text Properties — text fields for each skill-level text
- Ranks — nested rank entries, each with rank-level properties, upgrade costs, and modifier assets
- Prerequisites — unlock conditions (targetCode + comparison + value)
- Skill Modifiers — SAF modifier assets on the skill itself
- Cross-Forge References — 12 fields organized by companion forge
- Character Class Restrictions — allowed character classes
Step 4: Settings
Configure output paths and generation toggles:
- Output Path — folder for generated files (default:
Assets/GeneratedSkillDatabases/) - Use Custom Paths — separate folders for scripts and assets
- Generate Enum — toggle
{Prefix}Type.csgeneration - Generate Database — toggle database and editor generation
- File Preview — shows all files that will be created
Step 5: Generate
Review the summary and click Generate to produce your database. The generation uses a two-phase process:
.cs files (enum, database
class, custom editor). Unity triggers a domain reload to compile the new scripts.
[InitializeOnLoad] handler creates the .asset ScriptableObject and
populates it with all your skill data. GUID-based persistence ensures ScriptableObject references
survive the reload.
[InitializeOnLoad] handler to run after the
domain reload to complete Phase 2.
Property Types
Both skill-level and rank-level support 4 types of dynamic properties:
Categories
A selection from a named list of entries. Each category has a label and a list of string entries.
Flags
Boolean properties. Each flag has a name and a default value.
Numerics
Float or integer values with optional min/max constraints.
Texts
String values. Each text property has a name and a line count (1 = single line, >1 = multi-line TextArea).
Filtering by Properties
The database interface provides filtering methods for all property types:
Ranks and Upgrade Costs
Each skill can have multiple ranks representing progression levels. Ranks are stored
as SimpleSkillRank[] on the skill definition. Each rank has:
| Field | Type | Description |
|---|---|---|
rank |
int |
Rank number (starts at 1, not 0) |
categoryValues |
int[] |
Rank-level category values |
flagValues |
bool[] |
Rank-level flag values |
numericValues |
float[] |
Rank-level numeric values (damage, healing, etc.) |
textValues |
string[] |
Rank-level text values |
upgradeCosts |
SimpleSkillUpgradeCost[] |
Resources required to reach this rank |
modifiers |
ScriptableObject[] |
SAF modifier assets gained at this rank |
Upgrade Costs
Each rank can have multiple upgrade costs. An upgrade cost pairs a resource code with an amount:
The resourceCode is a free-form string. It can reference an item code from SIF, an
attribute code from SAF, or any custom identifier your game uses. The forge does not validate
the code — your game logic interprets it.
Querying Ranks
Reagent Costs vs. Upgrade Costs
SimpleSkillUpgradeCost (on each rank) represents
the cost to level up a skill to that rank. SimpleSkillReagentCost (on the skill
definition) represents items consumed each time the skill is cast. They are different systems.
Prerequisites
Skills can have prerequisites — conditions that must be met before the skill can be learned or used.
Each prerequisite is a SimpleSkillPrerequisite:
Prerequisites are evaluated using a Func<string, float> value provider — a
function you supply that returns the current value for any target code. This keeps the system
completely game-agnostic:
Common prerequisite patterns:
FIREBALL GreaterOrEqual 3— "Fireball must be at least rank 3"PLAYER_LEVEL GreaterOrEqual 10— "Character level 10 required"ICE_BOLT Equals 0— "Must not have learned Ice Bolt" (mutual exclusion)
Cross-Forge References
Each skill has 12 cross-forge reference fields that link skills to data from companion forges. All references are stored as string codes (no hard dependencies). The companion forge does not need to be installed for the data to be stored — it is just strings.
SIF (Simple Item Forge) — 4 Fields
| Field | Type | Description | Use Cases |
|---|---|---|---|
grantedByItemCode |
string |
Item that teaches/grants this skill | Skill books, scrolls, equipment passives, gem sockets |
requiredEquipmentCode |
string |
Item that must be equipped to use this skill | Bow for arrow skills, staff for magic, specific weapon types |
producesItemCode |
string |
Item created when the skill is used | Conjure food, crafting skills, transmutation, gathering yields |
reagentCosts[] |
SimpleSkillReagentCost[] |
Items consumed per cast | Arrows, soul shards, catalysts, reagents |
SEF (Simple Enemy Forge) — 5 Fields
| Field | Type | Description | Use Cases |
|---|---|---|---|
summonEnemyCode |
string |
Enemy summoned by this skill | Necromancer minions, pet classes, conjured creatures |
learnedFromEnemyCode |
string |
Enemy that teaches this skill | Blue Mage / FF, Enemy Skill materia, monster absorption |
taughtByNPCCode |
string |
NPC trainer that teaches this skill | Class trainers, skill masters, weapon trainers, move tutors |
effectiveAgainstFactions[] |
string[] |
Factions this skill is strong against | Holy vs Undead, Dragon Slayer vs Dragon, type advantages |
restrictedToFactionCode |
string |
Only characters of this faction can use the skill | Racial abilities, covenant skills, guild techniques |
SQF (Simple Quest Forge) — 2 Fields
| Field | Type | Description | Use Cases |
|---|---|---|---|
unlockedByQuestCode |
string |
Quest that must be completed to learn this skill | Class quests, weapon art quests, mastery trials |
rewardedByQuestCodes[] |
string[] |
Quests that award this skill as a reward | Reverse lookup for UI: "Learned from: The Archmage's Trial" |
SAF (Simple Attribute Forge) — 1 Field
| Field | Type | Description | Use Cases |
|---|---|---|---|
modifiers[] |
ScriptableObject[] |
SAF modifier assets attached to the skill itself | Passive effects, auras, stat modifications |
Additionally, each rank has its own modifiers[] array for effects
gained at specific ranks.
Convenience Accessors
The SimpleSkillDefinition struct provides boolean convenience properties for checking
whether cross-forge references are set:
Cross-Forge Queries
The ISimpleSkillDataSource interface provides reverse-lookup queries for all cross-forge fields:
Character Class Restrictions
Skills can be restricted to specific character classes using the allowedCharacterClasses
field. This integrates with SAF Character Templates — if you have character
template assets linked in Step 1, the wizard displays a checkbox list of available class names
in Step 3. You can also add class names manually.
An empty allowedCharacterClasses array means the skill is usable by all classes.
GetSkillsForClass("Mage") returns only skills that are
explicitly restricted to the Mage class. GetSkillsUsableByClass("Mage") returns
those plus all unrestricted skills (skills with an empty allowedCharacterClasses
array).
Overview
The Skill Tree Forge generates skill tree databases — grid-based talent trees where nodes reference skills from Skill Forge databases and are connected by directed parent-child edges. Each tree supports branch groups for specialization paths, point costs, level requirements, and single-level dynamic properties.
Generated databases implement ISimpleSkillTreeDataSource and produce the same 4-file
output as the Skill Forge (enum, database, editor, asset), with the suffix Tree
(e.g., ARPGTreeType.cs, ARPGTreeDatabase.cs).
Open the Skill Tree Forge wizard from the Unity menu:
Key features:
- Grid-based node layout with row/column positioning
- Parent-child connections enforcing unlock order
- Branch groups for specialization paths (e.g., "Fire", "Ice", "Lightning")
- Per-node point cost, required level, and required points in tree
- Nodes reference skill codes from any linked Skill Forge database
- Single-level dynamic properties on each tree
- Runtime tracker with unlock/reset/snapshot support
- Character class restrictions via SAF Character Templates
The 5-Step Wizard
The Skill Tree Forge follows the same 5-step wizard pattern as all forges.
Step 1: Setup
Configure the database name, namespace, class prefix, and template. The Skill Tree Forge adds a
Linked Skill Databases section where you drag-and-drop Skill Forge database assets.
Linking a skill database enables searchable dropdown menus for node skillCode fields
in Step 3. You can link multiple skill databases.
You can also link SAF Character Template assets for class restriction support.
ARPG generates ARPGTreeType,
ARPGTreeDatabase, etc.
Step 2: Definitions
Define single-level dynamic properties for your trees. Unlike the Skill Forge, there is no rank-level — properties apply to the tree definition itself (e.g., "Tree Type", "Total Point Cap", "Is Starter Tree"). The JSON schema export/import section is available for AI-assisted content generation.
Step 3: Builder
Split-panel editor (280px left panel). The left panel lists all tree definitions with search, filter, sort, bulk operations, and pagination. The right panel shows foldout sections for:
- Identity — code, display name, description, icon
- Categories / Flags / Numerics / Texts — single-level properties
- Nodes — ReorderableList of tree nodes (9 editable fields per node)
- Connections — ReorderableList of directed edges (from/to node dropdowns)
- Character Class Restrictions — allowed character classes
Step 4: Settings
Output paths, custom paths toggle, generation toggles, and file preview.
Step 5: Generate
Two-phase generation producing {Prefix}TreeType.cs,
{Prefix}TreeDatabase.cs, {Prefix}TreeDatabaseEditor.cs, and the
.asset file.
Nodes
Each tree contains an array of SimpleSkillTreeNode structs. A node represents a single
unlockable entry in the tree, referencing a skill from a linked Skill Forge database.
| Field | Type | Description |
|---|---|---|
nodeId |
int |
Unique identifier within this tree (auto-assigned) |
skillCode |
string |
Skill code referencing a Skill Forge database entry |
row |
int |
Row position in the tree grid (for visual layout) |
column |
int |
Column position in the tree grid (for visual layout) |
pointCost |
int |
Skill points required to unlock this node |
requiredLevel |
int |
Minimum character level required to unlock this node |
requiredPointsInTree |
int |
Minimum total points already spent in this tree to unlock |
branchGroup |
string |
Specialization path identifier (e.g., "Fire", "Ice"). Nodes with the same branchGroup form a specialization track. Empty = no specific branch. |
isRequired |
bool |
Whether this node must be unlocked to proceed further down its branch |
Querying Nodes
Connections
Connections are directed edges (SimpleSkillTreeConnection) that define parent-child
unlock dependencies between nodes. A child node cannot be unlocked until all parent nodes are
unlocked.
| Field | Type | Description |
|---|---|---|
fromNodeId |
int |
Parent node ID (must be unlocked first) |
toNodeId |
int |
Child node ID (unlockable after parent) |
Querying Connections
Single-Level Properties
Skill trees use single-level dynamic properties (Categories, Flags, Numerics, Texts) on the tree definition itself. There is no child-level like the Skill Forge's rank-level properties.
Runtime: SimpleSkillTreeTracker
SimpleSkillTreeTracker is a runtime state tracker that manages skill tree node unlocks,
point spending, prerequisite validation, cascade resets, and serializable snapshots.
Setup
Unlocking Nodes
UnlockNode tracks points spent internally
(for requiredPointsInTree validation) but does not deduct from a
player point balance. Your game code is responsible for checking and deducting available points
before calling UnlockNode.
Queries
Reset
Events
Snapshots (Save/Load)
Overview
The Skill Set Forge generates skill set databases — loadout templates that group skills into typed slots with threshold-based set bonuses that activate when enough skills from the set are equipped. Think item set bonuses from Diablo or gear sets from MMOs, but applied to skills.
Generated databases implement ISimpleSkillSetDataSource and produce the standard 4-file
output with the suffix Set (e.g., ARPGSetType.cs,
ARPGSetDatabase.cs).
Open the Skill Set Forge wizard from the Unity menu:
Key features:
- Typed slots with required/optional designation
- Skill code references from linked Skill Forge databases
- Threshold-based set bonuses (e.g., "Equip 3/5 for bonus")
- SAF modifier assets on bonuses
- Single-level dynamic properties on each set
- Runtime manager with equip/unequip, bonus tracking, and snapshots
- Character class restrictions via SAF Character Templates
The 5-Step Wizard
The Skill Set Forge follows the same 5-step wizard pattern as all forges.
Step 1: Setup
Configure the database name, namespace, class prefix, and template. Link Skill Forge database assets for searchable skill code dropdowns in Step 3. Link SAF Character Template assets for class restriction support. Supports multiple linked databases with duplicate detection.
Step 2: Definitions
Define single-level dynamic properties for your sets (e.g., "Set Type", "Max Slots", "Is Starter Set"). JSON schema export/import is available for AI-assisted content generation with context-aware usage hints.
Step 3: Builder
Split-panel editor (280px left panel). The right panel shows foldout sections for:
- Identity — code, display name, description, icon
- Categories / Flags / Numerics / Texts — single-level properties
- Slots — ReorderableList with 3 fields per slot (slotType, skillCode, isRequired)
- Bonuses — ReorderableList with threshold count, description, and SAF modifier assets
- Character Class Restrictions — allowed character classes
Step 4: Settings
Output paths, custom paths toggle, generation toggles, and file preview.
Step 5: Generate
Two-phase generation producing {Prefix}SetType.cs,
{Prefix}SetDatabase.cs, {Prefix}SetDatabaseEditor.cs, and the
.asset file with all slot, bonus, and modifier data baked in.
Slots
Each set contains an array of SimpleSkillSetSlot structs. A slot defines a position
in the loadout with a type label, an assigned skill code, and a required flag.
| Field | Type | Description |
|---|---|---|
slotType |
string |
Slot type label (e.g., "Active1", "Active2", "Passive1", "Ultimate"). Used for categorizing and filtering slots. Free-form string — your game defines the slot type conventions. |
skillCode |
string |
Skill code referencing a Skill Forge database entry. In the wizard, this is presented as a searchable dropdown when skill databases are linked. |
isRequired |
bool |
Whether this slot must be filled for the set to be considered valid. Optional slots can be left empty at runtime. |
Querying Slots
Bonuses
Each set can have multiple SimpleSkillSetBonus entries that activate when enough
skills from the set are equipped. This follows the same threshold pattern as item set bonuses.
| Field | Type | Description |
|---|---|---|
requiredCount |
int |
Number of equipped skills from this set required to activate the bonus |
bonusDescription |
string |
Human-readable description of the bonus effect (e.g., "+20% fire damage") |
modifiers[] |
ScriptableObject[] |
SAF modifier assets applied when this bonus is active. Requires Simple Attribute Forge to be installed for the modifier assets — the field still exists without SAF, but modifiers will be empty. |
Querying Bonuses
Example: Tiered Bonuses
A set with 5 slots might define bonuses like this:
| Required Count | Bonus Description |
|---|---|
| 2 | +10% fire damage |
| 3 | +20% fire damage, fire skills cost 15% less mana |
| 5 | +50% fire damage, all fire skills gain area of effect |
With 3 skills equipped, both the "2-piece" and "3-piece" bonuses are active.
GetActiveBonuses(3) returns both.
Single-Level Properties
Skill sets use single-level dynamic properties on the set definition itself.
Runtime: SimpleSkillBarManager
SimpleSkillBarManager is a runtime manager that handles equipping/unequipping skills
to set slots, tracks threshold-based set bonuses, fires events on changes, and supports
serializable snapshots for save/load.
Setup
Equip and Unequip
OnSkillUnequipped
and OnSkillEquipped events fire.
Queries
Events
Snapshots (Save/Load)
Overview
The Skill Combo Forge generates skill combo databases — sequential skill chains where players execute skills in a specific order to earn threshold-based rewards. Each combo defines ordered steps with timing windows, alternate skill choices, and branch groups, plus rewards that trigger at step count thresholds.
Generated databases implement ISimpleSkillComboDataSource and produce the standard 4-file
output with the suffix Combo (e.g., ARPGComboType.cs,
ARPGComboDatabase.cs).
Open the Skill Combo Forge wizard from the Unity menu:
Key features:
- Ordered steps with
sortOrdersequencing - Required and optional steps
- Alternate skill choices per step (
alternateSkillCodes[]) - Branch groups for OR-alternative step paths
- Per-step timing windows (
maxDelayin seconds) - Threshold-based rewards with SAF modifier assets
- Single-level dynamic properties on each combo
- Runtime tracker for automatic combo detection and progression
- Static evaluator for stateless combo analysis
- Character class restrictions via SAF Character Templates
The 5-Step Wizard
The Skill Combo Forge follows the same 5-step wizard pattern as all forges.
Step 1: Setup
Configure the database name, namespace, class prefix, and template. Link Skill Forge database assets for searchable skill code dropdowns in Step 3. Link SAF Character Template assets for class restriction support.
Step 2: Definitions
Define single-level dynamic properties for your combos (e.g., "Combo Type", "Element", "Damage Multiplier", "Is Finisher"). JSON schema export/import with context-aware usage hints and 5 combo design patterns (Chain Combo, Rotation, Reaction Chain, Hit String, Synergy Set).
Step 3: Builder
Split-panel editor (280px left panel). The right panel shows foldout sections for:
- Identity — code, display name, description, icon
- Categories / Flags / Numerics / Texts — single-level properties
- Steps — ReorderableList with 6 fields per step (skillCode, isRequired, alternateSkillCodes mini-list, branchGroup, maxDelay, sortOrder)
- Rewards — ReorderableList with threshold count, description, effect code, and SAF modifier assets
- Character Class Restrictions — allowed character classes
Step 4: Settings
Output paths, custom paths toggle, generation toggles, and file preview.
Step 5: Generate
Two-phase generation producing {Prefix}ComboType.cs,
{Prefix}ComboDatabase.cs, {Prefix}ComboDatabaseEditor.cs, and the
.asset file with all step, reward, and modifier data baked in.
Steps
Each combo contains an array of SimpleSkillComboStep structs, sorted by
sortOrder at runtime. A step defines a single position in the combo sequence.
| Field | Type | Description |
|---|---|---|
skillCode |
string |
Primary skill code that satisfies this step |
isRequired |
bool |
Whether this step must be hit or can be skipped. Optional steps are automatically skipped if the player uses a skill matching a later required step. |
alternateSkillCodes[] |
string[] |
Additional skill codes that also satisfy this step. Any of these (or the
primary skillCode) will advance the combo. |
branchGroup |
string |
Steps in the same branch group are OR alternatives — only one needs to be completed. Empty = no branch group. |
maxDelay |
float |
Maximum seconds allowed before the next step must be hit. If the player waits longer, the combo drops. 0 = no time limit. |
sortOrder |
int |
Determines the execution order of steps within the combo. Lower values go first. Steps are sorted by this field at runtime. |
Querying Steps
Example: Elemental Burst Combo
| Sort Order | Skill Code | Required | Alternates | Max Delay |
|---|---|---|---|---|
| 0 | FIREBALL | Yes | — | 0 (no limit) |
| 1 | ICE_BOLT | Yes | FROST_NOVA | 2.0 sec |
| 2 | LIGHTNING_STRIKE | Yes | — | 2.0 sec |
| 3 | ARCANE_BLAST | No (optional) | — | 3.0 sec |
The player must cast Fireball, then Ice Bolt (or Frost Nova) within 2 seconds, then Lightning Strike within 2 more seconds. The optional Arcane Blast at the end earns a bonus reward if hit within 3 seconds but is not required for combo completion.
Rewards
Each combo can have multiple SimpleSkillComboReward entries that trigger when enough
steps are completed. This follows the same threshold pattern as set bonuses.
| Field | Type | Description |
|---|---|---|
requiredSteps |
int |
Number of completed steps required to earn this reward |
rewardDescription |
string |
Human-readable description (e.g., "Elemental Overload: +50% elemental damage for 5s") |
effectCode |
string |
Game-specific effect identifier for your code to interpret |
modifiers[] |
ScriptableObject[] |
SAF modifier assets applied when this reward triggers |
Querying Rewards
Example: Tiered Rewards
| Required Steps | Reward | Effect Code |
|---|---|---|
| 2 | Elemental Resonance: +20% elemental damage for 3s | ELEM_RESONANCE |
| 3 | Elemental Overload: +50% elemental damage for 5s, AoE explosion | ELEM_OVERLOAD |
| 4 | Elemental Mastery: Full elemental damage for 8s, reset all cooldowns | ELEM_MASTERY |
Each tier stacks — completing 3 steps earns both the 2-step and 3-step rewards.
Single-Level Properties
Skill combos use single-level dynamic properties on the combo definition itself.
Runtime: SimpleSkillComboTracker
SimpleSkillComboTracker tracks active skill combos at runtime. Feed skill usage
into the tracker and it automatically evaluates all defined combos simultaneously — starting
new combos when a matching first step is detected, progressing active combos on subsequent matches,
dropping combos when timing windows expire, and triggering rewards at thresholds.
Setup
Feeding Skill Usage
Each call to OnSkillUsed does the following:
- Checks timing windows on all active combos (drops expired ones)
- Advances active combos if the skill matches their next step
- Skips optional steps when the skill matches a later required step
- Triggers rewards when step thresholds are reached
- Completes combos when all steps are matched
- Starts new combos if the skill matches any inactive combo's first step
Queries
Events
Snapshots (Save/Load)
Runtime: SimpleSkillComboEvaluator
SimpleSkillComboEvaluator is a static utility class for evaluating
combos without instantiating a tracker. All methods are stateless pure functions — useful for
UI previews, combo planning, AI decision-making, and tooltip generation.
Evaluating a Combo
Getting Next Valid Skills
This is especially useful for UI hints ("Cast one of these skills to continue the combo") and AI skill selection.
Finding Matching Combos
Quick Checks
Tracker vs. Evaluator
| Feature | SimpleSkillComboTracker | SimpleSkillComboEvaluator |
|---|---|---|
| Type | Instance class (stateful) | Static class (stateless) |
| Tracks multiple combos simultaneously | Yes | No (one-at-a-time evaluation) |
| Timing windows | Yes (automatic drop on expiry) | No |
| Events | Yes (started, progressed, completed, dropped, reward) | No |
| Snapshots | Yes (save/load) | No |
| Use case | Live gameplay combo tracking | UI previews, tooltips, AI planning |
AI-Assisted Content Generation
All 4 forges support schema export in Step 2 (Definitions). Export your property schema with embedded AI instructions, hand it to ChatGPT, Claude, or any LLM, and import the generated content back into your database — all without writing code.
This workflow lets you:
- Generate hundreds of skills/trees/sets/combos from a single prompt
- Maintain consistency with your property schema (AI can only use your defined properties)
- Iterate rapidly on content design before committing to implementation
- Use AI as a creative partner for brainstorming skill concepts
Export Formats
Each forge offers 3 export formats:
| Format | Best For | Content |
|---|---|---|
| Full JSON | Structured AI input, programmatic processing | Complete schema + definitions + existing entries + AI instructions as JSON |
| Light JSON | Quick AI prompts, smaller context windows | Schema + definitions + AI instructions (no existing entries) |
| Markdown | Human-readable, documentation, wiki | Schema + definitions formatted as Markdown tables + AI instructions |
Export Workflow
Embedded AI Instructions
The exported file includes a BuildInstructions section (600+ lines for the Skill Forge)
that teaches the AI everything it needs to know:
- Property system explanation — how Categories, Flags, Numerics, and Texts work at both skill-level and rank-level
- Ecosystem description — all 7 forge systems and how they connect
- User questions — 7-step questionnaire for the AI to ask the user about their game
- Per-property guidance — context-aware usage hints for each defined property
- Skill archetype patterns — 8 common skill types with design guidance
- Rank progression patterns — how to design meaningful rank upgrades
- Format examples — exact JSON structure using your actual definitions
- 5-phase workflow — structured process for the AI to follow
- Cross-forge awareness — what data is available from companion packages
Import Workflow
- Replace — delete all existing entries and import only the new ones
- Keep — keep existing entries and add new ones (skip duplicates by code)
- Cancel — abort the import
The import validates each entry: codes must be unique C# identifiers, property arrays must match your defined schema length, and required fields (code, displayName) must be present.
Tips for AI Generation
Be Specific About Your Game
Tell the AI what kind of game you're making. "Generate ARPG skills" produces generic results. "Generate skills for a dark fantasy ARPG where the player is a fallen angel regaining divine powers" produces much more interesting content.
Use the Full JSON Format
The Full JSON export includes your existing entries as examples. This gives the AI concrete patterns to follow, resulting in more consistent output.
Generate in Batches
Ask for 10–20 entries at a time rather than 100+. Smaller batches give the AI more room to be creative and reduce the chance of repetitive content.
Iterate on Definitions First
Before generating content, make sure your property definitions are finalized. Changing definitions after importing 200 skills means all those skills need to be re-synced.
Review and Edit
AI-generated content is a starting point. Use the builder in Step 3 to review, edit, and refine each entry. The split-panel editor with search, sort, and filter makes this efficient.
Genre Templates
All 4 forges ship with 6 genre templates that pre-populate property definitions with genre-appropriate Categories, Flags, Numerics, and Texts. Templates are a starting point — you can modify, add, or remove any property after applying a template.
Select a template in Step 1 (Setup) of any wizard. Choosing "None" starts with a blank slate. Changing templates after defining entries will prompt for confirmation, since it replaces all property definitions.
ARPG Template
Designed for action RPGs (Diablo, Path of Exile, Last Epoch). Emphasizes damage types, resource management, and scaling per rank.
Skill-Level Properties (Skill Forge)
| Type | Name | Details |
|---|---|---|
| Category | Skill Type | Attack, Spell, Buff, Debuff, Passive, Movement, Summon, Aura |
| Category | Element | Physical, Fire, Ice, Lightning, Poison, Holy, Dark, Arcane |
| Category | Target Type | Self, Single Target, AoE, Cone, Line, Chain, Global |
| Flag | Is Passive | Default: false |
| Flag | Is Ultimate | Default: false |
| Numeric | Base Cooldown | Seconds |
| Numeric | Mana Cost | Base resource cost |
| Text | Lore | Flavor text |
Rank-Level Properties (Skill Forge)
| Type | Name | Details |
|---|---|---|
| Numeric | Damage | Per-rank damage value |
| Numeric | Duration | Effect duration in seconds |
| Numeric | Cooldown Reduction | Percentage reduction per rank |
MOBA Template
Designed for MOBAs (League of Legends, Dota 2). Focuses on ability scaling, lane impact, and team synergy.
Skill-level categories include Lane Phase (Early, Mid, Late), Role Fit (Carry, Support, Tank, Assassin, Mage, Bruiser), and Crowd Control type. Rank-level numerics emphasize per-level scaling values and cooldown reduction.
MMO Template
Designed for MMOs (World of Warcraft, Final Fantasy XIV). Emphasizes class identity, raid roles, and resource management.
Skill-level categories include Skill Category (Core, Talent, Racial, Profession), Resource Type (Mana, Energy, Rage, Focus, Combo Points), and Cast Type (Instant, Channeled, Cast Time, Toggle). Rank-level properties track per-rank GCD modifications and resource cost scaling.
Turn-Based Template
Designed for turn-based RPGs (Final Fantasy, Persona, Fire Emblem). Focuses on action economy, turn order, and elemental weakness systems.
Skill-level categories include Action Cost (Free, Half Turn, Full Turn, Multi-Turn), Element, and Range. Flags include "Consumes Turn" and "Can Counter". Rank numerics track hit rate, critical rate, and accuracy bonuses.
Action Template
Designed for action games (Devil May Cry, Bayonetta, God of War). Emphasizes combo potential, input complexity, and style scoring.
Skill-level categories include Input Type (Press, Hold, Charge, Direction+Press), Attack Type (Light, Heavy, Launcher, Slam, Projectile), and Cancel Window. Flags include "Can Air Cancel" and "Has Super Armor". Rank numerics include "Hit Count" and "Style Points".
Roguelike Template
Designed for roguelikes (Hades, Slay the Spire, Dead Cells). Emphasizes run synergies, randomized upgrades, and resource efficiency.
Skill-level categories include Rarity (Common, Uncommon, Rare, Epic, Legendary), Synergy Tag (multiple synergy groups), and Acquisition (Starter, Shop, Drop, Boss Reward, Secret). Flags include "Stackable" and "Removable". Rank numerics track "Stack Multiplier" and "Trigger Chance".
Customizing Templates
After applying a template, you can freely:
- Add new categories, flags, numerics, or texts
- Remove any property you don't need
- Rename labels and entries
- Reorder properties (drag handles in the ReorderableList)
- Add category entries to existing categories
All changes in Step 2 automatically sync to existing entries in Step 3. New properties get default values; removed properties are cleaned up.
Data Structures
All runtime data structures live in the SimpleSkillForge namespace and are
[Serializable] structs. The Skill Forge uses a two-level property
system (skill-level + rank-level), while the Tree, Set, and Combo forges use single-level properties.
SimpleSkillDefinition
The main skill entry. Contains identity, two-level dynamic properties, nested ranks, prerequisites, modifier references, and 12 cross-forge reference fields.
Identity Fields
| Field | Type | Description |
|---|---|---|
code | string | Unique identifier (SCREAMING_SNAKE_CASE) |
displayName | string | Human-readable name |
description | string | Skill description text |
icon | Sprite | Skill icon |
Skill-Level Dynamic Properties (Level 1)
| Field | Type | Description |
|---|---|---|
categoryValues | int[] | Category indices (one per category definition) |
flagValues | bool[] | Boolean flags (one per flag definition) |
numericValues | float[] | Numeric values (one per numeric definition) |
textValues | string[] | Text values (one per text definition) |
Nested Data
| Field | Type | Description |
|---|---|---|
ranks | SimpleSkillRank[] | Per-rank data with Level 2 properties |
prerequisites | SimpleSkillPrerequisite[] | Unlock conditions |
modifiers | ScriptableObject[] | SAF modifier assets (passive effects) |
Cross-Forge References: SIF (Item Forge)
| Field | Type | Description |
|---|---|---|
grantedByItemCode | string | Item that teaches/grants this skill (skill books, scrolls, equipment passives) |
requiredEquipmentCode | string | Item that must be equipped to use this skill (weapon requirements) |
producesItemCode | string | Item created when this skill is used (conjure food, crafting skills) |
reagentCosts | SimpleSkillReagentCost[] | Items consumed per cast (arrows, soul shards, catalysts) |
Cross-Forge References: SEF (Enemy Forge)
| Field | Type | Description |
|---|---|---|
summonEnemyCode | string | Enemy summoned by this skill (necromancer minions, pet classes) |
learnedFromEnemyCode | string | Enemy that teaches this skill (Blue Mage, monster absorption) |
taughtByNPCCode | string | NPC trainer that teaches this skill (class trainers, skill masters) |
effectiveAgainstFactions | string[] | Factions this skill is strong against (Holy vs Undead, type advantages) |
restrictedToFactionCode | string | Only characters of this faction can use this skill |
Cross-Forge References: SQF (Quest Forge)
| Field | Type | Description |
|---|---|---|
unlockedByQuestCode | string | Quest that must be completed to learn this skill |
rewardedByQuestCodes | string[] | Quests that award this skill as a reward |
Cross-Forge References: SAF Character Templates
| Field | Type | Description |
|---|---|---|
allowedCharacterClasses | string[] | Character class names this skill is restricted to. Empty = usable by all classes. |
Accessor Methods
| Method | Returns | Description |
|---|---|---|
GetCategoryValue(int index) | int | Safe category access (returns 0 if out of range) |
GetFlagValue(int index) | bool | Safe flag access (returns false if out of range) |
GetNumericValue(int index) | float | Safe numeric access (returns 0f if out of range) |
GetTextValue(int index) | string | Safe text access (returns "" if out of range) |
GetMaxRank() | int | Returns the maximum rank number defined for this skill |
GetRank(int rankNumber) | SimpleSkillRank? | Returns rank data for a specific rank number, or null |
Convenience Properties
| Property | Type | Description |
|---|---|---|
IsItemGranted | bool | True if grantedByItemCode is set |
HasEquipmentRequirement | bool | True if requiredEquipmentCode is set |
ProducesItem | bool | True if producesItemCode is set |
HasReagentCosts | bool | True if reagentCosts has entries |
IsSummonSkill | bool | True if summonEnemyCode is set |
IsEnemyLearned | bool | True if learnedFromEnemyCode is set |
HasTrainer | bool | True if taughtByNPCCode is set |
HasFactionEffectiveness | bool | True if effectiveAgainstFactions has entries |
IsFactionRestricted | bool | True if restrictedToFactionCode is set |
IsQuestUnlocked | bool | True if unlockedByQuestCode is set |
IsQuestRewarded | bool | True if rewardedByQuestCodes has entries |
HasClassRestriction | bool | True if allowedCharacterClasses has entries |
Query Methods
| Method | Returns | Description |
|---|---|---|
IsUsableByClass(string className) | bool | True if unrestricted or className is in allowedCharacterClasses |
IsEffectiveAgainst(string factionCode) | bool | True if factionCode is in effectiveAgainstFactions |
IsRewardedByQuest(string questCode) | bool | True if questCode is in rewardedByQuestCodes |
SimpleSkillRank
A single rank of a skill. Each rank has its own rank-level dynamic properties (Level 2), upgrade costs, and optional SAF modifier references.
| Field | Type | Description |
|---|---|---|
rank | int | Rank number (starts at 1, not an index) |
categoryValues | int[] | Rank-level category indices |
flagValues | bool[] | Rank-level boolean flags |
numericValues | float[] | Rank-level numeric values |
textValues | string[] | Rank-level text values |
upgradeCosts | SimpleSkillUpgradeCost[] | Resources required to reach this rank |
modifiers | ScriptableObject[] | SAF modifier assets gained at this rank |
Accessor Methods
| Method | Returns | Description |
|---|---|---|
GetCategoryValue(int index) | int | Safe category access (returns 0 if out of range) |
GetFlagValue(int index) | bool | Safe flag access (returns false if out of range) |
GetNumericValue(int index) | float | Safe numeric access (returns 0f if out of range) |
GetTextValue(int index) | string | Safe text access (returns "" if out of range) |
SimpleSkillUpgradeCost
A resource cost for upgrading a skill to a specific rank. The resourceCode can reference an item code (SIF), attribute code (SAF), or any custom string.
| Field | Type | Description |
|---|---|---|
resourceCode | string | Identifier of the required resource |
amount | float | Quantity required |
SimpleSkillReagentCost
An item consumed each time the skill is used. Different from SimpleSkillUpgradeCost which is for leveling/ranking up.
| Field | Type | Description |
|---|---|---|
itemCode | string | Item code consumed per cast |
amount | int | Quantity consumed per cast |
SimpleSkillPrerequisite
A prerequisite condition for unlocking a skill. Evaluated as:
valueProvider(targetCode) [comparison] value
| Field | Type | Description |
|---|---|---|
targetCode | string | Code to evaluate (skill code, attribute code, quest code, or custom) |
comparison | SimpleSkillComparison | Comparison operator |
value | float | Threshold value to compare against |
SimpleSkillComparison (enum)
Comparison operators for prerequisite evaluation.
| Value | Meaning |
|---|---|
Equals | Current value equals target (using Mathf.Approximately) |
NotEquals | Current value does not equal target |
GreaterThan | Current value is greater than target |
LessThan | Current value is less than target |
GreaterOrEqual | Current value is greater than or equal to target |
LessOrEqual | Current value is less than or equal to target |
SimpleSkillTreeDefinition
A complete skill tree with identity, nodes, connections, and single-level dynamic properties.
Fields
| Field | Type | Description |
|---|---|---|
code | string | Unique identifier |
displayName | string | Human-readable name |
description | string | Tree description text |
icon | Sprite | Tree icon |
nodes | SimpleSkillTreeNode[] | All nodes in this tree |
connections | SimpleSkillTreeConnection[] | Directed edges between nodes |
categoryValues | int[] | Category indices |
flagValues | bool[] | Boolean flags |
numericValues | float[] | Numeric values |
textValues | string[] | Text values |
allowedCharacterClasses | string[] | Class restrictions (empty = unrestricted) |
Accessor Methods
| Method | Returns | Description |
|---|---|---|
GetCategoryValue(int index) | int | Safe category access (returns -1 if out of range) |
GetFlagValue(int index) | bool | Safe flag access (returns false if out of range) |
GetNumericValue(int index) | float | Safe numeric access (returns 0f if out of range) |
GetTextValue(int index) | string | Safe text access (returns "" if out of range) |
GetNodeById(int nodeId) | SimpleSkillTreeNode? | Find a node by its ID, or null |
GetNodesInBranch(string branchGroup) | SimpleSkillTreeNode[] | Get all nodes in a branch group |
GetBranchGroups() | string[] | Get all unique branch group names |
GetConnectionsFrom(int nodeId) | SimpleSkillTreeConnection[] | Get connections from a node (children) |
GetConnectionsTo(int nodeId) | SimpleSkillTreeConnection[] | Get connections to a node (parents) |
GetParentNodeIds(int nodeId) | int[] | Get parent node IDs |
GetChildNodeIds(int nodeId) | int[] | Get child node IDs |
GetRootNodes() | SimpleSkillTreeNode[] | Get nodes with no parent connections |
ContainsSkill(string skillCode) | bool | Check if any node references this skill code |
IsAvailableToClass(string className) | bool | True if unrestricted or className is allowed |
Convenience Properties
| Property | Type | Description |
|---|---|---|
NodeCount | int | Number of nodes |
ConnectionCount | int | Number of connections |
HasClassRestriction | bool | True if allowedCharacterClasses has entries |
SimpleSkillTreeNode
A single node in a skill tree. References a skill code and defines grid position, unlock requirements, and branch membership.
| Field | Type | Description |
|---|---|---|
nodeId | int | Unique identifier within this tree |
skillCode | string | Skill code from a linked Skill Forge database |
row | int | Row position in the tree grid (visual layout) |
column | int | Column position in the tree grid (visual layout) |
pointCost | int | Skill points required to unlock this node |
requiredLevel | int | Minimum character level required |
requiredPointsInTree | int | Minimum total points spent in this tree to unlock |
branchGroup | string | Specialization path identifier (e.g., "Fire", "Ice"). Empty = no branch. |
isRequired | bool | Must this node be unlocked to proceed down the branch? |
SimpleSkillTreeConnection
A directed edge in a skill tree: parent to child unlock dependency. The child node cannot be unlocked until the parent is unlocked.
| Field | Type | Description |
|---|---|---|
fromNodeId | int | Source node ID (must be unlocked first) |
toNodeId | int | Target node ID (unlockable after parent) |
SimpleSkillSetDefinition
A complete skill set with identity, slots, threshold-based bonuses, and single-level dynamic properties.
Fields
| Field | Type | Description |
|---|---|---|
code | string | Unique identifier |
displayName | string | Human-readable name |
description | string | Set description text |
icon | Sprite | Set icon |
slots | SimpleSkillSetSlot[] | Typed skill slots |
bonuses | SimpleSkillSetBonus[] | Threshold-based set bonuses |
categoryValues | int[] | Category indices |
flagValues | bool[] | Boolean flags |
numericValues | float[] | Numeric values |
textValues | string[] | Text values |
allowedCharacterClasses | string[] | Class restrictions (empty = unrestricted) |
Accessor Methods
| Method | Returns | Description |
|---|---|---|
GetCategoryValue(int index) | int | Safe category access (returns -1 if out of range) |
GetFlagValue(int index) | bool | Safe flag access |
GetNumericValue(int index) | float | Safe numeric access |
GetTextValue(int index) | string | Safe text access |
GetSlotTypes() | string[] | Get all unique slot type labels |
GetSlotsByType(string slotType) | SimpleSkillSetSlot[] | Get all slots of a specific type |
ContainsSkill(string skillCode) | bool | Check if any slot references this skill code |
GetSkillCodes() | string[] | Get all non-empty skill codes from slots |
GetBonusForCount(int equippedCount) | SimpleSkillSetBonus? | Get the highest-threshold bonus for a given count |
GetActiveBonuses(int equippedCount) | SimpleSkillSetBonus[] | Get all bonuses active for a given count |
IsAvailableToClass(string className) | bool | True if unrestricted or className is allowed |
Convenience Properties
| Property | Type | Description |
|---|---|---|
SlotCount | int | Number of slots |
BonusCount | int | Number of bonuses |
RequiredSlotCount | int | Number of required slots |
HasClassRestriction | bool | True if allowedCharacterClasses has entries |
SimpleSkillSetSlot
A single slot in a skill set, with a type label, skill reference, and required flag.
| Field | Type | Description |
|---|---|---|
slotType | string | Slot type label (e.g., "Active1", "Passive1", "Ultimate") |
skillCode | string | Skill code from a linked Skill Forge database |
isRequired | bool | Whether this slot must be filled for the set to be valid |
SimpleSkillSetBonus
A threshold-based bonus that activates when enough skills from the set are equipped.
| Field | Type | Description |
|---|---|---|
requiredCount | int | Number of equipped skills required to activate |
bonusDescription | string | Human-readable description of the bonus effect |
modifiers | ScriptableObject[] | SAF modifier assets applied when this bonus activates |
SimpleSkillComboDefinition
A complete skill combo with identity, ordered steps, threshold-based rewards, and single-level dynamic properties.
Fields
| Field | Type | Description |
|---|---|---|
code | string | Unique identifier |
displayName | string | Human-readable name |
description | string | Combo description text |
icon | Sprite | Combo icon |
steps | SimpleSkillComboStep[] | Ordered steps in the combo sequence |
rewards | SimpleSkillComboReward[] | Threshold-based rewards |
categoryValues | int[] | Category indices |
flagValues | bool[] | Boolean flags |
numericValues | float[] | Numeric values |
textValues | string[] | Text values |
allowedCharacterClasses | string[] | Class restrictions (empty = unrestricted) |
Accessor Methods
| Method | Returns | Description |
|---|---|---|
GetCategoryValue(int index) | int | Safe category access (returns -1 if out of range) |
GetFlagValue(int index) | bool | Safe flag access |
GetNumericValue(int index) | float | Safe numeric access |
GetTextValue(int index) | string | Safe text access |
GetStepByIndex(int index) | SimpleSkillComboStep? | Get step by index, or null if out of range |
ContainsSkill(string skillCode) | bool | Check if any step references this skill (primary or alternates) |
GetAllSkillCodes() | string[] | Get all unique skill codes from all steps |
GetActiveRewards(int completedStepCount) | SimpleSkillComboReward[] | Get rewards active for a given step count |
FindStepsBySkillCode(string skillCode) | SimpleSkillComboStep[] | Find all steps matching a skill code (primary or alternates) |
IsAvailableToClass(string className) | bool | True if unrestricted or className is allowed |
Convenience Properties
| Property | Type | Description |
|---|---|---|
StepCount | int | Number of steps |
RewardCount | int | Number of rewards |
HasClassRestriction | bool | True if allowedCharacterClasses has entries |
SimpleSkillComboStep
A single step in a combo chain, with a primary skill, alternates, branch grouping, and timing.
| Field | Type | Description |
|---|---|---|
skillCode | string | Primary skill code for this step |
isRequired | bool | Must this step be hit, or can it be skipped? |
alternateSkillCodes | string[] | Alternative skill codes that also satisfy this step |
branchGroup | string | Steps in the same branch group are OR alternatives |
maxDelay | float | Max seconds before the combo drops (0 = no limit) |
sortOrder | int | Sort order for step sequencing |
SimpleSkillComboReward
A threshold-based reward that activates when enough combo steps are completed.
| Field | Type | Description |
|---|---|---|
requiredSteps | int | Number of completed steps required to earn this reward |
rewardDescription | string | Human-readable description of the reward effect |
effectCode | string | Game-specific effect identifier |
modifiers | ScriptableObject[] | SAF modifier assets applied when this reward triggers |
Interfaces
Each forge generates a ScriptableObject database class that implements one of these interfaces. Cast your generated database asset to the interface for type-safe access.
ISimpleSkillDataSource
Interface for generated skill databases. Supports two-level dynamic properties (skill-level + rank-level).
Skill Access
| Member | Returns | Description |
|---|---|---|
SkillCount | int | Total number of skills |
GetSkillDefinitions() | SimpleSkillDefinition[] | All skill definitions |
GetSkillByCode(string code) | SimpleSkillDefinition? | Skill by code, or null |
GetSkillCodes() | string[] | All skill codes |
GetSkillNames() | string[] | All skill display names |
HasSkill(string code) | bool | Check if a skill exists |
GetSkillEnumType() | Type | The generated enum type for skill codes |
Rank Access
| Method | Returns | Description |
|---|---|---|
GetRanksForSkill(string skillCode) | SimpleSkillRank[] | All ranks for a skill |
GetMaxRank(string skillCode) | int | Max rank number for a skill |
Skill-Level Property Definitions (Level 1)
| Method | Returns | Description |
|---|---|---|
GetCategoryLabels() | string[] | Labels for skill-level categories |
GetCategoryEntries(int index) | string[] | Entries for a skill-level category |
GetFlagNames() | string[] | Names of skill-level flags |
GetNumericNames() | string[] | Names of skill-level numerics |
GetTextNames() | string[] | Names of skill-level texts |
Rank-Level Property Definitions (Level 2)
| Method | Returns | Description |
|---|---|---|
GetRankCategoryLabels() | string[] | Labels for rank-level categories |
GetRankCategoryEntries(int index) | string[] | Entries for a rank-level category |
GetRankFlagNames() | string[] | Names of rank-level flags |
GetRankNumericNames() | string[] | Names of rank-level numerics |
GetRankTextNames() | string[] | Names of rank-level texts |
Dynamic Filtering
| Method | Returns | Description |
|---|---|---|
GetSkillsByCategory(int categoryIndex, int entryIndex) | SimpleSkillDefinition[] | Skills matching a category value |
GetSkillsByFlag(int flagIndex, bool value) | SimpleSkillDefinition[] | Skills matching a flag value |
GetSkillsByNumericRange(int numericIndex, float min, float max) | SimpleSkillDefinition[] | Skills with a numeric in the given range |
Cross-Reference Queries
| Method | Returns | Description |
|---|---|---|
GetSkillsWithPrerequisite(string targetCode) | SimpleSkillDefinition[] | Skills requiring a specific target code |
GetSkillsWithUpgradeCost(string resourceCode) | SimpleSkillDefinition[] | Skills using a resource in any rank's upgrade costs |
Cross-Forge Queries: SIF
| Method | Returns | Description |
|---|---|---|
GetSkillsGrantedByItem(string itemCode) | SimpleSkillDefinition[] | Skills granted by a specific item |
GetSkillsRequiringEquipment(string itemCode) | SimpleSkillDefinition[] | Skills requiring a specific item equipped |
GetSkillsProducingItem(string itemCode) | SimpleSkillDefinition[] | Skills that produce a specific item |
GetSkillsConsumingReagent(string itemCode) | SimpleSkillDefinition[] | Skills consuming a specific reagent item |
Cross-Forge Queries: SEF
| Method | Returns | Description |
|---|---|---|
GetSkillsSummoningEnemy(string enemyCode) | SimpleSkillDefinition[] | Skills that summon a specific enemy |
GetSkillsLearnedFromEnemy(string enemyCode) | SimpleSkillDefinition[] | Skills learned from a specific enemy |
GetSkillsTaughtByNPC(string npcCode) | SimpleSkillDefinition[] | Skills taught by a specific NPC trainer |
GetSkillsEffectiveAgainstFaction(string factionCode) | SimpleSkillDefinition[] | Skills effective against a specific faction |
GetSkillsRestrictedToFaction(string factionCode) | SimpleSkillDefinition[] | Skills restricted to a specific faction |
Cross-Forge Queries: SQF
| Method | Returns | Description |
|---|---|---|
GetSkillsUnlockedByQuest(string questCode) | SimpleSkillDefinition[] | Skills unlocked by completing a specific quest |
GetSkillsRewardedByQuest(string questCode) | SimpleSkillDefinition[] | Skills rewarded by a specific quest |
Cross-Forge Queries: SAF Character Templates
| Method | Returns | Description |
|---|---|---|
GetSkillsForClass(string className) | SimpleSkillDefinition[] | Skills restricted to a specific class |
GetSkillsUsableByClass(string className) | SimpleSkillDefinition[] | Skills usable by a class (restricted to that class + unrestricted) |
ISimpleSkillTreeDataSource
Interface for generated skill tree databases. Supports single-level dynamic properties on trees.
Tree Access
| Member | Returns | Description |
|---|---|---|
TreeCount | int | Number of trees |
GetAllTrees() | SimpleSkillTreeDefinition[] | All tree definitions |
GetTreeByCode(string code) | SimpleSkillTreeDefinition? | Tree by code, or null |
GetTreeCodes() | string[] | All tree codes |
GetTreeNames() | string[] | All tree display names |
HasTree(string code) | bool | Check if a tree exists |
GetTreeEnumType() | Type | The generated enum type for tree codes |
Node and Connection Access
| Method | Returns | Description |
|---|---|---|
GetNodesForTree(string treeCode) | SimpleSkillTreeNode[] | All nodes for a tree |
GetConnectionsForTree(string treeCode) | SimpleSkillTreeConnection[] | All connections for a tree |
GetBranchGroups(string treeCode) | string[] | Unique branch group names in a tree |
Property Definitions (Single-Level)
| Method | Returns | Description |
|---|---|---|
GetCategoryLabels() | string[] | Category labels |
GetCategoryEntries(int categoryIndex) | string[] | Entries for a category |
GetFlagNames() | string[] | Flag names |
GetNumericNames() | string[] | Numeric property names |
GetTextNames() | string[] | Text property names |
Dynamic Filtering
| Method | Returns | Description |
|---|---|---|
GetTreesByCategory(int categoryIndex, int entryIndex) | SimpleSkillTreeDefinition[] | Trees matching a category value |
GetTreesByFlag(int flagIndex, bool value) | SimpleSkillTreeDefinition[] | Trees matching a flag value |
GetTreesByNumericRange(int numericIndex, float min, float max) | SimpleSkillTreeDefinition[] | Trees with a numeric in the given range |
Cross-Reference and Class Queries
| Method | Returns | Description |
|---|---|---|
FindTreesContainingSkill(string skillCode) | SimpleSkillTreeDefinition[] | Trees containing a node with the given skill code |
GetTreesForClass(string className) | SimpleSkillTreeDefinition[] | Trees restricted to a specific class |
GetTreesAvailableToClass(string className) | SimpleSkillTreeDefinition[] | Trees available to a class (restricted + unrestricted) |
ISimpleSkillSetDataSource
Interface for generated skill set databases. Supports single-level dynamic properties on sets.
Set Access
| Member | Returns | Description |
|---|---|---|
SetCount | int | Number of sets |
GetAllSets() | SimpleSkillSetDefinition[] | All set definitions |
GetSetByCode(string code) | SimpleSkillSetDefinition? | Set by code, or null |
GetSetCodes() | string[] | All set codes |
GetSetNames() | string[] | All set display names |
HasSet(string code) | bool | Check if a set exists |
GetSetEnumType() | Type | The generated enum type for set codes |
Slot and Bonus Access
| Method | Returns | Description |
|---|---|---|
GetSlotsForSet(string setCode) | SimpleSkillSetSlot[] | All slots for a set |
GetBonusesForSet(string setCode) | SimpleSkillSetBonus[] | All bonuses for a set |
Property Definitions (Single-Level)
| Method | Returns | Description |
|---|---|---|
GetCategoryLabels() | string[] | Category labels |
GetCategoryEntries(int categoryIndex) | string[] | Entries for a category |
GetFlagNames() | string[] | Flag names |
GetNumericNames() | string[] | Numeric property names |
GetTextNames() | string[] | Text property names |
Dynamic Filtering
| Method | Returns | Description |
|---|---|---|
GetSetsByCategory(int categoryIndex, int entryIndex) | SimpleSkillSetDefinition[] | Sets matching a category value |
GetSetsByFlag(int flagIndex, bool value) | SimpleSkillSetDefinition[] | Sets matching a flag value |
GetSetsByNumericRange(int numericIndex, float min, float max) | SimpleSkillSetDefinition[] | Sets with a numeric in the given range |
Cross-Reference and Class Queries
| Method | Returns | Description |
|---|---|---|
FindSetsContainingSkill(string skillCode) | SimpleSkillSetDefinition[] | Sets containing a slot with the given skill code |
GetSetsForClass(string className) | SimpleSkillSetDefinition[] | Sets restricted to a specific class |
GetSetsAvailableToClass(string className) | SimpleSkillSetDefinition[] | Sets available to a class (restricted + unrestricted) |
ISimpleSkillComboDataSource
Interface for generated skill combo databases. Supports single-level dynamic properties on combos.
Combo Access
| Member | Returns | Description |
|---|---|---|
ComboCount | int | Number of combos |
GetAllCombos() | SimpleSkillComboDefinition[] | All combo definitions |
GetComboByCode(string code) | SimpleSkillComboDefinition? | Combo by code, or null |
GetComboCodes() | string[] | All combo codes |
GetComboNames() | string[] | All combo display names |
HasCombo(string code) | bool | Check if a combo exists |
GetComboEnumType() | Type | The generated enum type for combo codes |
Step and Reward Access
| Method | Returns | Description |
|---|---|---|
GetStepsForCombo(string comboCode) | SimpleSkillComboStep[] | All steps for a combo |
GetRewardsForCombo(string comboCode) | SimpleSkillComboReward[] | All rewards for a combo |
Cross-Reference and Class Queries
| Method | Returns | Description |
|---|---|---|
FindCombosContainingSkill(string skillCode) | SimpleSkillComboDefinition[] | Combos containing a step with the given skill (primary or alternates) |
FindCombosStartingWith(string skillCode) | SimpleSkillComboDefinition[] | Combos whose first step matches the given skill code |
GetCombosForClass(string className) | SimpleSkillComboDefinition[] | Combos restricted to a specific class |
GetCombosAvailableToClass(string className) | SimpleSkillComboDefinition[] | Combos available to a class (restricted + unrestricted) |
Property Definitions (Single-Level)
| Method | Returns | Description |
|---|---|---|
GetCategoryLabels() | string[] | Category labels |
GetCategoryEntries(int categoryIndex) | string[] | Entries for a category |
GetFlagNames() | string[] | Flag names |
GetNumericNames() | string[] | Numeric property names |
GetTextNames() | string[] | Text property names |
Dynamic Filtering
| Method | Returns | Description |
|---|---|---|
GetCombosByCategory(int categoryIndex, int entryIndex) | SimpleSkillComboDefinition[] | Combos matching a category value |
GetCombosByFlag(int flagIndex, bool value) | SimpleSkillComboDefinition[] | Combos matching a flag value |
GetCombosByNumericRange(int numericIndex, float min, float max) | SimpleSkillComboDefinition[] | Combos with a numeric in the given range |
Static Helpers
Stateless utility classes with pure functions. No instantiation needed — call methods directly on the static class.
SimpleSkillHelper
Static utility class for prerequisite evaluation, upgrade cost queries, cross-reference lookups, and rank-up affordability checks. All methods are pure functions.
Prerequisite Evaluation
| Method | Returns | Description |
|---|---|---|
CheckPrerequisite(SimpleSkillPrerequisite, Func<string, float>) | bool | Evaluate a single prerequisite condition |
CheckAllPrerequisites(SimpleSkillDefinition, Func<string, float>) | bool | Evaluate all prerequisites for a skill (ALL must pass) |
EvaluatePrerequisites(SimpleSkillDefinition, Func<string, float>) | PrerequisiteResult[] | Evaluate all prerequisites with detailed results (currentValue, passed) |
Upgrade Cost Queries
| Method | Returns | Description |
|---|---|---|
GetTotalUpgradeCost(SimpleSkillDefinition, string resourceCode, int fromRank, int toRank) | float | Total cost of a resource to upgrade between ranks |
GetAllResourceCodes(SimpleSkillDefinition) | string[] | All unique resource codes used across all ranks |
GetUpgradeCostsForRank(SimpleSkillDefinition, int rankNumber) | SimpleSkillUpgradeCost[] | Upgrade costs for a specific rank |
CanAffordRankUp(SimpleSkillDefinition, int currentRank, Func<string, float>) | bool | Check if player can afford upgrading to the next rank |
Cross-Reference Queries
| Method | Returns | Description |
|---|---|---|
FindSkillsByCategory(ISimpleSkillDataSource, int categoryIndex, int entryIndex) | SimpleSkillDefinition[] | Skills matching a category value |
FindSkillsRequiring(ISimpleSkillDataSource, string targetCode) | SimpleSkillDefinition[] | Skills with a specific prerequisite target code |
FindUnlockedSkills(ISimpleSkillDataSource, Func<string, float>) | List<SimpleSkillDefinition> | All skills whose prerequisites are met |
GetPrerequisiteChain(ISimpleSkillDataSource, string skillCode) | List<string> | Recursive prerequisite chain (all skills needed before target) |
Cross-Forge Queries: SIF (Item Forge)
| Method | Returns | Description |
|---|---|---|
FindSkillsGrantedByItem(ISimpleSkillDataSource, string itemCode) | SimpleSkillDefinition[] | Skills granted by a specific item |
FindSkillsRequiringEquipment(ISimpleSkillDataSource, string itemCode) | SimpleSkillDefinition[] | Skills requiring a specific item equipped |
FindSkillsProducingItem(ISimpleSkillDataSource, string itemCode) | SimpleSkillDefinition[] | Skills that produce a specific item |
FindSkillsConsumingReagent(ISimpleSkillDataSource, string itemCode) | SimpleSkillDefinition[] | Skills consuming a specific reagent item |
GetAllReagentItemCodes(ISimpleSkillDataSource) | string[] | All unique reagent item codes across all skills |
Cross-Forge Queries: SEF (Enemy Forge)
| Method | Returns | Description |
|---|---|---|
FindSkillsSummoningEnemy(ISimpleSkillDataSource, string enemyCode) | SimpleSkillDefinition[] | Skills summoning a specific enemy |
FindSkillsLearnedFromEnemy(ISimpleSkillDataSource, string enemyCode) | SimpleSkillDefinition[] | Skills learned from a specific enemy |
FindSkillsTaughtByNPC(ISimpleSkillDataSource, string npcCode) | SimpleSkillDefinition[] | Skills taught by a specific NPC trainer |
FindSkillsEffectiveAgainstFaction(ISimpleSkillDataSource, string factionCode) | SimpleSkillDefinition[] | Skills effective against a faction |
FindSkillsRestrictedToFaction(ISimpleSkillDataSource, string factionCode) | SimpleSkillDefinition[] | Skills restricted to a faction |
Cross-Forge Queries: SQF (Quest Forge)
| Method | Returns | Description |
|---|---|---|
FindSkillsUnlockedByQuest(ISimpleSkillDataSource, string questCode) | SimpleSkillDefinition[] | Skills unlocked by a quest |
FindSkillsRewardedByQuest(ISimpleSkillDataSource, string questCode) | SimpleSkillDefinition[] | Skills rewarded by a quest |
Cross-Forge Queries: SAF Character Templates
| Method | Returns | Description |
|---|---|---|
FindSkillsForClass(ISimpleSkillDataSource, string className) | SimpleSkillDefinition[] | Skills restricted to a specific class |
FindSkillsUsableByClass(ISimpleSkillDataSource, string className) | SimpleSkillDefinition[] | Skills usable by a class (restricted + unrestricted) |
Tree Node Lookup
| Method | Returns | Description |
|---|---|---|
GetSkillForTreeNode(ISimpleSkillDataSource, ISimpleSkillTreeDataSource, string treeCode, int nodeId) | SimpleSkillDefinition? | Convenience: get the skill definition for a tree node |
Usage Example
SimpleSkillComboEvaluator
Static utility class for evaluating combo progress, finding matching combos, and computing next valid skills. Stateless — all methods are pure functions. Use this when you need combo evaluation without instantiating a tracker.
Methods
| Method | Returns | Description |
|---|---|---|
EvaluateCombo(SimpleSkillComboDefinition, string[] usedSkillCodes) | ComboEvalResult | Evaluate a combo against a sequence of used skills |
FindMatchingCombos(ISimpleSkillComboDataSource, string[] recentSkillCodes) | ComboMatch[] | Find all combos that partially or fully match recent skills |
GetActiveRewards(SimpleSkillComboDefinition, int completedStepCount) | SimpleSkillComboReward[] | Get rewards active for a given step count |
GetNextValidSkills(SimpleSkillComboDefinition, int completedStepCount) | string[] | Get skill codes that would advance the combo from current position |
IsComboComplete(SimpleSkillComboDefinition, string[] usedSkillCodes) | bool | Check if a combo is fully complete |
GetComboProgress(SimpleSkillComboDefinition, string[] usedSkillCodes) | float | Get completion progress (0 to 1) |
Result Types
ComboEvalResult
| Field | Type | Description |
|---|---|---|
matchedStepCount | int | Number of steps matched |
totalStepCount | int | Total steps in the combo |
completionPercentage | float | Completion percentage (0 to 1) |
isComplete | bool | Whether all steps have been matched |
nextValidSkillCodes | string[] | Skills that would advance the combo |
ComboMatch
| Field | Type | Description |
|---|---|---|
comboCode | string | The combo code |
matchedSteps | int | Number of steps matched |
totalSteps | int | Total steps in the combo |
isComplete | bool | Whether the combo is fully complete |
Usage Example
State Trackers
Mutable runtime state managers. Instantiate them with a database reference, use methods to modify state, subscribe to events for reactive updates, and create/restore snapshots for save/load.
SimpleSkillTreeTracker
Tracks skill tree progression at runtime. Manages node unlocks, point spending, prerequisite validation, cascade resets, and serializable snapshots.
Constructor
Events
| Event | Signature | Description |
|---|---|---|
OnNodeUnlocked | Action<string, int> | Fired when a node is unlocked (treeCode, nodeId) |
OnNodeReset | Action<string, int> | Fired when a node is reset/locked (treeCode, nodeId) |
OnTreeReset | Action<string> | Fired when an entire tree is reset (treeCode) |
OnPointsChanged | Action<string, int> | Fired when points spent changes (treeCode, newTotal) |
Properties
| Property | Type | Description |
|---|---|---|
Database | ISimpleSkillTreeDataSource | The tree database this tracker uses |
InitializedTreeCodes | string[] | All initialized tree codes |
Lifecycle Methods
| Method | Returns | Description |
|---|---|---|
InitializeTree(string treeCode) | bool | Initialize a tree for tracking. Required before unlock/query operations. |
IsTreeInitialized(string treeCode) | bool | Check if a tree has been initialized |
GetTreeState(string treeCode) | SimpleSkillTreeState | Get the runtime state object, or null |
Node Unlock Methods
| Method | Returns | Description |
|---|---|---|
CanUnlockNode(string treeCode, int nodeId, int playerLevel, int availablePoints) | bool | Check all prerequisites: parent nodes, level, points in tree, point cost |
UnlockNode(string treeCode, int nodeId, int playerLevel) | bool | Unlock a node (caller manages point deduction) |
IsNodeUnlocked(string treeCode, int nodeId) | bool | Check if a specific node is unlocked |
Query Methods
| Method | Returns | Description |
|---|---|---|
GetPointsSpent(string treeCode) | int | Total skill points spent in a tree |
GetPointsSpentInBranch(string treeCode, string branchGroup) | int | Points spent in a specific branch |
GetUnlockedNodeIds(string treeCode) | int[] | All unlocked node IDs for a tree |
GetAvailableNodeIds(string treeCode, int playerLevel, int availablePoints) | int[] | All node IDs that can currently be unlocked |
GetAllUnlockedSkillCodes() | string[] | All unlocked skill codes across all initialized trees |
IsSkillUnlocked(string skillCode) | bool | Check if a skill code is unlocked in any tree |
Reset Methods
| Method | Returns | Description |
|---|---|---|
ResetNode(string treeCode, int nodeId) | int | Reset a node and cascade to dependents. Returns points refunded. |
ResetTree(string treeCode) | int | Reset an entire tree. Returns points refunded. |
ClearAll() | void | Clear all tracked state |
Serialization
| Method | Returns | Description |
|---|---|---|
CreateSnapshot() | SimpleSkillTreeTrackerSnapshot | Export current state as a serializable snapshot |
RestoreFromSnapshot(SimpleSkillTreeTrackerSnapshot) | void | Restore state from a snapshot |
Usage Example
SimpleSkillBarManager
Manages skill set loadouts at runtime. Handles equipping/unequipping skills to set slots, tracks active set bonuses based on equipped count thresholds, and supports snapshot serialization.
Constructor
Events
| Event | Signature | Description |
|---|---|---|
OnSkillEquipped | Action<string, int, string> | Fired when a skill is equipped (setCode, slotIndex, skillCode) |
OnSkillUnequipped | Action<string, int, string> | Fired when a skill is unequipped (setCode, slotIndex, previousSkillCode) |
OnSetBonusActivated | Action<string, int> | Fired when a set bonus activates (setCode, bonusIndex) |
OnSetBonusDeactivated | Action<string, int> | Fired when a set bonus deactivates (setCode, bonusIndex) |
OnLoadoutChanged | Action<string> | Fired on any equip/unequip (setCode) |
Properties
| Property | Type | Description |
|---|---|---|
Database | ISimpleSkillSetDataSource | The set database this manager uses |
InitializedSetCodes | string[] | All initialized set codes |
Lifecycle Methods
| Method | Returns | Description |
|---|---|---|
InitializeSet(string setCode) | bool | Initialize a set for loadout tracking. Required before equip/query operations. |
IsSetInitialized(string setCode) | bool | Check if a set has been initialized |
GetLoadoutState(string setCode) | SimpleSkillSetLoadoutState | Get the runtime loadout state, or null |
Equip / Unequip Methods
| Method | Returns | Description |
|---|---|---|
EquipSkill(string setCode, int slotIndex, string skillCode) | bool | Equip a skill to a slot (auto-unequips previous) |
UnequipSkill(string setCode, int slotIndex) | bool | Unequip a skill from a slot |
ClearLoadout(string setCode) | int | Clear all equipped skills. Returns number of slots cleared. |
Query Methods
| Method | Returns | Description |
|---|---|---|
GetEquippedSkill(string setCode, int slotIndex) | string | Get the skill code in a slot, or empty string |
GetEquippedCount(string setCode) | int | Number of non-empty slots |
AreRequiredSlotsFilled(string setCode) | bool | Check if all required slots are filled |
GetActiveBonuses(string setCode) | SimpleSkillSetBonus[] | Get currently active bonuses |
IsBonusActive(string setCode, int bonusIndex) | bool | Check if a specific bonus is active |
IsSkillEquipped(string skillCode) | bool | Check if a skill is equipped in any set |
GetAllEquippedSkillCodes() | string[] | All equipped skill codes across all sets |
FindEquippedSkill(string skillCode, out string setCode, out int slotIndex) | bool | Find which set and slot a skill is equipped in |
Serialization
| Method | Returns | Description |
|---|---|---|
CreateSnapshot() | SimpleSkillBarSnapshot | Export current state as a serializable snapshot |
RestoreFromSnapshot(SimpleSkillBarSnapshot) | void | Restore state from a snapshot |
ClearAll() | void | Clear all tracked state |
Usage Example
SimpleSkillComboTracker
Tracks active skill combos at runtime. Feed skill usage to auto-evaluate all defined combos simultaneously, handles timing windows, triggers threshold rewards, and supports snapshot serialization.
Constructor
Events
| Event | Signature | Description |
|---|---|---|
OnComboStarted | Action<string> | Fired when a combo starts (first step matched). Parameter: comboCode. |
OnComboProgressed | Action<string, int, int> | Fired when a combo progresses (comboCode, currentStep, totalSteps) |
OnComboCompleted | Action<string> | Fired when a combo is fully completed (comboCode) |
OnComboDropped | Action<string, string> | Fired when a combo is dropped (comboCode, reason) |
OnRewardTriggered | Action<string, int> | Fired when a combo reward triggers (comboCode, rewardIndex) |
Properties
| Property | Type | Description |
|---|---|---|
Database | ISimpleSkillComboDataSource | The combo database this tracker uses |
Skill Usage
| Method | Returns | Description |
|---|---|---|
OnSkillUsed(string skillCode, float currentTime) | void | Feed a skill usage. Evaluates all combos and starts new ones. |
Query Methods
| Method | Returns | Description |
|---|---|---|
GetActiveComboStates() | SimpleActiveComboState[] | Get all active combo states |
GetActiveComboCount() | int | Number of active combos |
IsComboActive(string comboCode) | bool | Check if a specific combo is active |
GetComboProgress(string comboCode) | float | Completion progress of an active combo (0 to 1) |
Control Methods
| Method | Returns | Description |
|---|---|---|
DropCombo(string comboCode) | void | Manually drop an active combo |
DropAllCombos() | void | Drop all active combos |
Serialization
| Method | Returns | Description |
|---|---|---|
CreateSnapshot() | SimpleComboTrackerSnapshot | Export current state as a serializable snapshot |
RestoreFromSnapshot(SimpleComboTrackerSnapshot) | void | Restore state from a snapshot |
ClearAll() | void | Clear all tracked state |
Usage Example
Supporting Types
These types are used internally by the static helpers and state trackers.
PrerequisiteResult
Returned by SimpleSkillHelper.EvaluatePrerequisites().
| Field | Type | Description |
|---|---|---|
prerequisite | SimpleSkillPrerequisite | The prerequisite that was evaluated |
currentValue | float | The current value from the value provider |
passed | bool | Whether the prerequisite was met |
SimpleIntArray
Wrapper for int[] to allow serialization of nested arrays. Used for multi-select category values.
| Field | Type | Description |
|---|---|---|
values | int[] | The wrapped integer array |
Snapshot Types
All snapshot types are [Serializable] classes compatible with JsonUtility.
| Type | Used By | Contains |
|---|---|---|
SimpleSkillTreeTrackerSnapshot | SimpleSkillTreeTracker | List of tree state snapshots (treeCode, totalPointsSpent, unlockedNodeIds) |
SimpleSkillBarSnapshot | SimpleSkillBarManager | List of loadout snapshots (setCode, equippedSkills) |
SimpleComboTrackerSnapshot | SimpleSkillComboTracker | List of active combo snapshots (comboCode, completedStepCount, usedSkillCodes, lastStepTime) |
Cross-Forge Integration
Simple Skill Forge integrates with 4 companion packages from the Living Failure ecosystem. All integrations
use safe reflection — no hard dependencies, no compile errors, no #if
preprocessor directives. Install companion packages when you need them; SSF adapts automatically.
| Package | Package ID | What SSF Gets |
|---|---|---|
| Simple Attribute Forge | com.livingfailure.simple-attribute-forge |
Modifier assets on skills/ranks/bonuses, character class restrictions |
| Simple Item Forge | com.livingfailure.simple-item-forge |
4 skill-item reference fields + reagent costs |
| Simple Enemy Forge | com.livingfailure.simple-enemy-forge |
5 skill-enemy/faction reference fields |
| Simple Quest Forge | com.livingfailure.simple-quest-forge |
2 skill-quest reference fields |
How Bridges Work
SSF uses two detection paths:
1. UPM Detection (Automatic)
The .asmdef files contain versionDefines that detect companion packages by
their UPM package name and set scripting defines automatically:
2. Reflection Detection (Fallback)
For non-UPM installs (Asset Store, .unitypackage), bridge classes use Type.GetType() to
probe for companion types at editor time. Each bridge is a static class that caches type references and
builds delegate-based accessors:
At runtime, the demo scenes use FindType() (scanning all loaded assemblies)
instead of Type.GetType() with assembly-qualified names, since assembly names may vary
between UPM and Asset Store installs.
Simple Attribute Forge (SAF)
When SAF is detected, the following features become available:
Modifier Assets
The Skill Forge builder (Step 3) shows a Skill Modifiers section where you can assign
SimpleModifierAssetBase ScriptableObjects to skills. Each rank can also have its own modifier
assets. The Skill Set Forge allows modifiers on set bonuses.
Character Class Restrictions
When SAF Character Templates are detected, all 4 forges show an Allowed Character Classes section. You can assign character template assets in Step 1, and the builder provides checkbox toggles for each detected class name plus a manual entry list.
At runtime, each definition struct has allowedCharacterClasses (string[]) with
HasClassRestriction and IsUsableByClass() / IsAvailableToClass()
accessors. The interfaces provide GetSkillsForClass() and GetSkillsUsableByClass()
query methods.
Simple Item Forge (SIF)
When SIF is detected, the Skill Forge builder shows 4 cross-forge reference fields plus reagent costs:
| Field | Type | Purpose | Example |
|---|---|---|---|
grantedByItemCode | string | Item that teaches/grants this skill | Skill books, scrolls, equipment passives, gem sockets |
requiredEquipmentCode | string | Item that must be equipped to use this skill | Bow for arrow skills, staff for magic, specific weapon types |
producesItemCode | string | Item created when skill is used | Conjure food, crafting skills, transmutation, gathering yields |
reagentCosts[] | SimpleSkillReagentCost[] | Items consumed per cast | Arrows, soul shards, catalysts, reagents |
SimpleSkillUpgradeCost
(which defines costs to level up a skill rank). Reagents are consumed every time the skill is cast.Runtime Queries
Simple Enemy Forge (SEF)
When SEF is detected, the Skill Forge builder shows 5 cross-forge reference fields:
| Field | Type | Purpose | Example |
|---|---|---|---|
summonEnemyCode | string | Enemy summoned by this skill | Necromancer minions, pet classes, conjured creatures |
learnedFromEnemyCode | string | Enemy that teaches this skill | Blue Mage skills, Enemy Skill materia, monster absorption |
taughtByNPCCode | string | NPC trainer that teaches this skill | Class trainers, weapon masters, move tutors |
effectiveAgainstFactions[] | string[] | Factions this skill is strong against | Holy vs Undead, Dragon Slayer vs Dragons, type advantages |
restrictedToFactionCode | string | Only characters of this faction can use the skill | Racial abilities, covenant skills, guild techniques |
taughtByNPCCode field
references an enemy code from the SEF database.Runtime Queries
Simple Quest Forge (SQF)
When SQF is detected, the Skill Forge builder shows 2 cross-forge reference fields:
| Field | Type | Purpose | Example |
|---|---|---|---|
unlockedByQuestCode | string | Quest that must be completed to learn this skill | Class quests, weapon art quests, mastery trials |
rewardedByQuestCodes[] | string[] | Quests that award this skill as a reward | Reverse lookup: "Learned from: The Archmage's Trial" |
Runtime Queries
Character Class System
All 4 forge types (Skill, Tree, Set, Combo) support allowedCharacterClasses on their
definition structs. This feature is enabled when SAF Character Templates are detected, but can also
be used manually by typing class names directly.
How It Works
- In Step 1, assign Character Template assets to populate available class names
- In Step 3 (builder), toggle classes on/off per entry or type custom names
- An empty
allowedCharacterClassesarray means the entry is unrestricted (usable by all classes) - A non-empty array means the entry is restricted to listed classes only
Runtime API
Demo Scenes
Simple Skill Forge ships with two interactive demo scenes that showcase all 4 forges and their runtime components. Both demos are generated procedurally via editor menu commands — no manual scene setup required.
| Demo | Purpose | Requirements |
|---|---|---|
| ARPG Demo | Proves the SSF runtime API works: browse skills, rank up, unlock tree nodes, equip loadouts, cast combos | SSF only (standalone) |
| Soulslike Demo | Showcases cross-forge integration: browse items/enemies/quests and see how they connect to skills | SSF + SAF + SIF + SEF + SQF (all installed) |
ARPG Demo
A 4-tab interactive skill system with Royal Orange theme (1920x1080).
Tab 1: Skills
Left panel: searchable skill list with rank badges. Right panel: skill detail with identity, properties, rank stats (per-rank costs, UNLOCKED/LOCKED status), prerequisites (MET/NOT MET), and cross-forge connections. RANK UP button deducts resources. EQUIP TO BAR adds the skill to the bottom bar.
Tab 2: Skill Trees
Left panel: tree list. Right panel: node list showing skill name, SP cost, level requirement, and UNLOCK/UNLOCKED/LOCKED status. Click a node to unlock it (deducts skill points). RESET TREE refunds all points.
Tab 3: Loadout
Left panel: set list with equipped count. Right panel: dropdown per slot for skill assignment, X button to unequip, and set bonus progress (3/5 threshold bonuses with OK/[ ] indicators).
Tab 4: Combos
Left panel: combo list with step count. Right panel: step sequence with skill names, required/optional flags, timing windows, alternate skills, reward thresholds. Live tracker shows combo progress bars and next valid skills.
Bottom Bar
6 skill slots with CAST buttons. Casting updates combo tracking, shows combo progress, set status, and cast log. Cyclic assignment — equipping when full wraps to slot 0.
Top Bar
Class dropdown (filters all tabs by character class). Cheat buttons: +LVL, +SP, +Souls for testing.
Soulslike Demo
A 7-tab cross-forge showcase with upsell panel. Same Royal Orange theme.
Upsell Panel
Shown when any companion package (SAF/SIF/SEF/SQF) is not installed. Displays a checklist of
INSTALLED/MISSING packages with descriptions of what each provides. A forceShowUpsell debug
toggle on the component lets you test this panel even with all packages installed.
Tabs 1–4: Skills, Trees, Loadout, Combos
Same functionality as the ARPG demo. Uses "Souls" instead of "Gold" for the Soulslike theme.
Tab 5: Items
Browses all items from assigned SIF databases. Shows item name, code, description, properties (categories, flags, numerics, texts reflected from the item database), and skill connections — which skills grant, require, produce, or consume this item.
Tab 6: Enemies
Browses all enemies from assigned SEF databases. Shows enemy name, code, description, info (properties reflected from the enemy database), and skill connections — which skills are taught by, trained by, or summoned by this enemy.
Tab 7: Quests
Browses all quests from assigned SQF databases. Shows quest name, code, description, and skill connections — which skills this quest unlocks or rewards.
Cross-Forge Reflection
The Soulslike demo uses FindType() to scan all loaded assemblies for SIF/SEF/SQF interfaces.
It builds lookup dictionaries (code → name, code → description) and reverse lookups
(item → skills that reference it) via reflection at startup. No hard dependencies on any companion package.
Generating Demo Scenes
ARPG Demo
Window > Living Failure > Simple Skill Forge > Generate Skill Demo
Soulslike Demo
Window > Living Failure > Simple Skill Forge > Generate Soulslike Demo
Assigning Databases
After generating a demo canvas, select the root canvas GameObject in the Hierarchy. The demo component will be attached with empty database array fields:
ARPG Demo (SkillDemo component)
| Field | What to Assign |
|---|---|
skillDatabases | Your generated Skill database .asset(s) |
treeDatabases | Your generated Skill Tree database .asset(s) |
setDatabases | Your generated Skill Set database .asset(s) |
comboDatabases | Your generated Skill Combo database .asset(s) |
Soulslike Demo (SoulslikeSkillDemo component)
| Field | What to Assign |
|---|---|
skillDatabases | SSF Skill database(s) |
treeDatabases | SSF Skill Tree database(s) |
setDatabases | SSF Skill Set database(s) |
comboDatabases | SSF Skill Combo database(s) |
attributeDatabases | SAF Attribute database(s) |
modifierAssets | SAF Modifier assets |
itemDatabases | SIF Item database(s) |
enemyDatabases | SEF Enemy database(s) |
factionDatabases | SEF Faction database(s) |
questDatabases | SQF Quest database(s) |
characterTemplates | SAF Character Template assets |
Troubleshooting
Common issues and their solutions when working with Simple Skill Forge.
Generation Issues
"Generation seems stuck" / Nothing happens after clicking Generate
Simple Skill Forge uses two-phase generation. Phase 1 generates C# scripts, which triggers a Unity domain reload (recompilation). Phase 2 runs automatically after the reload to create the ScriptableObject asset. This process can take 5–30 seconds depending on your project size.
[InitializeOnLoad]."The generated .asset file is empty"
This typically means Phase 2 failed. Check the Console for errors. Common causes:
- A compile error in your project prevented the domain reload from completing.
- The
SessionStatekeys were lost (rare, usually caused by a Unity crash during generation).
Fix: Delete the generated Scripts/ folder, fix any compile errors, and re-run the wizard.
"Duplicate code" validation error
Every entry code must be unique within a database and must be a valid C# identifier (letters, digits,
underscores; cannot start with a digit). Use SCREAMING_SNAKE_CASE for consistency:
FIREBALL, DARK_SLASH, HEAL_OVER_TIME.
"Output path does not exist"
The output folder must exist before generation. Create it manually in your Assets folder, or use the Browse button in Step 4 to select an existing folder.
Editor Issues
The generated custom inspector shows "Element 0, Element 1" instead of property names
This can happen if the database was generated with an older version of the editor generator. Re-run the wizard to regenerate the editor script.
Cross-forge sections (SIF/SEF/SQF) appear in the inspector even without companion packages
The generated editor uses Type.GetType() bridge checks to gate cross-forge sections.
If sections appear without the companion package installed, regenerate the database — the editor
generator has been updated to include proper bridge detection.
Property definitions changed but entries are out of sync
When you add/remove/reorder property definitions in Step 2, the wizard automatically syncs all entries. However, if you modify the generated database asset manually, the sync won't apply. Use the wizard for all structural changes.
Runtime Issues
SimpleSkillTreeTracker throws "Tree not initialized"
Call InitializeTree(treeCode) for each tree before attempting to unlock nodes or query state.
The tracker does not auto-initialize — this is intentional so you can control which trees are active.
SimpleSkillBarManager set bonuses not activating
Set bonuses require the correct number of distinct skills equipped. Equipping the same skill
in multiple slots does not count multiple times. Check GetEquippedCount(setCode) to verify.
SimpleSkillComboTracker drops combos unexpectedly
Combos have timing windows defined by maxDelay on each step. If you cast skills too slowly,
the combo will drop. Set maxDelay to 0 to disable timing for a step. Also ensure you're
passing consistent Time.time values to OnSkillUsed().
Prerequisite checks always return false
SimpleSkillHelper.CheckPrerequisite() requires a Func<string, float> value
provider that returns the current value for any prerequisite target code. Common mistake: the provider
returns 0 for all codes because it doesn't check the right dictionary.
Integration Issues
SAF/SIF/SEF/SQF bridge not detecting installed package
Bridge detection uses two paths:
- UPM path:
versionDefinesin.asmdeffiles detect packages bycom.livingfailure.*package name and set scripting defines automatically. - Non-UPM path:
[InitializeOnLoad]detector classes useType.GetType()to probe for companion types and set scripting defines manually.
If detection fails, check that the companion package's .asmdef files are present and correctly
named. For Asset Store imports, ensure the folder structure matches the expected layout.
Character class restrictions not showing in the wizard
Class names come from SAF Character Template assets assigned in Step 1. If you don't have SAF installed or haven't assigned any character template assets, the class restriction section will be empty. You can still manually type class names in the builder.
Cross-forge reference dropdowns are empty
Cross-forge dropdowns in Step 3 are populated from linked databases assigned in Step 1. If you haven't assigned any SIF/SEF/SQF databases, the dropdowns will only show manual code entry fields.
Demo Scene Issues
ARPG Demo: "Assign all databases to SkillDemo component"
After running Window > Living Failure > Simple Skill Forge > Generate Skill Demo,
you need to manually assign your generated database ScriptableObjects to the SkillDemo component in the
Inspector. Drag your Skill, Tree, Set, and Combo database assets into the corresponding array fields.
Soulslike Demo: Shows upsell panel instead of main UI
The Soulslike demo requires all 4 companion packages (SAF, SIF, SEF, SQF) to be installed. If any are missing, it shows an upsell panel explaining what's needed. Install the missing packages and re-enter Play mode.
Soulslike Demo: "forceShowUpsell" is checked
The SoulslikeSkillDemo component has a debug toggle forceShowUpsell. Uncheck it in the
Inspector to show the main UI even when all bridges are detected.
Demo scroll views don't scroll
Ensure the EventSystem exists in the scene. The generator creates one automatically, but if you deleted
it, scrolling won't work. Add GameObject > UI > Event System.
FAQ
Can I have multiple skill databases in one project?
Yes. Run the wizard multiple times with different database names. Each run generates its own enum, database
class, and editor. At runtime, cast each ScriptableObject to ISimpleSkillDataSource and merge
or query them independently.
Can I modify the generated database asset in the Inspector?
Yes. The generated custom editor provides a full split-panel builder with search, sort, filter, and pagination — identical to the wizard's Step 3. You can add, remove, edit, and duplicate entries directly in the Inspector without reopening the wizard.
Does SSF support multiplayer / networking?
SSF generates data assets and provides runtime state trackers. The trackers (SimpleSkillTreeTracker,
SimpleSkillBarManager, SimpleSkillComboTracker) are pure C# classes with snapshot serialization. You can
serialize their state via CreateSnapshot() / RestoreFromSnapshot() for network
sync, save/load, or undo/redo.
What's the performance impact?
Generated databases are standard Unity ScriptableObjects with struct arrays. All runtime lookups use linear scans over small arrays (typical game databases have 50–500 entries). The trackers use dictionaries for O(1) state lookups. There are no per-frame allocations in normal usage.
Can I use SSF with Addressables / Asset Bundles?
Yes. The generated database is a standard ScriptableObject and works with any Unity asset loading system. Cast the loaded asset to the appropriate interface at runtime.
About Simple Skill Forge
Simple Skill Forge is a Unity Editor tool for creating ScriptableObject-based skill databases using a wizard-driven workflow. It follows the same proven architecture as Simple Enemy Forge, Simple Item Forge, and Simple Quest Forge — dynamic property systems, two-phase code generation, schema export/import for AI-assisted content creation, and optional integration bridges via safe reflection.
Whether you're building a small indie RPG or a large-scale MMO, Simple Skill Forge adapts to your game's needs. You define the properties that matter to your game (there are no hardcoded "Mana Cost" or "Cooldown" fields), and the tool generates production-ready code and data assets from your design.
Design Philosophy
Two-Level Properties
The Skill Forge defines dynamic properties at both skill-level AND rank-level. A skill can have "Element" and "Skill Type" while each of its ranks independently tracks "Damage Multiplier" and "Cast Time". The other three forges (Tree, Set, Combo) use single-level properties.
Dynamic, Not Hardcoded
There are no built-in "Mana Cost" or "Cooldown" fields. You define your own property schema using four property types: Categories (dropdowns), Flags (booleans), Numerics (numbers), and Texts (strings). A MOBA might need "Lane Phase" and "Team Fight Impact". A roguelike might need "Synergy Tag" and "Stack Limit". Your game, your properties, your rules.
Four Tools, One Ecosystem
Skill Forge defines individual skills with ranks and cross-forge references. Skill Tree Forge organizes them into unlockable talent grids. Skill Set Forge groups them into loadouts with set bonuses. Skill Combo Forge chains them into timed sequences with rewards. Together they cover every aspect of a skill system.
AI-First Content Pipeline
All four wizards support schema export in 3 formats (Full JSON, Light JSON, Markdown) with detailed AI instructions embedded in the export. Define your schema once, let AI generate hundreds of skills, then import the results — all without writing a line of code.
The Forge Ecosystem
Simple Skill Forge is part of the Simple Forge Ecosystem, a family of Unity Editor tools that share a common architecture:
| Package | Forges | Runtime Components |
|---|---|---|
| Simple Attribute Forge | Attribute Forge, Modifier System, Character Templates | Runtime attributes, modifier tracker, formula calculator |
| Simple Item Forge | Item Forge, Loot Forge, Crafting Forge, Shop Forge | Loot roller, crafting evaluator, shop manager |
| Simple Enemy Forge | Enemy, Squad, Spawn, Scaling, Wave, Behavior, Faction Forges | Spawn roller, wave runner, scaling helper, faction helper |
| Simple Quest Forge | Quest Forge, Quest Chain Forge, Procedural Quest Forge | Quest tracker, chain tracker, procedural generator |
| Simple Skill Forge | Skill Forge, Skill Tree Forge, Skill Set Forge, Skill Combo Forge | Tree tracker, bar manager, combo tracker, combo evaluator |
Every package in the ecosystem follows the same 5-step wizard pattern, uses the same dynamic property system, generates the same output structure (enum + database + editor + asset), and supports the same AI schema export/import workflow.
What Gets Generated
Each forge generates 4 files per database run:
The generated database implements the corresponding interface (ISimpleSkillDataSource,
ISimpleSkillTreeDataSource, ISimpleSkillSetDataSource, or
ISimpleSkillComboDataSource), so your game code only depends on the interface —
never on the generated class name.
Companion Products
Simple Skill Forge optionally integrates with these companion packages via safe reflection. No hard dependencies — install them only when you need them:
Simple Attribute Forge (SAF)
Enables modifier asset references on skills, ranks, and set bonuses. Provides attribute names for prerequisites and character class templates for class restrictions on all 4 forge types.
Simple Item Forge (SIF)
Enables skill-item relationships: skill books (grantedByItemCode), weapon requirements (requiredEquipmentCode), produced items (producesItemCode), and reagent costs per cast.
Simple Enemy Forge (SEF)
Enables skill-enemy relationships: summon skills (summonEnemyCode), NPC trainers (taughtByNPCCode), learned-from enemies (learnedFromEnemyCode), faction effectiveness, and faction restrictions.
Simple Quest Forge (SQF)
Enables skill-quest relationships: quest-gated unlocks (unlockedByQuestCode) and quest-rewarded skills (rewardedByQuestCodes).
Version History
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | 2025 | Initial release. 4 forges, 6 genre templates, 4 runtime trackers, cross-forge integration (SAF/SIF/SEF/SQF), AI schema export/import, character class restrictions, 2 demo scenes (ARPG + Soulslike), database export window, batch icon assignment. |
Support
Simple Skill Forge is developed and maintained by Living Failure.
| Publisher | Living Failure on Unity Asset Store |
| livingfailuregames@gmail.com | |
| Unity Version | 2021.3+ |
| Package Name | com.livingfailure.simple-skill-forge |
Found a bug? Have a feature request? Email us or leave a review on the Asset Store page.