View Format: Multi-Page Single Page

Simple Skill Forge

Generate Complete Skill Databases, Skill Trees, Loadouts, and Combos in Minutes.

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:

Window > Living Failure > Simple Skill Forge > Skill Forge

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.
Template selection: When you choose a template, it populates Step 2 with genre-appropriate property definitions. Selecting None clears all existing definitions (with a confirmation dialog). You can always modify template-provided definitions freely.

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.cs generation
  • 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:

1 Phase 1 — Script Generation: Writes .cs files (enum, database class, custom editor). Unity triggers a domain reload to compile the new scripts.
2 Phase 2 — Asset Creation: After the domain reload, an [InitializeOnLoad] handler creates the .asset ScriptableObject and populates it with all your skill data. GUID-based persistence ensures ScriptableObject references survive the reload.
Do not close the wizard window or switch editor focus during generation. The two-phase process requires the [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.

// Definition CategoryDefinition { string label; // e.g., "Skill Type" List<string> entries; // e.g., ["Attack", "Buff", "Debuff", "Heal", "Summon"] int defaultIndex; // default selection } // Access on a skill int skillTypeIndex = skill.GetCategoryValue(0); // Get the human-readable entry name string[] entries = database.GetCategoryEntries(0); // skill-level string skillTypeName = entries[skillTypeIndex]; // "Attack" // Rank-level categories string[] rankEntries = database.GetRankCategoryEntries(0); int rankCatValue = rank.GetCategoryValue(0);

Flags

Boolean properties. Each flag has a name and a default value.

// Access bool isPassive = skill.GetFlagValue(0); // Get the flag name string[] flagNames = database.GetFlagNames(); // skill-level string[] rankFlagNames = database.GetRankFlagNames(); // rank-level

Numerics

Float or integer values with optional min/max constraints.

// Access float manaCost = skill.GetNumericValue(0); // Get the numeric name string[] numericNames = database.GetNumericNames(); // skill-level string[] rankNumNames = database.GetRankNumericNames(); // rank-level // Rank-level numerics (values that change per rank) float damage = rank.GetNumericValue(0); // e.g., Rank 1: 50, Rank 2: 80

Texts

String values. Each text property has a name and a line count (1 = single line, >1 = multi-line TextArea).

// Access string tooltip = skill.GetTextValue(0); // Get the text name string[] textNames = database.GetTextNames(); // skill-level string[] rankTextNames = database.GetRankTextNames(); // rank-level

Filtering by Properties

The database interface provides filtering methods for all property types:

// All skills where category 0 == entry index 2 SimpleSkillDefinition[] debuffs = database.GetSkillsByCategory(0, 2); // All skills where flag 0 (Is Passive) == true SimpleSkillDefinition[] passives = database.GetSkillsByFlag(0, true); // All skills where numeric 1 (Cooldown) is between 0 and 5 SimpleSkillDefinition[] quickSkills = database.GetSkillsByNumericRange(1, 0f, 5f);

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:

SimpleSkillUpgradeCost { string resourceCode; // e.g., "GOLD", "SKILL_POINT", "DRAGON_SCALE" float amount; // e.g., 500 }

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

// Get all ranks for a skill SimpleSkillRank[] ranks = database.GetRanksForSkill("FIREBALL"); // Get max rank number int maxRank = database.GetMaxRank("FIREBALL"); // Get a specific rank from the skill struct SimpleSkillRank? rank2 = skill.GetRank(2); if (rank2.HasValue) { float damage = rank2.Value.GetNumericValue(0); SimpleSkillUpgradeCost[] costs = rank2.Value.upgradeCosts; } // Get the max rank from the skill struct int max = skill.GetMaxRank();

Reagent Costs vs. Upgrade Costs

Important distinction: 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:

SimpleSkillPrerequisite { string targetCode; // e.g., "FIREBALL", "PLAYER_LEVEL" SimpleSkillComparison comparison; // Equals, NotEquals, GreaterThan, LessThan, // GreaterOrEqual, LessOrEqual float value; // e.g., 3.0 (meaning "rank 3") }

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:

// Check if prerequisites are met bool canLearn = SimpleSkillHelper.CheckAllPrerequisites( skill, (code) => { // Return current rank for skill codes if (playerSkillRanks.ContainsKey(code)) return playerSkillRanks[code]; // Return player level for "PLAYER_LEVEL" if (code == "PLAYER_LEVEL") return playerLevel; return 0f; } ); // Query skills with a specific prerequisite SimpleSkillDefinition[] advancedFire = database.GetSkillsWithPrerequisite("FIREBALL");

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:

skill.IsItemGranted // grantedByItemCode is set skill.HasEquipmentRequirement // requiredEquipmentCode is set skill.ProducesItem // producesItemCode is set skill.HasReagentCosts // reagentCosts is non-empty skill.IsSummonSkill // summonEnemyCode is set skill.IsEnemyLearned // learnedFromEnemyCode is set skill.HasTrainer // taughtByNPCCode is set skill.HasFactionEffectiveness // effectiveAgainstFactions is non-empty skill.IsFactionRestricted // restrictedToFactionCode is set skill.IsQuestUnlocked // unlockedByQuestCode is set skill.IsQuestRewarded // rewardedByQuestCodes is non-empty skill.HasClassRestriction // allowedCharacterClasses is non-empty

Cross-Forge Queries

The ISimpleSkillDataSource interface provides reverse-lookup queries for all cross-forge fields:

// SIF queries database.GetSkillsGrantedByItem("TOME_OF_FIRE"); database.GetSkillsRequiringEquipment("IRON_BOW"); database.GetSkillsProducingItem("CONJURED_BREAD"); database.GetSkillsConsumingReagent("SOUL_SHARD"); // SEF queries database.GetSkillsSummoningEnemy("SKELETON_WARRIOR"); database.GetSkillsLearnedFromEnemy("BLUE_DRAGON"); database.GetSkillsTaughtByNPC("ARCHMAGE_THERON"); database.GetSkillsEffectiveAgainstFaction("UNDEAD"); database.GetSkillsRestrictedToFaction("ELF"); // SQF queries database.GetSkillsUnlockedByQuest("CLASS_TRIAL_MAGE"); database.GetSkillsRewardedByQuest("THE_ARCHMAGES_TRIAL");

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.

// Check class restriction bool hasRestriction = skill.HasClassRestriction; // Check if a specific class can use the skill bool canUse = skill.IsUsableByClass("Mage"); // true if unrestricted or "Mage" is in the list // Database-level queries SimpleSkillDefinition[] mageOnly = database.GetSkillsForClass("Mage"); // restricted TO Mage SimpleSkillDefinition[] mageUsable = database.GetSkillsUsableByClass("Mage"); // restricted TO Mage + unrestricted
Distinction: 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).