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.
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.
Enter a prefix for generated types (e.g., "WarFactions" generates
WarFactionsType.cs, WarFactionsDatabase.cs, etc.)
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).
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:
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 SimpleFactionHelper
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.
SimpleFactionDefinition
A single faction with identity, color, and dynamic properties.
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:
In practice, you should use the ISimpleFactionDataSource interface
methods rather than indexing the matrix directly.
ISimpleFactionDataSource
Interface implemented by generated faction databases.
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.