Appearance
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 lookupStat 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: boolInventory Model
Aspects are roster-shared items.
RunInventory
├── unassignedAspects[]: List<AspectInstance>
├── consumables[]: List<Consumable>
├── equipment[]: List<Equipment>
├── relics[]: List<RelicInstance>
└── gold: intUpgrade 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?