Configuration Guide
Configuration Guide
All NPC behavior is driven by ScriptableObject assets that you create and assign in the Inspector. This guide covers every configurable field.
NpcBrainConfig
Create via: Right-click > Create > AI NPC Brain > Brain Config
Script: Runtime/Core/NpcBrainConfig.cs
Provider Settings
| Field | Type | Default | Description |
|---|---|---|---|
providerMode |
ProviderMode |
OpenAI_Default |
Controls which LLM backend is primary and whether fallback is allowed. |
ProviderMode options:
| Mode | Behavior |
|---|---|
OpenAI_Default |
Uses OpenAI if an API key is set, otherwise falls back to Ollama, then Mock. |
Ollama_Fallback |
Same as OpenAI_Default (tries OpenAI first, Ollama second, Mock last). |
Ollama_Only |
Only uses Ollama. No fallback. |
OpenAI_Only |
Only uses OpenAI. No fallback. |
OpenAI Settings
| Field | Type | Default | Description |
|---|---|---|---|
openAiApiKey |
string |
"" |
Your API key. Leave empty if using Ollama only. |
openAiModel |
string |
gpt-4o-mini |
Model ID. Options: gpt-4o-mini (fast/cheap), gpt-4o (smart), or any compatible model. |
openAiBaseUrl |
string |
https://api.openai.com/v1 |
Override for Azure OpenAI or API-compatible proxies. |
Ollama Settings
| Field | Type | Default | Description |
|---|---|---|---|
ollamaBaseUrl |
string |
http://localhost:11434 |
Ollama server URL. |
ollamaModel |
string |
llama3.1:8b |
Model name. Must be pulled locally first (ollama pull llama3.1:8b). |
Generation Parameters
| Field | Type | Default | Range | Description |
|---|---|---|---|---|
temperature |
float |
0.6 |
0–2 | Controls randomness. Lower = more deterministic, higher = more creative. Recommended: 0.4–0.8 for NPC dialogue. |
maxTokens |
int |
350 |
— | Maximum tokens in the LLM response. Keep low (300–500) for snappy dialogue. |
timeoutMs |
int |
20000 |
— | Request timeout in milliseconds. Increase for slow models or high latency. |
Event Limits
| Field | Type | Default | Description |
|---|---|---|---|
maxEventsSuggested |
int |
2 |
Maximum event suggestions the LLM is allowed to return. |
maxEventsFired |
int |
1 |
Maximum events that will actually be dispatched per turn. |
fireConfidenceThreshold |
float |
0.65 |
Minimum confidence (0–1) for an event to pass the confidence gate. |
Memory Settings
| Field | Type | Default | Description |
|---|---|---|---|
recentTurnsToInclude |
int |
6 |
Number of recent conversation turns included in the prompt. More turns = better context but higher token cost. |
maxMemoryFactsToStorePerTurn |
int |
3 |
Cap on new memory facts the NPC can store from a single turn. |
maxRelevantMemoriesInPrompt |
int |
5 |
Number of stored facts included in the prompt for context. |
Relationship Settings
| Field | Type | Default | Description |
|---|---|---|---|
maxDeltaPerStat |
int |
3 |
Maximum change to any single relationship stat (affinity, trust, fear, respect) per turn. Prevents the LLM from making huge jumps. |
PersonaDefinition
Create via: Right-click > Create > AI NPC Brain > Persona Definition
Script: Runtime/Core/PersonaDefinition.cs
| Field | Type | Description |
|---|---|---|
npcId |
string |
Stable unique identifier. Used as the save-file key and referenced throughout the system. Example: npc_aurelia_alchemist. |
displayName |
string |
Human-readable name shown in the chat UI. Example: Aurelia. |
personaJson |
string (TextArea) |
Free-form JSON blob injected into the LLM's developer prompt. This is where you define the NPC's personality. |
Writing Good Persona JSON
The persona JSON is the most important piece of configuration. It directly shapes how the NPC speaks and behaves. Structure it with these keys:
{
"role": "Alchemist shopkeeper in a quiet fantasy village",
"traits": ["witty", "cautious", "secretly romantic"],
"goals": ["sell potions", "find the Moonpetal flower", "protect her shop"],
"speech_style": "Short, precise sentences. Dry humor. Occasionally trails off when nervous.",
"backstory": "Inherited the shop from her mentor. Doesn't trust strangers easily.",
"vendor_type": "alchemy",
"romance_eligible": true,
"quest_giver": true
}
Tips:
- Keep it concise. The entire persona JSON goes into every prompt.
- traits should be 3–5 adjectives that strongly define personality.
- speech_style is critical — it controls the NPC's voice.
- Add custom keys freely. The LLM will use anything relevant.
NpcEventCatalog
Create via: Right-click > Create > AI NPC Brain > Event Catalog
Script: Runtime/Core/NpcEventCatalog.cs
The catalog is a whitelist of game events. Only events listed here can be suggested by the LLM and fired at runtime.
Event Definition Fields
| Field | Type | Description |
|---|---|---|
eventId |
string |
Unique event identifier, e.g. shop.open. |
description |
string (TextArea) |
Human-readable description included in the LLM prompt so it knows when to suggest this event. |
args |
List<CatalogArgDef> |
Argument schema: name, type, and optional allowed values. |
Argument Types
| ArgType | Validation |
|---|---|
String |
Always passes. |
Int |
Must parse as int. |
Float |
Must parse as float. |
Bool |
Must parse as bool (true/false). |
Allowed Values
If allowedValues is non-empty on an arg, the provided value must be one of those strings. This is how you constrain animation IDs, shop IDs, etc.
See Event System for details on how events flow through validation.
NpcAnimationMap
Create via: Right-click > Create > AI NPC Brain > NPC Animation Map
Script: Scripts/NpcAnimationMap.cs
Maps semantic animation IDs to Animator trigger parameter names.
AnimTriggerBinding Fields
| Field | Type | Description |
|---|---|---|
animId |
string |
Semantic ID used in event payloads. Example: nod. |
animatorTrigger |
string |
Actual Animator parameter name. Example: Nod. |
usageHint |
string (TextArea) |
Hint included in the LLM prompt so it knows when to pick this animation. Example: "Use when agreeing or confirming." |
moodTag |
AnimationMoodTag |
Broad mood category: Neutral, Positive, Negative, Unsure, Greeting, Farewell, Curious, Emphatic. |
Use the editor tool Tools > AI NPC Brain > NPC Animation Setup to auto-fill this from an Animator Controller. See Editor Tools.
NpcUiBindings
Create via: Right-click > Create > AI NPC Brain > NPC UI Bindings
Script: Runtime/Npc/NpcUiBindings.cs
Stores the canonical window IDs for an NPC's UI panels.
| Field | Type | Description |
|---|---|---|
npcId |
string |
NPC identifier. Example: npc_aurelia_alchemist. |
shopWindowId |
string |
Window ID for the shop panel. Example: npc_aurelia_alchemist.shop. |
questBoardWindowId |
string |
Window ID for the quest board panel. |
relationshipWindowId |
string |
Window ID for the relationship panel. |
autoGenerateFromNpcId |
bool |
If true, clicking "Auto-Generate IDs" will fill the window IDs from the npcId. |
WindowRegistry
Create via: Right-click > Create > AI NPC Brain > Window Registry
Script: Runtime/Core/WindowRegistry.cs
A ScriptableObject-based mapping of window IDs to panel GameObjects. Use WindowRegistryRuntime (MonoBehaviour) for scene-based panels instead.
Relationship State
Relationship scores are tracked per NPC-player pair and persisted to disk. They are not configured directly — they evolve through conversation.
| Stat | Range | Description |
|---|---|---|
affinity |
-100 to 100 | How much the NPC likes the player. |
trust |
0 to 100 | How much the NPC trusts the player. |
fear |
0 to 100 | How afraid the NPC is of the player. |
respect |
0 to 100 | How much the NPC respects the player. |
stage |
string | Narrative stage: acquaintance, friend, rival, etc. |
flags |
List\<string> | Narrative flags the LLM can add/remove (e.g. knows_player_name, completed_first_quest). |
Each turn, the LLM returns a relationship_delta that adjusts these scores. The delta for each stat is clamped by maxDeltaPerStat before applying.
World State
The worldStateCompact field on AiNpcBrain is a free-form text area that gets injected into the prompt. Use it to tell the NPC about the current state of the game world:
Time: evening
Weather: raining
Player inventory: 3 healing potions, rusty sword
Recent event: bandits attacked the village
Update this string from your game systems as needed. Keep it concise to minimize token usage.