View Format: Multi-Page Single Page

Simple Enemy Forge

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

Faction Forge

Faction Forge defines factions with an N×N relationship matrix that determines how factions interact with each other. Each pair of factions has a stance ranging from Allied to Hostile, enabling your game to query whether two entities should fight, cooperate, or ignore each other.

Each faction also supports dynamic properties (Categories, Flags, Numerics, Texts) for storing custom metadata like faction traits, reputation thresholds, or territorial boundaries.

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

The Relationship Matrix

The relationship matrix is an N×N grid where each cell defines the stance between two factions. The matrix is symmetric — if Humans are Hostile toward Orcs, then Orcs are automatically Hostile toward Humans.

Humans Elves Orcs Undead Humans Allied Friendly Hostile Hostile Elves Friendly Allied Hostile Hostile Orcs Hostile Hostile Allied Neutral Undead Hostile Hostile Neutral Allied

Key properties of the matrix:

  • Symmetric — When you set A→B to Hostile, B→A is automatically set to Hostile as well
  • Self-relationship is always Allied — A faction is always allied with itself (the diagonal)
  • Stored as a flat list — The N×N matrix is stored as a flat List<int> in row-major order for efficient serialization

The matrix grows quadratically with faction count. 4 factions produce a 4×4 matrix (16 cells), 10 factions produce a 10×10 matrix (100 cells). Due to symmetry, only N×(N-1)/2 unique relationships need to be defined.

The 5 Stances

Faction Forge uses the SimpleFactionStance enum with 5 possible stances, stored as integer values from -2 to 2:

Stance Value Meaning
Hostile -2 Openly hostile — attack on sight, maximum aggression
Unfriendly -1 Negative disposition — may attack under certain conditions
Neutral 0 Indifferent — won't attack unprovoked, won't assist
Friendly 1 Positive disposition — will not attack, may cooperate
Allied 2 Same side — full cooperation, shared resources and information

The numeric values allow easy comparison. Stances less than 0 are negative, 0 is neutral, and greater than 0 are positive. This makes range checks straightforward in game code.

Step 1 — Setup

Configure the basics and optionally link enemy databases.

1 Class Prefix
Enter a prefix for generated types (e.g., "WarFactions" generates WarFactionsType.cs, WarFactionsDatabase.cs, etc.)
2 Enemy Databases (Optional)
Link Enemy Database ScriptableObjects if you want to reference enemy codes within faction data. This is optional — factions work independently.

Step 2 — Definitions

Define the dynamic property system for your factions. These properties are attached to each faction definition, letting you store custom metadata.

  • Categories — Dropdown properties like Government Type, Alignment, Territory Size
  • Flags — Boolean toggles like Is Playable, Has Territory, Is Hidden
  • Numerics — Number fields like Reputation Threshold, Military Strength, Population
  • Texts — String fields like Lore, Capital City, Leader Name

This step also provides schema export and import for AI-assisted content creation. The schema includes the relationship matrix, which round-trips through JSON import with full symmetric validation.

Step 3 — Factions

Build your factions in a split-panel editor. The left panel shows the faction list, and the right panel shows the selected faction's details.

Identity

Each faction has a Name, Code (auto-generated from name), and Description.

Dynamic Properties

All four property sections (Categories, Flags, Numerics, Texts) are always visible with values for each property defined in Step 2.

Relationships

The relationships section shows a stance dropdown for every other faction in the database. When you change A's stance toward B, B's stance toward A is automatically updated to match (symmetric write).

Relationships for "Humans": Elves [Friendly v] Orcs [Hostile v] Undead [Hostile v] Dwarves [Allied v]

Adding or removing a faction automatically expands or shrinks the relationship matrix for all existing factions.

Step 4 — Generate

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

After generation, your project will contain:

Assets/ └─ Generated/ ├─ Factions/Scripts/ │ ├─ WarFactionsType.cs (enum) │ ├─ WarFactionsDatabase.cs (ScriptableObject) │ └─ Editor/ │ └─ WarFactionsDatabaseEditor.cs (custom inspector) └─ Factions/Data/ └─ WarFactionsDatabase.asset (your data)

The generated custom editor features a split-panel layout with search, sort, pagination, bulk operations, dynamic property editing, and per-faction relationship editing with symmetric matrix writes.

Runtime Helper: SimpleFactionHelper

SimpleFactionHelper is a static helper class that provides convenience methods for querying faction relationships beyond what ISimpleFactionDataSource offers directly.

Using the Interface Directly

using SimpleEnemyForge; var db = factionDatabase as ISimpleFactionDataSource; // Get the stance between two factions SimpleFactionStance stance = db.GetRelationship("HUMANS", "ORCS"); // stance = SimpleFactionStance.Hostile (-2) // Check specific relationships bool hostile = db.IsHostile("HUMANS", "ORCS"); // true bool allied = db.IsAllied("HUMANS", "ELVES"); // false bool friendly = db.IsFriendly("HUMANS", "ELVES"); // true (Friendly or Allied) // Get all factions hostile to Humans string[] enemies = db.GetHostileFactions("HUMANS"); // ["ORCS", "UNDEAD"] // Get all factions allied with Humans string[] allies = db.GetAlliedFactions("HUMANS"); // ["DWARVES"]

