View Format: Multi-Page Single Page

Simple Skill Forge

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

Cross-Forge Integration

Simple Skill Forge integrates with 4 companion packages from the Simple Forge 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.

PackagePackage IDWhat 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:

"versionDefines": [ { "name": "com.livingfailure.simple-attribute-forge", "expression": "", "define": "SIMPLE_ATTRIBUTE_FORGE" }, { "name": "com.livingfailure.simple-item-forge", "expression": "", "define": "SIMPLE_ITEM_FORGE" }, { "name": "com.livingfailure.simple-enemy-forge", "expression": "", "define": "SIMPLE_ENEMY_FORGE" }, { "name": "com.livingfailure.simple-quest-forge", "expression": "", "define": "SIMPLE_QUEST_FORGE" } ]

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:

// Example: SIFBridge probes for item data source var type = Type.GetType("SimpleItemForge.ISimpleItemDataSource, SimpleItemForge.Runtime"); if (type != null) { IsAvailable = true; GetItemCodes = (db) => (string[])type.GetMethod("GetItemCodes").Invoke(db, null); }

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:

FieldTypePurposeExample
grantedByItemCodestring Item that teaches/grants this skill Skill books, scrolls, equipment passives, gem sockets
requiredEquipmentCodestring Item that must be equipped to use this skill Bow for arrow skills, staff for magic, specific weapon types
producesItemCodestring Item created when skill is used Conjure food, crafting skills, transmutation, gathering yields
reagentCosts[]SimpleSkillReagentCost[] Items consumed per cast Arrows, soul shards, catalysts, reagents
Note: Reagent costs are different from SimpleSkillUpgradeCost (which defines costs to level up a skill rank). Reagents are consumed every time the skill is cast.

Runtime Queries

// Find all skills that require a specific item equipped var bowSkills = db.GetSkillsRequiringEquipment("LONGBOW"); // Find all skills that consume a specific reagent var arrowSkills = db.GetSkillsConsumingReagent("IRON_ARROW");

Simple Enemy Forge (SEF)

When SEF is detected, the Skill Forge builder shows 5 cross-forge reference fields:

FieldTypePurposeExample
summonEnemyCodestring Enemy summoned by this skill Necromancer minions, pet classes, conjured creatures
learnedFromEnemyCodestring Enemy that teaches this skill Blue Mage skills, Enemy Skill materia, monster absorption
taughtByNPCCodestring 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
restrictedToFactionCodestring Only characters of this faction can use the skill Racial abilities, covenant skills, guild techniques
In SEF, NPCs are represented as enemy definitions. The taughtByNPCCode field references an enemy code from the SEF database.

Runtime Queries

// Find all skills learned from a specific enemy var blueSkills = db.GetSkillsLearnedFromEnemy("FIRE_DRAGON"); // Find all skills effective against a faction var antiUndead = db.GetSkillsEffectiveAgainstFaction("UNDEAD");

Simple Quest Forge (SQF)

When SQF is detected, the Skill Forge builder shows 2 cross-forge reference fields:

FieldTypePurposeExample
unlockedByQuestCodestring 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

// Find all skills unlocked by completing a quest var questSkills = db.GetSkillsUnlockedByQuest("ARCHMAGE_TRIAL"); // Find all skills rewarded by a quest var rewards = db.GetSkillsRewardedByQuest("DRAGON_SLAYER_QUEST");

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 allowedCharacterClasses array means the entry is unrestricted (usable by all classes)
  • A non-empty array means the entry is restricted to listed classes only

Runtime API

// Check if a skill has class restrictions if (skill.HasClassRestriction) Debug.Log($"Restricted to: {string.Join(", ", skill.allowedCharacterClasses)}"); // Check if a specific class can use a skill bool canUse = skill.IsUsableByClass("Warrior"); // Query: get all skills usable by a class (restricted to that class + unrestricted) var warriorSkills = db.GetSkillsUsableByClass("Warrior"); // Same pattern works for trees, sets, and combos var warriorTrees = treeDb.GetTreesAvailableToClass("Warrior"); var warriorSets = setDb.GetSetsAvailableToClass("Warrior"); var warriorCombos = comboDb.GetCombosAvailableToClass("Warrior");