View Format: Multi-Page Single Page

Simple Skill Forge

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

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:

Window > Living Failure > Simple Skill Forge > Skill Combo Forge

Key features:

  • Ordered steps with sortOrder sequencing
  • Required and optional steps
  • Alternate skill choices per step (alternateSkillCodes[])
  • Branch groups for OR-alternative step paths
  • Per-step timing windows (maxDelay in 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

// Get all steps for a combo SimpleSkillComboStep[] steps = database.GetStepsForCombo("ELEMENTAL_BURST"); // Convenience accessors on the combo struct int stepCount = combo.StepCount; SimpleSkillComboStep? step = combo.GetStepByIndex(0); // Check if the combo contains a specific skill (primary or alternates) bool hasFireball = combo.ContainsSkill("FIREBALL"); // Get all unique skill codes from all steps string[] allSkills = combo.GetAllSkillCodes(); // Find steps that match a specific skill code SimpleSkillComboStep[] matching = combo.FindStepsBySkillCode("FIREBALL"); // Find all combos containing a skill SimpleSkillComboDefinition[] combosWithFireball = database.FindCombosContainingSkill("FIREBALL"); // Find combos whose first step matches a skill SimpleSkillComboDefinition[] combosStarting = database.FindCombosStartingWith("SLASH");

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

// Get all rewards for a combo SimpleSkillComboReward[] rewards = database.GetRewardsForCombo("ELEMENTAL_BURST"); // Convenience accessors on the combo struct int rewardCount = combo.RewardCount; // Get all rewards active at a given step count (stacking) SimpleSkillComboReward[] active = combo.GetActiveRewards(completedStepCount: 3);

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.

// Access combo-level properties int comboType = combo.GetCategoryValue(0); bool isFinisher = combo.GetFlagValue(0); float damageMultiplier = combo.GetNumericValue(0); string description = combo.GetTextValue(0); // Get property definition labels string[] catLabels = database.GetCategoryLabels(); // e.g., ["Combo Type", "Element"] string[] catEntries = database.GetCategoryEntries(0); // e.g., ["Chain", "Rotation", "Reaction"] string[] flagNames = database.GetFlagNames(); // e.g., ["Is Finisher", "Requires Airborne"] string[] numNames = database.GetNumericNames(); // e.g., ["Damage Multiplier", "Cooldown Reduction"] string[] textNames = database.GetTextNames(); // e.g., ["Combo Description", "Flavor Text"] // Filter combos by property values SimpleSkillComboDefinition[] chains = database.GetCombosByCategory(0, 0); SimpleSkillComboDefinition[] finishers = database.GetCombosByFlag(0, true); SimpleSkillComboDefinition[] highDamage = database.GetCombosByNumericRange(0, 1.5f, 10f);

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

// Create a tracker from your combo database var tracker = new SimpleSkillComboTracker(comboDatabase);

Feeding Skill Usage

// Call OnSkillUsed whenever the player casts a skill // The tracker evaluates ALL combos simultaneously tracker.OnSkillUsed("SLASH", Time.time); tracker.OnSkillUsed("UPPERCUT", Time.time); tracker.OnSkillUsed("SLAM", Time.time);

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

// Get all active combo states SimpleActiveComboState[] active = tracker.GetActiveComboStates(); // Get the number of active combos int count = tracker.GetActiveComboCount(); // Check if a specific combo is active bool isActive = tracker.IsComboActive("ELEMENTAL_BURST"); // Get completion progress (0 to 1) float progress = tracker.GetComboProgress("ELEMENTAL_BURST"); // Manually drop a combo tracker.DropCombo("ELEMENTAL_BURST"); // Drop all active combos tracker.DropAllCombos();

Events

tracker.OnComboStarted += (comboCode) => Debug.Log($"Combo started: {comboCode}"); tracker.OnComboProgressed += (comboCode, currentStep, totalSteps) => Debug.Log($"Combo {comboCode}: {currentStep}/{totalSteps}"); tracker.OnComboCompleted += (comboCode) => Debug.Log($"Combo complete: {comboCode}"); tracker.OnComboDropped += (comboCode, reason) => Debug.Log($"Combo dropped: {comboCode} ({reason})"); tracker.OnRewardTriggered += (comboCode, rewardIndex) => Debug.Log($"Reward {rewardIndex} triggered in {comboCode}");

Snapshots (Save/Load)

// Save current state (including mid-combo progress) SimpleComboTrackerSnapshot snapshot = tracker.CreateSnapshot(); string json = JsonUtility.ToJson(snapshot); // Load state var loaded = JsonUtility.FromJson<SimpleComboTrackerSnapshot>(json); tracker.RestoreFromSnapshot(loaded);

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

// Evaluate how well a sequence of skills matches a combo string[] usedSkills = { "FIREBALL", "ICE_BOLT", "LIGHTNING_STRIKE" }; ComboEvalResult result = SimpleSkillComboEvaluator.EvaluateCombo(combo, usedSkills); // Result fields: result.matchedStepCount; // 3 result.totalStepCount; // 4 result.completionPercentage; // 0.75 result.isComplete; // false result.nextValidSkillCodes; // ["ARCANE_BLAST"] (what to cast next)

Getting Next Valid Skills

// Get skills that would advance the combo from a given position string[] nextSkills = SimpleSkillComboEvaluator.GetNextValidSkills(combo, completedStepCount: 2); // Returns the primary skillCode + all alternateSkillCodes for step at index 2

This is especially useful for UI hints ("Cast one of these skills to continue the combo") and AI skill selection.

Finding Matching Combos

// Find all combos that partially or fully match a recent skill sequence string[] recentSkills = { "SLASH", "UPPERCUT" }; ComboMatch[] matches = SimpleSkillComboEvaluator.FindMatchingCombos(comboDatabase, recentSkills); foreach (var match in matches) { Debug.Log($"{match.comboCode}: {match.matchedSteps}/{match.totalSteps}" + (match.isComplete ? " COMPLETE" : "")); }

Quick Checks

// Check if a combo is fully complete bool complete = SimpleSkillComboEvaluator.IsComboComplete(combo, usedSkills); // Get completion progress (0 to 1) float progress = SimpleSkillComboEvaluator.GetComboProgress(combo, usedSkills); // Get active rewards for a step count SimpleSkillComboReward[] rewards = SimpleSkillComboEvaluator.GetActiveRewards(combo, completedStepCount: 3);

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