Skip to content

Aspect Data Model Architecture

Status: RESOLVED — July 19, 2026


Data Model

AspectDefinition (ScriptableObject)

Designer-editable in Unity Inspector. One asset per aspect.

AspectDefinition
├── id: string ("aspect.knight.key")
├── displayName: string ("Knight")
├── slotType: enum (Key, Function, Movement, Defense, Utility)
├── rarity: enum (Common, Uncommon, Rare, Legendary)
├── icon: Sprite
├── description: string
├── abilities[]: List<AbilityDefinition>
│   ├── abilityId: string
│   ├── tier: int (0=base, 1, 2, 3)
│   └── abilityData: AbilityData
├── keyStats: StatBlock?  // ONLY for Key Aspects. Flex slots have no stats.
│   ├── hp: int
│   ├── atk: int
│   ├── mag: int
│   ├── def: int
│   └── spd: int
└── synergyTags[]: List<string>  // for explicit synergy lookup

Stat System

  • No stat stacking. Flex aspects (Function, Movement, Defense, Utility) do NOT provide stat modifiers.
  • Unit stats = Key Aspect base stats + level-up bonuses + equipment.
  • This avoids the stacking question entirely. Build identity comes from abilities, not stat math.

AspectInstance (Runtime)

AspectInstance
├── definition: AspectDefinition
├── currentTier: int
├── unlockedAbilityIds[]: List<string>
└── slotIndex: int (0-4)

UnitData (Runtime)

UnitData
├── unitId: string
├── characterDef: CharacterDefinition
├── aspects[5]: AspectInstance?  // slot 0 = Key, slots 1-4 = flex
├── equipment: EquipmentSlots
├── baseStats: StatBlock  // from Key Aspect
├── bonusStats: StatBlock  // from level-ups + equipment
├── computedStats: StatBlock  // base + bonus
├── hp: int, mp: int, ct: int
├── statusEffects[]: List<StatusEffect>
└── isDowned: bool

Inventory Model

Aspects are roster-shared items.

RunInventory
├── unassignedAspects[]: List<AspectInstance>
├── consumables[]: List<Consumable>
├── equipment[]: List<Equipment>
├── relics[]: List<RelicInstance>
└── gold: int

Upgrade Trees

  • Linear — Tier 0 → 1 → 2 → 3. No branching. Simpler to design, implement, and balance.

Synergy Detection

  • Explicit combination table — a ScriptableObject or JSON lookup of all valid aspect ID pairs → synergy effects.
  • Tag-based matching was considered but rejected: explicit table is simpler to debug and validate.

Serialization

  • Definitions: ScriptableObjects (Unity asset workflow).
  • Run state saves: System.Text.Json (built-in Unity support).
  • Meta-progression: JSON file in persistent data path.

Slot Validation

  • Slot 0: only Key aspects (slotType == Key)
  • Slot 1: only Function aspects
  • Slot 2: only Movement aspects
  • Slot 3: only Defense aspects
  • Slot 4: only Utility aspects (empty at MVP — no Utility aspects implemented yet)
  • No duplicate aspect IDs across slots

Open Questions

  • [ ] Aspect inventory UI: grid filtered by slot type? How many aspects visible at once?
  • [ ] How to handle duplicate aspect drops? Auto-convert to EXP? Crafting currency?
  • [ ] Utility slot visibility: greyed out or hidden until v0.4?

Markdown is the canonical GDD source.