AI NPC Framework

Description

AI NPC Brain is a Unity-focused system that turns NPCs into LLM-driven characters: they chat in character, remember facts about the player, track relationship stats (affinity, trust, fear, respect, flags), and can suggest game actions as structured events. Those suggestions are validated against a whitelist (your event catalog) before anything runs, so the model can’t arbitrarily trigger unknown gameplay.

It ships with pluggable backends (OpenAI, local Ollama, and a mock fallback for offline/UI testing), file-based persistence for conversation and memory, sample UI, demo scene, and editor tools (e.g. animation/catalog setup).

Technical Features

  • LLM-backed NPC dialogue — NPCs reply in character from a persona you define (ScriptableObject + JSON), with OpenAI, local Ollama, or an offline mock for testing.
  • Persistent memory — Stores facts about the player across sessions (file-based), with limits so prompts stay bounded.
  • Relationship model — Tracks affinity, trust, fear, respect, narrative flags, and stage; each turn can apply clamped deltas from the model.
  • Structured, safe game events — The model returns JSON; only catalog-whitelisted events can fire, with typed args, optional allowed values, and a confidence threshold.
  • Conversation history — Rolling turn history in the prompt (configurable depth) plus relevant memories retrieval.
  • World context — worldStateCompact on the brain injects free-form game state into prompts (time, location, inventory snippets, etc.).
  • Unity integration — Central AiNpcBrain component with UnityEvents (OnNpcReply, OnEmotionChanged, OnAnyNpcEventPayload, etc.) for UI, animation, and gameplay hooks.
  • Animation bridge — NpcAnimationMap maps semantic animation IDs to Animator triggers; NpcAnimationReceiver plays them from validated events.
  • UI workflow — Sample TMP chat UIs (simple and scroll-view), optional window IDs and WindowRegistryRuntime for opening shop/quest/relationship panels.
  • Editor tooling — Tools > AI NPC Brain (e.g. NPC Animation Setup) to sync Animator triggers with the animation map and event catalog.
  • Demo content — Demo scene, sample assets, and prefabs so buyers can press Play after wiring an API key or Ollama.
  • Unity 6 + URP oriented — Documented for Unity 6 and URP, with standard dependencies (Input System, Newtonsoft JSON, TextMesh Pro).

Documentation

Getting Started

AI NPC Brain - Getting Started

A Unity package that gives your NPCs an LLM-powered brain. NPCs hold conversations, remember facts about the player, track relationship scores, suggest game events (open shop, offer quests, play animations), and validate everything through a configurable whitelist before anything fires.

Unity version: 6000.x (Unity 6)
Render pipeline: URP
Key dependencies: TextMesh Pro, Input System, Newtonsoft JSON (via Unity package)


1. Import the Package

  1. Open your Unity project (Unity 6 / URP recommended).
  2. Copy or import the Assets/Runtime, Assets/Editor, Assets/Scripts, Assets/Samples, and Assets/Prefabs folders into your project's Assets directory.
  3. Make sure the following packages are installed via Window > Package Manager:
  4. TextMesh Pro (included with Unity)
  5. Input System (com.unity.inputsystem)
  6. Newtonsoft JSON (com.unity.nuget.newtonsoft-json)

If you are using the demo scene, also import Assets/Scenes, Assets/Mixamo Character, and Assets/Settings.


2. Create Your NPC's ScriptableObject Assets

You need four ScriptableObject assets per NPC. Create them via Right-click in Project > Create > AI NPC Brain > ...

2a. Persona Definition

Create > AI NPC Brain > Persona Definition

Field Description
npcId Unique string identifier, e.g. npc_aurelia_alchemist. Used as the save-file key.
displayName Name shown in the chat UI, e.g. Aurelia.
personaJson Free-form JSON blob injected into the LLM prompt. Describe the NPC's role, personality traits, goals, and speech style.

Example persona JSON:

{
  "role": "Alchemist shopkeeper in a fantasy village",
  "traits": ["witty", "cautious", "curious"],
  "goals": ["sell potions", "find rare ingredients"],
  "speech_style": "Speaks in short, precise sentences with dry humor"
}

2b. Brain Config

Create > AI NPC Brain > Brain Config

This controls which LLM provider to use, API keys, generation parameters, and safety limits. Key fields:

Field Default Description
providerMode OpenAI_Default Which LLM backend to use. Options: OpenAI_Default, Ollama_Fallback, Ollama_Only, OpenAI_Only
openAiApiKey (empty) Your OpenAI API key. Do not commit this to version control.
openAiModel gpt-4o-mini The OpenAI model to use.
openAiBaseUrl https://api.openai.com/v1 Base URL (change for Azure or compatible proxies).
ollamaBaseUrl http://localhost:11434 Local Ollama instance URL.
ollamaModel llama3.1:8b The Ollama model to use.
temperature 0.6 LLM creativity (0 = deterministic, 2 = very random).
maxTokens 350 Maximum response tokens.
fireConfidenceThreshold 0.65 Minimum confidence for an event to fire.
maxDeltaPerStat 3 Maximum relationship score change per turn.

2c. Event Catalog

Create > AI NPC Brain > Event Catalog

