View Format: Multi-Page Single Page

Simple Enemy Forge

Generate Complete Enemy Databases, Squads, Spawn Tables, and More in Minutes.

Scaling Forge

Scaling Forge creates profiles that define how enemy numeric properties (HP, ATK, DEF, Speed, etc.) change as a function of level or difficulty. Instead of manually entering stat values for every level, you define a formula and let the math do the work.

Each scaling profile contains rules — one per numeric property you want to scale. A profile is typically paired with an enemy code (e.g., the "GOBLIN_WARRIOR" profile scales HP, ATK, and DEF for goblins), but you can also create shared profiles like "DEFAULT_SCALING" that apply to many enemies.

Open the wizard via Window › Simple Enemy Forge › Scaling Forge Wizard.

Scaling Forge has 3 steps: Setup, Scaling Rules, Generate. There is no Definitions step — Scaling Forge reads its numeric property names directly from the linked Enemy Database.

The 6 Scaling Types

Each scaling rule specifies one of six types that determines how the base value transforms with level:

Type Formula Use Case
None value = base No scaling — value stays constant at all levels
Linear base + (level - 1) * increment Steady, predictable progression. Good for HP, basic stats.
Percentage base * (1 + (level - 1) * percentage / 100) Proportional growth. Higher base values scale faster in absolute terms.
Exponential base * pow(exponentialBase, level - 1) Rapid power growth. Use sparingly — values explode quickly.
Curve base + curve.Evaluate(level / maxLevel) * multiplier Full control via AnimationCurve. Design any progression shape.
Step Lookup table of (level, value) pairs Manual breakpoints. At level X, value becomes Y. No interpolation.

Formula Examples

Linear

// HP scaling: base=100, increment=25 // Level 1: 100 + (1-1) * 25 = 100 // Level 5: 100 + (5-1) * 25 = 200 // Level 10: 100 + (10-1) * 25 = 325

Percentage

// ATK scaling: base=50, percentage=15 // Level 1: 50 * (1 + 0 * 0.15) = 50 // Level 5: 50 * (1 + 4 * 0.15) = 80 // Level 10: 50 * (1 + 9 * 0.15) = 117.5

Exponential

// Gold reward scaling: base=10, exponentialBase=1.2 // Level 1: 10 * pow(1.2, 0) = 10 // Level 5: 10 * pow(1.2, 4) = 20.74 // Level 10: 10 * pow(1.2, 9) = 51.60

Step

// Defense tier scaling: manual breakpoints // Steps: (1, 10), (5, 25), (10, 50), (20, 100) // Level 1: 10 // Level 3: 10 (no step at 3, uses level 1 value) // Level 7: 25 (uses level 5 step) // Level 15: 50 (uses level 10 step) // Level 20: 100

Step 1 — Setup

Link Enemy Database

Scaling Forge requires exactly one Enemy Database. The wizard reads the database's numeric property names (e.g., HP, ATK, DEF, Speed) and uses them as the target properties for scaling rules. If your Enemy Database has no numeric properties defined, you will need to add some in Enemy Forge first.

Output Configuration

Field Description Example
Database Name Display name for the generated asset My Scaling Profiles
Type Prefix Prefix for generated C# types My
Namespace C# namespace for generated code MyGame.Data

Step 2 — Scaling Rules

The main editing step uses a split-panel layout:

Left Panel — Profile List

  • Search — Filter profiles by name or code
  • Sort — Sort alphabetically by name or code
  • Multi-select — Checkbox selection for bulk operations
  • Pagination — Toggle between Show All and paginated view

Right Panel — Profile Editor

Select a profile from the list to edit:

Identity

Name, Code (with Auto toggle), and Description.

Rules

Each profile contains a ReorderableList of rules. Each rule targets one numeric property from the linked Enemy Database:

Field Description
Target Property Dropdown of numeric property names from the enemy database (HP, ATK, DEF, etc.)
Scaling Type Dropdown: None, Linear, Percentage, Exponential, Curve, Step

The remaining fields change based on the selected scaling type:

Scaling Type Visible Parameters
None (no parameters)
Linear increment — value added per level
Percentage percentage — percent increase per level
Exponential exponentialBase — base of the exponentiation
Curve curve (AnimationCurve), curveMultiplier, curveMaxLevel
Step steps — ReorderableList of (level, value) pairs, sorted by level

Formula HelpBox

Below each rule, a HelpBox displays the active equation using the rule's current parameters. This makes it easy to verify your math at a glance:

// Example HelpBox contents: Linear: base + (level - 1) * 25.0 Percentage: base * (1 + (level - 1) * 15.0 / 100) Exponential: base * pow(1.2, level - 1) Step: lookup table with 4 entries

Slider Preview

At the bottom of the profile editor, an IntSlider lets you pick a preview level. A 5-column table shows the scaling results for every rule in the profile:

Column Description
Property The numeric property name
Type The scaling type (Linear, Exponential, etc.)
Base The unscaled base value from the enemy database
Scaled The computed value at the selected level
Change Delta percentage from base (e.g., +150%)

