📋 Overview
The Behavior Profile system is the heart of the Medieval NPC AI, providing rich personality data that drives authentic medieval character behaviors. Each NPC receives a unique combination of personality archetypes, trait weightings, and medieval-specific characteristics that influence their daily activities, social interactions, and decision-making processes.
🎯 Personality Archetypes
The system defines 16 distinct personality archetypes that form the foundation of NPC behavior. Each archetype influences specific trait weightings and behavior patterns:
Brave
Courageous warriors and defenders with high BraveryWeight
High: BraveryWeight, HonorCode | Low: CowardiceWeight
Cowardly
Cautious individuals who avoid conflict and danger
High: CowardiceWeight | Low: BraveryWeight, HonorCode
Honest
Truthful and trustworthy characters with strong moral principles
High: HonestyWeight, HonorCode, CurrentMorality | Low: DeceitWeight
Deceitful
Cunning and manipulative individuals who use deception
High: DeceitWeight | Low: HonestyWeight, CurrentMorality
Cheerful
Optimistic and sociable characters who brighten their communities
High: CheerfulnessWeight, CurrentSociability | Low: GloomWeight
Gloomy
Pessimistic and withdrawn individuals who prefer solitude
High: GloomWeight | Low: CheerfulnessWeight, CurrentSociability
Courageous
Heroic characters who face danger without hesitation
High: CurrentCourage, BraveryWeight | Low: CowardiceWeight
Trustworthy
Reliable and dependable community members
High: HonestyWeight, HonorCode | Low: DeceitWeight
Compassionate
Empathetic characters who help others in need
High: CompassionWeight, CommunityResponsibility
Balanced
Well-rounded individuals with moderate trait values
Moderate: All traits | Special: Balanced approach to life
⚖️ Trait Weighting System
The system uses a comprehensive trait weighting approach with 15+ different personality traits that influence NPC behavior:
Core Personality Traits
| Trait |
Range |
Description |
Affects |
| BraveryWeight |
0.0 - 1.0 |
Willingness to face danger and conflict |
Combat behavior, risk-taking, leadership |
| HonestyWeight |
0.0 - 1.0 |
Tendency to tell truth and act with integrity |
Trading, conversations, reputation |
| CheerfulnessWeight |
0.0 - 1.0 |
General optimism and positive outlook |
Social interactions, mood, group dynamics |
| CompassionWeight |
0.0 - 1.0 |
Empathy and desire to help others |
Helping behavior, charity, healing |
| DeceitWeight |
0.0 - 1.0 |
Tendency to lie and manipulate |
Trading, conversations, thievery |
| CowardiceWeight |
0.0 - 1.0 |
Avoidance of danger and conflict |
Fleeing behavior, risk avoidance |
| GloomWeight |
0.0 - 1.0 |
Pessimism and negative outlook |
Social withdrawal, mood, conversations |
Medieval-Specific Traits
| Trait |
Range |
Description |
Affects |
| SuperstitionLevel |
0.0 - 1.0 |
Belief in supernatural and omens |
Religious behavior, fear responses |
| HonorCode |
0.0 - 1.0 |
Adherence to personal and social honor |
Combat, promises, social standing |
| FeudalLoyalty |
0.0 - 1.0 |
Loyalty to feudal lord and social superiors |
Military service, obedience, duty |
| ReligiousPiety |
0.0 - 1.0 |
Devotion to religious practices |
Church attendance, prayer, moral behavior |
| CraftsmanshipPride |
0.0 - 1.0 |
Pride in manual skills and craft work |
Work quality, skill development |
| FamilyDuty |
0.0 - 1.0 |
Commitment to family obligations |
Family care, inheritance, marriage |
| CommunityResponsibility |
0.0 - 1.0 |
Sense of duty to local community |
Community service, cooperation |
| Proud |
0.0 - 1.0 |
Personal pride and self-respect |
Social behavior, honor, reputation |
| DisciplineWeight |
0.0 - 1.0 |
Self-control and disciplined behavior |
Work ethic, military training |
| StealthSkill |
0.0 - 1.0 |
Ability to move unseen and unheard |
Thievery, scouting, hunting |
| KnowledgeSeeking |
0.0 - 1.0 |
Desire to learn and acquire knowledge |
Scholarship, reading, observation |
🔧 Profile Generation
The NPCBehaviorProfileGenerator creates unique behavior profiles using several approaches:
// Generate a completely random profile
var randomProfile = NPCBehaviorProfileGenerator.GenerateRandomProfile();
// Generate a profile based on specific archetype
var braveProfile = NPCBehaviorProfileGenerator.GenerateProfileForArchetype(
NPCPersonalityArchetype.Brave);
// Generate a profile with custom parameters
var customProfile = NPCBehaviorProfileGenerator.GenerateProfileWithParameters(
bravery: 0.8f, honesty: 0.6f, cheerfulness: 0.7f);
Profile Properties
| Property |
Type |
Description |
| SocialRole |
NPCSocialRole |
Primary social role (Child, Adult, Drunk) |
| PrimaryArchetype |
NPCPersonalityArchetype |
Main personality archetype |
| SecondaryArchetypes |
List<NPCPersonalityArchetype> |
Additional personality influences |
| CurrentCourage |
float |
Runtime courage level (0.0 - 1.0) |
| CurrentMorality |
float |
Runtime morality level (0.0 - 1.0) |
| CurrentSociability |
float |
Runtime sociability level (0.0 - 1.0) |
🔄 Runtime Modification
Behavior profiles support runtime modification through dedicated setter methods that maintain encapsulation:
// Modify runtime properties
profile.SetCurrentMorality(0.9f); // Increase morality
profile.SetCurrentSociability(0.3f); // Decrease sociability
profile.SetCurrentCourage(0.8f); // Boost courage
// Modify archetypes
profile.SetPrimaryArchetype(NPCPersonalityArchetype.Brave);
profile.SetSecondaryArchetypes(new List<NPCPersonalityArchetype> {
NPCPersonalityArchetype.Honest,
NPCPersonalityArchetype.Trustworthy
});
🎮 AI Controller Integration & Profile Assignment
This section covers the complete workflow from MedievalBioGenerator character creation to profile assignment and NPC behavior initialization.
Complete Integration Workflow
MedievalBioGenerator
→
Character Data
→
Profile Generation
→
AI Controller
→
NPC Behavior
Step 1: Bio Generation Integration
// Complete integration example using MedievalBioGenerator
public class NPCSpawner : MonoBehaviour
{
[Header("NPC Configuration")]
public GameObject npcPrefab;
public int npcCount = 10;
private MedievalBioGenerator bioGenerator;
private NPCBehaviorProfileGenerator profileGenerator;
void Start()
{
bioGenerator = FindObjectOfType<MedievalBioGenerator>();
profileGenerator = new NPCBehaviorProfileGenerator();
SpawnNPCs();
}
private void SpawnNPCs()
{
for (int i = 0; i < npcCount; i++)
{
// Step 1: Generate character bio
var characterBio = bioGenerator.GenerateRandomCharacter();
// Step 2: Create behavior profile from bio
var behaviorProfile = CreateProfileFromBio(characterBio);
// Step 3: Spawn NPC and assign profile
var npc = Instantiate(npcPrefab, GetRandomSpawnPosition(), Quaternion.identity);
var aiController = npc.GetComponent<MedievalNPCAIController>();
// Step 4: Initialize AI with profile
aiController.InitializeWithProfile(behaviorProfile, characterBio);
}
}
private NPCBehaviorProfile CreateProfileFromBio(CharacterBio bio)
{
var profile = new NPCBehaviorProfile();
// Map personality traits
profile.SetPrimaryArchetype(MapPersonalityToArchetype(bio.Personality));
profile.SetSecondaryArchetypes(MapSecondaryTraits(bio.Traits));
// Map social role based on age
profile.SocialRole = MapAgeToSocialRole(bio.Age);
profile.Occupation = bio.Occupation;
profile.FamilyTradition = bio.FamilyBackground;
// Map medieval-specific traits
profile.ReligiousPiety = bio.ReligiousDevotion / 100f;
profile.HonorCode = bio.SocialStanding / 100f;
profile.LoyaltyToLord = bio.FeudalLoyalty / 100f;
// Set initial runtime values
profile.SetCurrentMorality(bio.MoralAlignment / 100f);
profile.SetCurrentSociability(bio.Sociability / 100f);
profile.SetCurrentCourage(bio.Bravery / 100f);
return profile;
}
}
Step 2: Advanced Profile Mapping
public static class BioToProfileMapper
{
public static NPCPersonalityArchetype MapPersonalityToArchetype(CharacterPersonality personality)
{
return personality switch
{
CharacterPersonality.Brave => NPCPersonalityArchetype.Brave,
CharacterPersonality.Cowardly => NPCPersonalityArchetype.Cowardly,
CharacterPersonality.Honest => NPCPersonalityArchetype.Honest,
CharacterPersonality.Deceitful => NPCPersonalityArchetype.Deceitful,
CharacterPersonality.Cheerful => NPCPersonalityArchetype.Cheerful,
CharacterPersonality.Gloomy => NPCPersonalityArchetype.Gloomy,
CharacterPersonality.Trustworthy => NPCPersonalityArchetype.Trustworthy,
CharacterPersonality.Impulsive => NPCPersonalityArchetype.Impulsive,
CharacterPersonality.Thoughtful => NPCPersonalityArchetype.Thoughtful,
CharacterPersonality.Greedy => NPCPersonalityArchetype.Greedy,
CharacterPersonality.Generous => NPCPersonalityArchetype.Generous,
CharacterPersonality.Aggressive => NPCPersonalityArchetype.Aggressive,
CharacterPersonality.Peaceful => NPCPersonalityArchetype.Peaceful,
CharacterPersonality.Proud => NPCPersonalityArchetype.Proud,
CharacterPersonality.Humble => NPCPersonalityArchetype.Humble,
CharacterPersonality.Loyal => NPCPersonalityArchetype.Loyal,
CharacterPersonality.Treacherous => NPCPersonalityArchetype.Treacherous,
_ => NPCPersonalityArchetype.Balanced
};
}
public static NPCSocialRole MapAgeToSocialRole(int age)
{
if (age < 16) return NPCSocialRole.Child;
if (age > 65) return NPCSocialRole.Elder;
return NPCSocialRole.Adult;
}
public static List<NPCPersonalityArchetype> MapSecondaryTraits(List<string> traits)
{
var archetypes = new List<NPCPersonalityArchetype>();
foreach (var trait in traits)
{
switch (trait.ToLower())
{
case "religious":
archetypes.Add(NPCPersonalityArchetype.Pious);
break;
case "craftsman":
archetypes.Add(NPCPersonalityArchetype.Craftsmanship);
break;
case "scholar":
archetypes.Add(NPCPersonalityArchetype.Scholarly);
break;
case "military":
archetypes.Add(NPCPersonalityArchetype.Disciplined);
break;
case "merchant":
archetypes.Add(NPCPersonalityArchetype.Trader);
break;
}
}
return archetypes;
}
}
Step 3: AI Controller Initialization
public class MedievalNPCAIController : MonoBehaviour
{
[Header("Behavior Configuration")]
[SerializeField] private NPCBehaviorProfile behaviorProfile;
[SerializeField] private MedievalBehaviorEngine behaviorEngine;
[SerializeField] private NPCSchedulePeriod currentSchedulePeriod;
[Header("Character Data")]
[SerializeField] private CharacterBio characterBio;
[SerializeField] private string characterName;
[SerializeField] private int characterAge;
// Component references
private NavMeshAgent navMeshAgent;
private Animator animator;
private NPCInteractionSystem interactionSystem;
// Runtime state
private NPCBehaviorType currentBehavior;
private float lastBehaviorUpdate;
private List<MedievalNPCAIController> nearbyNPCs;
public void InitializeWithProfile(NPCBehaviorProfile profile, CharacterBio bio)
{
// Store references
behaviorProfile = profile;
characterBio = bio;
characterName = bio.FullName;
characterAge = bio.Age;
// Get component references
navMeshAgent = GetComponent<NavMeshAgent>();
animator = GetComponent<Animator>();
interactionSystem = GetComponent<NPCInteractionSystem>();
// Initialize behavior engine
behaviorEngine = new MedievalBehaviorEngine();
behaviorEngine.Initialize(this, behaviorProfile);
// Initialize interaction system
if (interactionSystem != null)
{
interactionSystem.Initialize(this, behaviorProfile);
}
// Set up schedule system
UpdateSchedulePeriod();
// Register with NPC manager
MedievalNPCManager.Instance.RegisterNPC(this);
Debug.Log($"NPC {characterName} initialized with {profile.PrimaryArchetype} archetype");
}
void Update()
{
// Update schedule period based on game time
UpdateSchedulePeriod();
// Update behavior at regular intervals (performance optimization)
if (Time.time - lastBehaviorUpdate > GetUpdateInterval())
{
UpdateBehavior();
lastBehaviorUpdate = Time.time;
}
// Update nearby NPCs for interactions
UpdateNearbyNPCs();
}
private void UpdateBehavior()
{
var newBehavior = behaviorEngine.SelectBehavior(currentSchedulePeriod);
if (newBehavior != currentBehavior)
{
currentBehavior = newBehavior;
ExecuteBehavior(currentBehavior);
}
}
private void ExecuteBehavior(NPCBehaviorType behaviorType)
{
switch (behaviorType)
{
case NPCBehaviorType.Work:
StartWorkBehavior();
break;
case NPCBehaviorType.Socialize:
StartSocialBehavior();
break;
case NPCBehaviorType.Pray:
StartPrayerBehavior();
break;
case NPCBehaviorType.Trade:
StartTradeBehavior();
break;
case NPCBehaviorType.Walk:
StartWalkingBehavior();
break;
}
}
private float GetUpdateInterval()
{
// Dynamic update frequency based on distance to player
var player = GameObject.FindGameObjectWithTag("Player");
if (player != null)
{
float distance = Vector3.Distance(transform.position, player.transform.position);
// Update more frequently when closer to player
if (distance < 20f) return 0.5f; // Very close - update twice per second
if (distance < 50f) return 1.0f; // Close - update every second
if (distance < 100f) return 2.0f; // Medium - update every 2 seconds
}
return 3.0f; // Far away - update every 3 seconds
}
}
Step 4: Runtime Profile Updates
public class DynamicProfileSystem : MonoBehaviour
{
// Modify NPC behavior based on game events
public void ApplyLifeEvent(MedievalNPCAIController npc, LifeEvent lifeEvent)
{
var profile = npc.BehaviorProfile;
switch (lifeEvent.Type)
{
case LifeEventType.BirthOfChild:
profile.SetCurrentSociability(profile.CurrentSociability + 0.2f);
profile.FamilyDuty += 0.1f;
break;
case LifeEventType.DeathInFamily:
profile.SetCurrentMorality(profile.CurrentMorality - 0.3f);
profile.SetCurrentSociability(profile.CurrentSociability - 0.4f);
break;
case LifeEventType.Promotion:
profile.SetCurrentCourage(profile.CurrentCourage + 0.2f);
profile.LoyaltyToLord += 0.1f;
break;
case LifeEventType.Demotion:
profile.SetCurrentCourage(profile.CurrentCourage - 0.2f);
profile.LoyaltyToLord -= 0.1f;
break;
case LifeEventType.ReligiousExperience:
profile.ReligiousPiety += 0.3f;
profile.SetCurrentMorality(Mathf.Min(1.0f, profile.CurrentMorality + 0.2f));
break;
case LifeEventType.CrimeWitnessed:
profile.SetCurrentMorality(profile.CurrentMorality - 0.1f);
if (profile.CurrentMorality < 0.5f)
{
profile.SetPrimaryArchetype(NPCPersonalityArchetype.Deceitful);
}
break;
}
// Notify the behavior engine of profile changes
npc.UpdateBehaviorProfile(profile);
Debug.Log($"Applied {lifeEvent.Type} to {npc.CharacterName}: " +
$"Morality={profile.CurrentMorality:F2}, " +
$"Sociability={profile.CurrentSociability:F2}");
}
// Gradual personality changes over time
public void ApplyAgingEffects(MedievalNPCAIController npc)
{
var profile = npc.BehaviorProfile;
var age = npc.CharacterAge;
// Elderly NPCs become more conservative and less active
if (age > 60)
{
profile.SetCurrentCourage(profile.CurrentCourage * 0.99f);
profile.SetCurrentSociability(profile.CurrentSociability * 0.98f);
profile.ReligiousPiety = Mathf.Min(1.0f, profile.ReligiousPiety * 1.01f);
}
// Young adults gain confidence
if (age < 25)
{
profile.SetCurrentCourage(Mathf.Min(1.0f, profile.CurrentCourage * 1.02f));
}
}
}
Integration Validation & Testing
⚡ Integration Testing Checklist
- Bio Data Mapping: Verify all MedievalBioGenerator fields map correctly to behavior profiles
- Profile Assignment: Confirm profiles are properly assigned to NPCs on spawn
- Behavior Execution: Test that NPCs behave according to their assigned profiles
- Runtime Updates: Validate profile changes affect NPC behavior in real-time
- Performance: Monitor FPS when spawning multiple NPCs with complex profiles
- Memory Usage: Check for memory leaks in profile generation and assignment
// Integration test example
public class NPCIntegrationTester : MonoBehaviour
{
[ContextMenu("Test Integration")]
public void TestCompleteIntegration()
{
// Test bio generation
var bioGenerator = FindObjectOfType<MedievalBioGenerator>();
var testBio = bioGenerator.GenerateRandomCharacter();
Debug.Log($"Generated Bio: {testBio.FullName}, Age: {testBio.Age}, " +
$"Personality: {testBio.Personality}, Occupation: {testBio.Occupation}");
// Test profile creation
var profile = CreateProfileFromBio(testBio);
Debug.Log($"Created Profile: {profile.PrimaryArchetype}, " +
$"Social Role: {profile.SocialRole}, Occupation: {profile.Occupation}");
// Test NPC spawn and assignment
var testNPC = GameObject.CreatePrimitive(PrimitiveType.Capsule);
var aiController = testNPC.AddComponent<MedievalNPCAIController>();
aiController.InitializeWithProfile(profile, testBio);
Debug.Log($"NPC Initialized: {aiController.CharacterName} with " +
$"{aiController.BehaviorProfile.PrimaryArchetype} archetype");
// Test behavior execution
aiController.TestBehaviorExecution();
// Cleanup
DestroyImmediate(testNPC);
Debug.Log("Integration test completed successfully!");
}
}