The catalog is a whitelist of every game event the NPC is allowed to suggest. Each event has: - An eventId (e.g. shop.open, anim.trigger) - A description (shown to the LLM in the prompt) - A list of typed arguments with optional allowed values

Common events to add:

Event ID Args Description
shop.open shop_id (String) Opens the NPC's shop panel
quest.offer quest_id (String) Offers a quest to the player
relationship.open_status relationship_id (String) Opens the relationship status panel
anim.trigger anim_id (String) Triggers an NPC animation
anim.move_to move_id (String) Moves the NPC to a target

2d. NPC Animation Map (optional)

Create > AI NPC Brain > NPC Animation Map

Maps semantic animation IDs (like nod, wave) to actual Animator trigger parameter names (like Nod, Wave). This lets the LLM pick contextually appropriate animations.

Tip: Use the editor tool Tools > AI NPC Brain > NPC Animation Setup to auto-fill this from your Animator Controller. See Editor Tools.


3. Set Up the Scene

3a. Add the AiNpcBrain Component

  1. Create or select the NPC's root GameObject.
  2. Add the AiNpcBrain component.
  3. Assign your ScriptableObject assets:
  4. Persona → your Persona Definition asset
  5. Config → your Brain Config asset
  6. Event Catalog → your Event Catalog asset
  7. Animation Map → (optional) your NPC Animation Map asset

3b. Add a Chat UI

Two sample UIs are provided:

Simple (for prototyping): Add SimpleChatUi to a GameObject and wire up: - brain → the AiNpcBrain component - input → a TMP_InputField - chatLog → a TMP_Text

Full-featured: Add NpcChatUiController to a GameObject and wire up: - brain → the AiNpcBrain component - inputField → a TMP_InputField - sendButton → a UI Button - scrollRect → a ScrollRect - contentRoot → the Content transform inside the ScrollView - messagePrefab → the ChatText prefab from Prefabs/UI/

3c. Wire Up Event Receivers

The AiNpcBrain component exposes an OnAnyNpcEventPayload UnityEvent that fires validated JSON payloads. Connect your receiver(s) in the Inspector:

  • For animations: Add NpcAnimationReceiver → assign its OnEventPayload method to OnAnyNpcEventPayload.
  • For UI panels: Add AureliaDemoReceiver (or your own receiver) → assign its OnEventFired method to OnAnyNpcEventPayload.

3d. Optional: UI Panel Routing

If you want events like shop.open to actually open panels:

  1. Create > AI NPC Brain > NPC UI Bindings — set the NPC ID and it auto-generates window IDs.
  2. Add WindowRegistryRuntime to a GameObject in the scene.
  3. Add WindowPanelId components to each panel root (shop panel, quest panel, etc.).
  4. Use the editor button Auto-Populate From Scene on the WindowRegistryRuntime inspector to discover all panels.

4. Configure Your LLM Provider

Option A: OpenAI (cloud)

  1. Get an API key from platform.openai.com.
  2. In your Brain Config asset, set:
  3. providerMode = OpenAI_Default or OpenAI_Only
  4. openAiApiKey = your key
  5. openAiModel = gpt-4o-mini (fast and cheap) or gpt-4o (smarter)

Security: For production, set the API key at runtime via script instead of baking it into the asset: csharp brain.config.openAiApiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY");

Option B: Ollama (local, free)

  1. Install Ollama on your machine.
  2. Pull a model: ollama pull llama3.1:8b
  3. In your Brain Config asset, set:
  4. providerMode = Ollama_Only
  5. ollamaBaseUrl = http://localhost:11434
  6. ollamaModel = llama3.1:8b

Option C: Mock (offline testing)

Set providerMode to any mode without providing an API key. The system will fall back to MockProvider, which returns canned responses based on keyword matching (useful for testing UI flow without burning API credits).


5. Press Play

  1. Enter Play Mode.
  2. Type a message in the chat input and press Enter or click Send.
  3. The NPC will respond in-character, and may trigger animations or open UI panels.

Check the Console for [AiNpcBrain] log messages if something isn't working.


6. Running the Demo Scene

  1. Open Assets/Scenes/AI Brain Demo.unity.
  2. The scene comes pre-configured with:
  3. Aurelia — a Mixamo character with an Animator Controller
  4. Pre-built ScriptableObject assets in Assets/Samples/
  5. A chat UI with ScrollView
  6. AureliaDemoReceiver for panel routing
  7. NpcAnimationReceiver for animation playback
  8. DemoCursorUnlock to keep the mouse visible
  9. Set your API key in the Aurelia Brain config asset (or run Ollama locally).
  10. Press Play and start chatting.

7. Troubleshooting

Problem Solution
"NPC brain not configured" Assign Persona and Config assets on the AiNpcBrain component.
"The NPC hesitates, unsure what to say" LLM provider failed. Check Console for HTTP errors. Verify API key / Ollama is running.
"The NPC seems confused" LLM returned invalid JSON. Try a more capable model or lower temperature.
Events not firing Check that your Event Catalog has the event defined with correct args. Check fireConfidenceThreshold in config.
Animations not playing Verify the Animation Map has the correct Animator trigger names. Check that NpcAnimationReceiver has an Animator and Animation Map assigned.
Panels not opening Verify WindowRegistryRuntime has bindings populated. Check that WindowPanelId components are on panel roots with matching IDs.

Next Steps