Entities & Relationships
An Entity is anything that can participate in relationships. All entities implement the IRelationshipEntity interface:
- EntityId — Stable unique identifier (deterministic, survives sessions)
- EntityName — Display name for UI and logs
- EntityIcon — Optional visual representation
- EntityType — Character, Faction, or Custom
A Relationship is a numeric value between two entities, optionally scoped to a specific definition. Relationships are stored as RelationshipState objects with a current value, level, lock state, and definition reference.
Entity Types
Characters
GameObject with CharacterRelationship component
Factions (SO)
ScriptableObject — defined at edit time
Runtime Factions
Created dynamically at runtime
Relationship Definitions
A RelationshipDefinition is a ScriptableObject template that defines how a relationship type behaves. One definition can be shared across many entity pairs.
Min/max values (e.g., -100 to +100) and initial value for new relationships
Named tiers with thresholds, colors, and optional GC2 onEnter/onExit actions
Symmetric (A↔B, default) or Asymmetric (A→B ≠ B→A) per definition
Optional decay with Linear, Curve, or Asymmetric modes
Optional audit log with configurable buffer size per definition
GC2 Stats integration (optional)
Symmetric & Asymmetric Relationships
Symmetric (Default)
isSymmetric = true
A's relationship with B equals B's relationship with A. Entity IDs are sorted — modifying from either direction changes the same value.
Player ↔ Merchant: 75
// Same value regardless of directionAsymmetric (Opt-in)
isSymmetric = false
A→B and B→A are independent values. Entity order is preserved — each direction is a separate relationship.
Player → Companion: 80 (Player trusts)
Companion → Player: 45 (Companion wary)Multi-Dimensional Relationships
The same entity pair can have multiple independent relationships, each scoped to a differentRelationshipDefinition. This enables separate dimensions like trade reputation and personal trust between the same characters.
Player ↔ Merchant:
├─ "Trade Reputation" → 80 (Trusted)
├─ "Personal Trust" → 30 (Cautious)
└─ "Guild Standing" → 60 (Respected)
// Each dimension is independent with its own levels and decayRelationship Levels
Levels are named tiers based on value thresholds, defined per RelationshipDefinition. They enable gameplay changes at specific reputation milestones.
Example: Merchant Reputation
Each level has a threshold value, display name, color, and optional GC2 InstructionLists for onEnter/onExit actions. Level transitions fire OnRelationshipLevelChanged events.
Factions & Inheritance
Factions group characters for collective reputation management. They are ScriptableObjects that implement IRelationshipEntity, meaning factions themselves can have relationships with other factions or characters.
Parent/child relationships with configurable inheritance rates
Automatic membership via GameObject tags
Modify all faction members at once
Factions use asset-based GUID for reliable persistence across sessions
Faction Hierarchies
Kingdom (Parent)
├─ Royal Guards (Child — inheritanceRate: 0.7)
│ ├─ Captain
│ └─ Guard #1
└─ Merchants Guild (Child — inheritanceRate: 0.3)
└─ Guild Master
Player attacks Guard #1:
1. Royal Guards → Player: -75 (broadcast)
2. Kingdom → Player: -52.5 (70% from Royal Guards)
3. Merchants Guild observes: -15.75 (30% of Kingdom)Configurable Inheritance
Each faction controls how much of its parent's relationships it inherits:
| Property | Description |
|---|---|
| inheritanceRate | 0.0–1.0. How much of parent's value to inherit (0 = none, 1 = full) |
| dynamicInheritance | If true, parent values are scaled on every lookup. If false, only when the child relationship is first created. |
| inheritOnFirstInteraction | If true, create child relationships from parent on first interaction with unknown entities |
| propagateToChildren | None, OnChange (every change), or OnLevelChange (level transitions only) |
Stable Entity IDs
The system uses deterministic entity IDs to ensure save/load reliability across play sessions. The old GUID-based system is replaced with three ID modes:
Designer sets the ID in the Inspector. Best for scene entities (key NPCs, named characters).
References an EntityIdAsset ScriptableObject. Best for prefab entities that are spawned or pooled.
Generated from scene name + hierarchy path + name. Editor warning when this mode is active.
Factions use their AssetDatabase GUID (serialized in m_StableId) for stability across builds. If a relationship is loaded before the target entity registers, it enters a pending queue and is applied automatically once the entity becomes available.