Using SimpleFactionHelper

using SimpleEnemyForge; var db = factionDatabase as ISimpleFactionDataSource; // Check if hostile or unfriendly (stance < Neutral) bool isEnemy = SimpleFactionHelper.IsHostileOrUnfriendly(db, "HUMANS", "ORCS"); // true // Check if friendly or allied (stance > Neutral) bool isFriend = SimpleFactionHelper.IsFriendlyOrAllied(db, "HUMANS", "ELVES"); // true // Get the numeric stance value (-2 to 2) int stanceValue = SimpleFactionHelper.GetStanceValue(db, "HUMANS", "ORCS"); // -2 // Get all factions with a specific stance toward a faction string[] hostiles = SimpleFactionHelper.GetFactionsWithStance( db, "HUMANS", SimpleFactionStance.Hostile); // ["ORCS", "UNDEAD"] // Get all non-hostile factions (Unfriendly, Neutral, Friendly, or Allied) string[] nonHostile = SimpleFactionHelper.GetNonHostileFactions(db, "HUMANS"); // ["ELVES", "DWARVES"]

Helper Methods

Method Returns Description
IsHostileOrUnfriendly(db, codeA, codeB) bool True if stance is Hostile or Unfriendly (value < 0).
IsFriendlyOrAllied(db, codeA, codeB) bool True if stance is Friendly or Allied (value > 0).
GetStanceValue(db, codeA, codeB) int Returns the numeric stance value from -2 (Hostile) to 2 (Allied).
GetFactionsWithStance(db, code, stance) string[] Returns all faction codes that have the exact specified stance toward the given faction.
GetNonHostileFactions(db, code) string[] Returns all faction codes with stance of Unfriendly or higher (not Hostile).

Runtime Data Structures

SimpleFactionStance (Enum)

The stance enum with integer values for easy comparison.

public enum SimpleFactionStance { Hostile = -2, // Attack on sight Unfriendly = -1, // May attack under conditions Neutral = 0, // Indifferent Friendly = 1, // Won't attack, may cooperate Allied = 2 // Full cooperation }

SimpleFactionDefinition

A single faction with identity, color, and dynamic properties.

public struct SimpleFactionDefinition { public string code; // Unique identifier (e.g., "UNDEAD") public string name; // Display name (e.g., "The Undead") public string description; // Description public Color color; // Editor display color // Dynamic properties public int[] categoryValues; public bool[] flagValues; public float[] numericValues; public string[] textValues; }

Relationship Matrix

The relationship matrix is stored as a flat List<int> in row-major order. For N factions, the matrix has N×N entries. To get the stance from faction index A to faction index B:

// Row-major indexing int stanceValue = relationshipMatrix[factionIndexA * factionCount + factionIndexB]; SimpleFactionStance stance = (SimpleFactionStance)stanceValue;

In practice, you should use the ISimpleFactionDataSource interface methods rather than indexing the matrix directly.

ISimpleFactionDataSource

Interface implemented by generated faction databases.

public interface ISimpleFactionDataSource { // Faction access int FactionCount { get; } string[] GetFactionNames(); string[] GetFactionCodes(); SimpleFactionDefinition[] GetFactionDefinitions(); // Relationship queries SimpleFactionStance GetRelationship(string codeA, string codeB); SimpleFactionStance GetRelationship(int indexA, int indexB); // Convenience helpers bool IsHostile(string codeA, string codeB); bool IsAllied(string codeA, string codeB); bool IsFriendly(string codeA, string codeB); string[] GetHostileFactions(string factionCode); string[] GetAlliedFactions(string factionCode); // Metadata access string[] GetCategoryLabels(); string[] GetCategoryEntries(int categoryIndex); string[] GetFlagNames(); string[] GetNumericNames(); string[] GetTextNames(); }

Tips

Start with 3-4 Factions

Begin with a small number of factions to keep relationships manageable. You can always add more later — the matrix expands automatically. A classic setup might be Players, Neutral Wildlife, Enemy Horde, and Undead.

Leverage Symmetric Writes

The wizard and generated editor both enforce symmetric relationships automatically. When you set Humans→Orcs to Hostile, Orcs→Humans is updated to match. You only need to define each relationship once.

Use Dynamic Properties for Traits

Store faction-specific metadata in dynamic properties. Use numerics for Military Strength or Reputation Threshold, categories for Government Type or Alignment, and texts for lore, leader names, or capital cities.

Matrix Grows Quadratically

The relationship matrix has N×N cells. 5 factions produce 25 cells (manageable), but 20 factions produce 400 cells. Keep faction count reasonable for your game's needs — most games work well with 4-8 factions.