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).