# Improved Enemy System: Separation of Concerns ## Overview The enemy character system has been refactored to provide better separation of concerns between **individual enemy data** and **spawning/encounter logic**. ## What Changed ### Before: Mixed Responsibilities ❌ ```csharp // EnemyCharacterData.cs (BAD) public class EnemyCharacterData : ScriptableObject { // Individual enemy stats public int maxHealth = 10; public int attack = 8; // Spawning logic (WRONG PLACE!) public int minGroupSize = 1; public int maxGroupSize = 3; public BiomeType[] preferredBiomes; } ``` ### After: Clean Separation ✅ ```csharp // EnemyCharacterData.cs (GOOD) public class EnemyCharacterData : ScriptableObject { // ONLY individual enemy data public int maxHealth = 10; public int attack = 8; public WeaponType preferredWeaponType; public bool regeneratesHealth; // etc... } // CombatTravelEvent.cs (GOOD) public class CombatTravelEvent : TravelEvent { // ONLY spawning/encounter logic public int minEnemies = 1; public int maxEnemies = 3; public float forestChance = 0.8f; public EnemyCharacterData[] possibleEnemies; } ``` ## Benefits ### 🎯 **Single Responsibility Principle** - **EnemyCharacterData**: Individual enemy stats, abilities, and rewards - **Travel Events**: When, where, and how many enemies spawn ### 🔄 **Reusability** - Same enemy can be used in different encounters with different group sizes - Forest Troll can appear solo in "Boss Encounter" or in groups in "Troll Pack" ### 🛠️ **Maintainability** - Change spawn behavior without touching enemy stats - Modify enemy stats without affecting encounter design ### 🎮 **Game Design Flexibility** ```csharp // Same Skeleton Warrior in different contexts: // Solo boss fight var bossFight = new CombatTravelEvent { minEnemies = 1, maxEnemies = 1, possibleEnemies = { skeletonWarrior } }; // Small patrol var patrol = new CombatTravelEvent { minEnemies = 2, maxEnemies = 4, possibleEnemies = { skeletonWarrior, goblinScout } }; // Large army encounter var army = new CombatTravelEvent { minEnemies = 5, maxEnemies = 8, possibleEnemies = { skeletonWarrior, goblinScout, forestTroll } }; ``` ## File Structure ### Enemy Data (Individual Stats) ``` Assets/Scripts/Characters/Enemies/ ├── EnemyCharacterData.cs (Base class for enemy stats) ├── SkeletonWarrior.asset (Individual skeleton data) ├── GoblinScout.asset (Individual goblin data) └── ForestTroll.asset (Individual troll data) ``` ### Travel Events (Encounter Logic) ``` Assets/Scripts/Events/ ├── TravelEventTypes.cs (CombatTravelEvent class) ├── SpecificTravelEvents.cs (Specific encounter types) └── TravelEventSystem.cs (Main event manager) Assets/Resources/TravelEvents/ ├── SkeletonAmbush.asset (1-3 skeletons in forests) ├── GoblinRaid.asset (2-5 goblins on roads) └── TrollEncounter.asset (1 troll in deep forests) ``` ## Migration Guide ### For Existing Enemy Assets - ✅ **Automatically cleaned**: Spawn settings removed from all enemy assets - ✅ **No code changes needed**: Generated enemy scripts still work - ✅ **Backward compatible**: Existing functionality preserved ### For New Travel Events ```csharp // Create travel events that reference enemy data: [CreateAssetMenu(fileName = "Skeleton Ambush", menuName = "RPG/Travel Events/Specific/Skeleton Ambush")] public class SkeletonAmbushEvent : CombatTravelEvent { void OnEnable() { eventName = "Skeleton Ambush"; // Encounter-specific settings minEnemies = 1; maxEnemies = 3; forestChance = 0.8f; roadChance = 0.2f; // Reference to enemy data (drag from Project window) possibleEnemies = new EnemyCharacterData[] { /* Drag SkeletonWarrior.asset here */ }; } } ``` ## Best Practices ### ✅ Do This: - Put **individual stats** in EnemyCharacterData - Put **encounter rules** in Travel Events - Reference enemy data assets in travel events - Use multiple travel events for the same enemy in different contexts ### ❌ Don't Do This: - Put spawn logic in enemy data - Put individual stats in travel events - Hardcode encounter parameters in enemy scripts - Mix individual and group behaviors ## Example Scenarios ### Scenario 1: Bandit Encounters ```csharp // BanditLeader.asset (Individual) maxHealth = 25, attack = 10, goldReward = 50 // BanditSoldier.asset (Individual) maxHealth = 15, attack = 8, goldReward = 20 // BanditAmbush.asset (Encounter) minEnemies = 3, maxEnemies = 5 possibleEnemies = [BanditSoldier, BanditLeader] forestChance = 0.9f, roadChance = 0.3f ``` ### Scenario 2: Dynamic Difficulty ```csharp // Same enemies, different encounter intensity: // Easy Encounter minEnemies = 1, maxEnemies = 2 // Normal Encounter minEnemies = 2, maxEnemies = 4 // Hard Encounter minEnemies = 3, maxEnemies = 6 ``` This separation makes the system much more flexible and maintainable! 🎯