View Format: Multi-Page Single Page

Simple Enemy Forge

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

Behavior Forge

Behavior Forge defines condition-based action rules for enemy AI. Instead of hardcoding behavior trees or finite state machines, you author behavior profiles that map conditions to action codes. At runtime, the SimpleBehaviorEvaluator checks conditions against the current game state and returns the best action to take.

Conditions reuse the same SimpleSpawnCondition system from Spawn Forge, checking dynamic numeric properties against thresholds. Actions are user-defined string codes (like FLEE, HEAL, AOE_ATTACK) that your game code interprets.

Open it from Window → Simple Enemy Forge → Behavior Forge Wizard. The wizard has 4 steps: Setup, Definitions, Behavior Rules, and Generate.

How Behavior Profiles Work

A behavior profile is a named collection of rules. Each rule has conditions that check dynamic properties, an action code to trigger, a priority for conflict resolution, and an optional cooldown.

Behavior Profile: "Goblin Warrior AI" | +-- Rule 1: Priority 10, Cooldown 5s | Conditions: IF Health < 25% | Action: FLEE | +-- Rule 2: Priority 8, Cooldown 3s | Conditions: IF Ally Count < 2 AND Health < 50% | Action: CALL_REINFORCEMENTS | +-- Rule 3: Priority 5, Cooldown 0s | Conditions: IF Target Distance <= 2 | Action: MELEE_ATTACK | +-- Rule 4: Priority 3, Cooldown 0s | (No conditions — fallback) | Action: APPROACH_TARGET

When evaluated, the Goblin Warrior first checks if it should flee (highest priority). If health is fine, it checks whether to call reinforcements. If neither emergency applies, it attacks if in range, or approaches the target as a fallback.

Priority-Based Resolution

When multiple rules match the current conditions, the highest priority wins. Rules are evaluated in priority order (highest first), and the first matching rule is selected as the best action.

This creates a natural decision hierarchy:

  • Priority 10+ — Emergency behaviors (flee, heal when critical)
  • Priority 7-9 — Tactical behaviors (call reinforcements, use abilities)
  • Priority 4-6 — Combat behaviors (melee attack, ranged attack)
  • Priority 1-3 — Fallback behaviors (approach target, idle, patrol)

A rule with no conditions always matches, making it an ideal fallback at low priority.

Cooldown System

Each rule has a cooldown field (in seconds) that prevents the same action from triggering repeatedly. After a rule fires, it cannot match again until the cooldown expires. This is tracked per-rule at runtime.

Set cooldown to 0 for actions that should always be available (like basic attacks or movement). Use higher cooldowns for powerful abilities or behaviors that should not spam (like calling reinforcements every 10 seconds).

Step 1 — Setup

Configure the basics for your behavior database.

1 Class Prefix
Enter a prefix for generated types (e.g., "GoblinBehavior" generates GoblinBehaviorType.cs, GoblinBehaviorDatabase.cs, etc.)

Unlike Wave Forge or Squad Forge, Behavior Forge does not require linking to an Enemy Database. Behavior profiles are standalone — you assign them to enemies in your own code by matching profile codes to enemy types.

Step 2 — Definitions

Define the dynamic property system for your behavior profiles and the context properties that conditions check against.

Profile Properties

These properties are stored on each behavior profile:

  • Categories — Dropdown properties like AI Archetype, Aggression Level
  • Flags — Boolean toggles like Uses Ranged, Has Flee Behavior
  • Numerics — Number fields like Base Aggro Range, Evaluation Interval
  • Texts — String fields like Designer Notes, Behavior Description

Context Properties

Context properties define what the conditions can check against at runtime. These are the numeric values that your game provides in a SimpleSpawnContext when evaluating behavior. Examples include Health Percent, Ally Count, Target Distance, Mana Percent, or any game-state value.

This step also provides schema export and import for AI-assisted content creation.

Step 3 — Behavior Rules

Build your behavior profiles in a split-panel editor. The left panel shows a paginated list of profiles, and the right panel shows the selected profile's rules.

For each profile, you define:

  • Identity — Name, Code (auto-generated), Description
  • Rules — A ReorderableList of condition-action rules
  • Dynamic Properties — Values for categories, flags, numerics, and texts

For each rule within a profile:

  • Action Code — A string code your game interprets (e.g., FLEE, HEAL)
  • Priority — Integer priority for conflict resolution (higher wins)
  • Cooldown — Minimum seconds between triggers
  • Conditions — An array of SimpleSpawnCondition checks. Each condition tests a context numeric property against a threshold using a comparison operator (equals, not equals, less than, greater than, etc.). All conditions must pass for the rule to match.

Step 4 — Generate