This gives you immediate visual feedback on how your scaling rules behave across the level range.

Step 3 — Generate

Same two-phase generation as all forges:

1 Phase 1 — Generate Scripts
Writes C# source files, triggers AssetDatabase.Refresh() and domain reload.
2 Phase 2 — Create Asset
[InitializeOnLoad] handler creates the ScriptableObject from temporary JSON data.

Generated Files

File Description
{Prefix}ScalingType.cs Enum with one entry per scaling profile code
{Prefix}ScalingDatabase.cs ScriptableObject implementing ISimpleScalingDataSource
Editor/{Prefix}ScalingDatabaseEditor.cs Custom Inspector with split panel, slider preview, nested rules with foldouts
{Prefix}ScalingDatabase.asset The data asset

Runtime Helper — SimpleScalingHelper

A static utility class that computes scaled values using the same formulas as the generated databases. Use this when you need to scale values outside of the database's GetScaledValue method.

ComputeScaledValue

// Apply a single scaling rule to a base value float scaledHP = SimpleScalingHelper.ComputeScaledValue(rule, baseHP, level);

ScaleAllNumerics

// Scale an entire array of numeric values using a profile // Returns a NEW array - never mutates the input float[] baseValues = new float[] { 100f, 50f, 30f }; // HP, ATK, DEF float[] scaledValues = SimpleScalingHelper.ScaleAllNumerics(profile, baseValues, level);

ScaleEnemy

// Scale an enemy's numeric values using a scaling profile. // Returns a new float array of scaled numerics — does not modify the enemy struct. float[] scaled = SimpleScalingHelper.ScaleEnemy(enemy, profile, level); // Overload with difficulty multiplier (useful for wave loop scaling). // All scaled values are multiplied by the difficulty multiplier after scaling. float[] scaledHard = SimpleScalingHelper.ScaleEnemy(enemy, profile, level, 1.2f);

Using the Generated Database Directly

// The generated database also implements GetScaledValue directly ISimpleScalingDataSource scalingDB = myScalingDatabase as ISimpleScalingDataSource; // Get a scaled value for a specific profile, property, and level float scaledHP = scalingDB.GetScaledValue("GOBLIN_WARRIOR", 0, baseHP, level); // Parameters: profileCode, numericIndex, baseValue, level // Get the numeric property names to find the right index string[] numericNames = scalingDB.GetNumericNames(); int hpIndex = System.Array.IndexOf(numericNames, "HP"); float scaledHP2 = scalingDB.GetScaledValue("GOBLIN_WARRIOR", hpIndex, baseHP, level);

Runtime Data Structures

SimpleScalingStep

public struct SimpleScalingStep { public int level; // Level at which this value takes effect public float value; // The value to use (absolute, not additive) }

SimpleScalingRule

public struct SimpleScalingRule { public int numericIndex; // Index into enemy database's numeric definitions public SimpleScalingType scalingType; // None, Linear, Percentage, Exponential, Curve, Step // Linear parameters public float increment; // Value added per level // Percentage parameters public float percentage; // Percent increase per level // Exponential parameters public float exponentialBase; // Base of exponentiation // Curve parameters public AnimationCurve curve; // Mapping normalized level (0-1) to multiplier public float curveMultiplier; // Scales the curve output public int curveMaxLevel; // Maximum level for normalization // Step parameters public SimpleScalingStep[] steps; // Level-value lookup table }

SimpleScalingProfile

public struct SimpleScalingProfile { public string code; // Unique identifier (e.g., "GOBLIN_WARRIOR") public string name; // Display name public string description; // Optional description public SimpleScalingRule[] rules; // Rules for individual numeric properties }

Interface Reference — ISimpleScalingDataSource

Member Returns Description
ProfileCount int Total number of scaling profiles
GetScalingProfiles() SimpleScalingProfile[] Get all scaling profiles
GetScalingProfile(string code) SimpleScalingProfile? Get a profile by code, or null if not found
GetProfileCodes() string[] Get all profile codes
GetNumericNames() string[] Get numeric property names (copied from enemy DB at generation time)
GetScaledValue(string profileCode, int numericIndex, float baseValue, int level) float Compute the scaled value for a specific profile, property, base value, and level

Tips

Start with Linear

Linear scaling is the easiest to understand and balance. Start there for most stats (HP, ATK, DEF), then switch to other types only when you need specific curve shapes. Percentage is a natural next step for proportional growth.

Use Step for Manual Control

Step scaling gives you complete control over exact values at specific levels. It is ideal for tier-based systems (Bronze/Silver/Gold) or when designers need to hand-tune specific breakpoints rather than rely on formulas.

Preview with the Slider

Always use the slider preview to check your scaling at extreme levels. A formula that looks fine at level 10 might produce absurd values at level 50. The Change% column makes it easy to spot runaway scaling.

Test at Extremes

Check level 1 (should match base values), your expected mid-game level, and your max level. Exponential scaling in particular can produce values that break game balance if the exponentialBase is too high. A value of 1.05-1.15 is usually safe.