Click Generate to create all output files using the standard two-phase process.

After generation, your project will contain:

Assets/ └─ Generated/ ├─ Behaviors/Scripts/ │ ├─ GoblinBehaviorType.cs (enum) │ ├─ GoblinBehaviorDatabase.cs (ScriptableObject) │ └─ Editor/ │ └─ GoblinBehaviorDatabaseEditor.cs (custom inspector) └─ Behaviors/Data/ └─ GoblinBehaviorDatabase.asset (your data)

The generated custom editor features a split-panel layout with search, sort, pagination, bulk operations, nested condition editing, and an "Open Behavior Forge Wizard" button for quick access back to the wizard.

Runtime Helper: SimpleBehaviorEvaluator

SimpleBehaviorEvaluator is a static helper class that evaluates behavior profile rules against a SimpleSpawnContext. It reuses SimpleSpawnEvaluator.EvaluateConditions since behavior conditions are the same SimpleSpawnCondition arrays used in Spawn Forge.

using SimpleEnemyForge; // Build a context with the current game state var context = new SimpleSpawnContext(); context.SetNumeric(0, healthPercent); // Context property 0: Health % context.SetNumeric(1, allyCount); // Context property 1: Ally Count context.SetNumeric(2, targetDistance); // Context property 2: Target Distance // Get the database and profile var db = behaviorDatabase as ISimpleBehaviorDataSource; var profile = db.GetBehaviorProfile("GOBLIN_WARRIOR_AI"); if (profile.HasValue) { // Get the best (highest priority) matching action SimpleBehaviorRule? best = SimpleBehaviorEvaluator.EvaluateBestAction( profile.Value, context); if (best.HasValue) { string action = best.Value.actionCode; // e.g., "FLEE" ExecuteAction(action); } // Or get ALL matching action codes, sorted by priority string[] actions = SimpleBehaviorEvaluator.GetMatchingActionCodes( profile.Value, context); // e.g., ["FLEE", "CALL_REINFORCEMENTS", "APPROACH_TARGET"] // Or get all matching rules with full detail SimpleBehaviorRule[] rules = SimpleBehaviorEvaluator.EvaluateProfile( profile.Value, context); }

Evaluator Methods

Method Returns Description
EvaluateBestAction(profile, context) SimpleBehaviorRule? Returns the highest-priority matching rule, or null if no rules match.
GetMatchingActionCodes(profile, context) string[] Returns all matching action codes sorted by priority descending.
EvaluateProfile(profile, context) SimpleBehaviorRule[] Returns all matching rules sorted by priority descending. Use this when you need access to full rule details (priority, cooldown, conditions).

Runtime Data Structures

SimpleBehaviorProfile

A named behavior profile containing condition-action rules and dynamic properties.

public struct SimpleBehaviorProfile { public string code; // Unique identifier (e.g., "AGGRESSIVE_MELEE") public string name; // Display name public string description; // Description public SimpleBehaviorRule[] rules; // Rules evaluated in priority order // Dynamic properties public int[] categoryValues; public bool[] flagValues; public float[] numericValues; public string[] textValues; }

SimpleBehaviorRule

A single rule that maps conditions to an action code.

public struct SimpleBehaviorRule { public SimpleSpawnCondition[] conditions; // Conditions that must pass public string actionCode; // Action to trigger (e.g., "HEAL", "FLEE") public int priority; // Higher wins when multiple rules match public float cooldown; // Minimum seconds between triggers }

ISimpleBehaviorDataSource

Interface implemented by generated behavior databases.

public interface ISimpleBehaviorDataSource { int ProfileCount { get; } SimpleBehaviorProfile[] GetBehaviorProfiles(); SimpleBehaviorProfile? GetBehaviorProfile(string code); string[] GetProfileCodes(); string[] GetProfileNames(); }

Tips

Always Include a Fallback

Add a low-priority rule with no conditions as the last rule in every profile. This ensures the evaluator always returns an action, even when no other conditions match. Use actions like IDLE or APPROACH_TARGET.

Use Priorities Wisely

Reserve high priorities (10+) for emergency behaviors like fleeing or healing. Mid-range (5-9) for tactical decisions. Low priorities (1-4) for default combat and movement. This creates clear decision hierarchies.

Keep Cooldowns Reasonable

Set cooldown to 0 for always-available actions (basic attacks, movement). Use 3-10 seconds for abilities and special moves. Use 10+ seconds for powerful or dramatic behaviors (calling reinforcements, enraging).

Test with the Evaluator

Use the Bestiary Demo's Behavior tab to test profiles with different context values interactively. Build a SimpleSpawnContext with test values and verify which actions trigger under different scenarios.