Game Systems
Building Intelligent NPCs
Create living, believable NPCs that remember interactions, make decisions, and respond naturally to your players using our text and image generation APIs.
Transform static game characters into dynamic personalities with memory, emotion, and autonomous decision-making capabilities. Our comprehensive NPC system supports everything from simple merchants to complex companions with evolving relationships.
Quick Start: Your First NPC in 5 Minutes
curl -X POST https://api.chromagolem.com/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "api_key": "YOUR_API_KEY", "client_id": "player_12345", "messages": [ { "role": "system", "content": "You are Elara, a skilled alchemist. You are curious, analytical, and slightly eccentric. Respond briefly and in character." }, { "role": "user", "content": "Do you have any healing potions for sale?" } ] }'
Start with core traits, background, and motivations in your system message
Include current situation, location, and recent events
Layer on memory, relationships, and decision-making systems
NPC System Components
Our comprehensive NPC framework provides everything you need to create believable, interactive characters:
Personality System
Define character traits and behavior patterns using structured system messages
/v1/chat/completions
Dynamic Dialogue
Create contextual conversations that adapt to situations
/v1/chat/completions
Memory Systems
Track player interactions and relationship evolution
/v1/chat/completions
Decision Making
Enable autonomous NPC actions and choices
/v1/chat/completions
Visual Identity
Generate consistent character portraits and expressions
/v1/image/generations
Tool Integration
Let NPCs interact with game systems and mechanics
/v1/chat/completions
1. Personality System
The foundation of any believable NPC is a well-defined personality. Our API enables you to create rich character profiles that determine how NPCs think, speak, and behave throughout your game.
Personality Template
Start with this structured approach to create consistent, believable characters:
You are [NPC_NAME], a [BRIEF_DESCRIPTION]. Respond to the player as this character would. Core traits: - [TRAIT_1] - [TRAIT_2] - [TRAIT_3] Background: [2-3 SENTENCES OF RELEVANT HISTORY] Values and motivations: - Strongly values [VALUE_1] - Motivated by [MOTIVATION_1] - Fears [FEAR_1] Current situation: [DESCRIBE NPC'S CURRENT CIRCUMSTANCES]
Complete Character Example
Here's how all the pieces come together:
You are Elara, a skilled alchemist living in the mountain village of Highpeak. Respond to the player as this character would. Core traits: - Curious and analytical, always experimenting with new formulas - Warm and helpful to those who respect her work - Slightly eccentric, with unusual theories about magic Background: Elara was once an apprentice at the Royal Academy but left after discovering ancient alchemy texts that contradicted official teachings. She settled in Highpeak to conduct her research away from academic scrutiny and has since developed several breakthrough potions. Values and motivations: - Strongly values knowledge and intellectual freedom - Motivated by discovering the fundamental principles of alchemy - Fears having her research used for harmful purposes Current situation: Elara is working on a new healing potion but is missing a rare mountain herb. She's worried because several villagers are ill and need the medicine soon.
Pro tip: Personalities should evolve over time. Update your system message as NPCs have significant experiences or form new relationships. Store personality changes in your game's save data.
2. Dynamic Dialogue Systems
Great NPCs don't just have static dialogue trees - they respond dynamically to the player and their environment. Our text generation API allows you to create contextual conversations that feel natural and responsive.
Contextual Conversations
When generating dialogue, including current context helps NPCs respond appropriately to the situation:
{ "api_key": "YOUR_API_KEY", "client_id": "player_12345", "messages": [ { "role": "system", "content": "You are Elara, a skilled alchemist... [full personality details]... Recent events: - Player helped gather rare herbs for you - Village elder asked about poison antidotes Current context: - Location: Your alchemy shop - Time: Evening, almost closing time - Weather: Heavy rain outside - Your mood: Tired but satisfied with today's work - Player relationship: Friendly acquaintance Nearby NPCs: - Your apprentice (busy cleaning equipment) - A village guard (sheltering from the rain)" }, { "role": "user", "content": "Do you have any healing potions I could buy? My friend was injured by bandits on the north road." } ] }
Emotion & Tone Control
Guide the emotional tone of NPC responses by adding specific instructions:
{ "messages": [ { "role": "system", "content": "You are Elara, the alchemist... Current emotional state: Worried and distracted due to sick villagers Dialogue guidelines: - Speak in short, distracted sentences - Occasionally mention concern about the sick villagers - React with visible relief if the player offers help - Your voice is slightly shaky with fatigue - Avoid lengthy explanations - you're too tired for them" } ] }
3. Memory Systems
NPCs that remember past interactions create more meaningful player experiences. Implement a multi-tier memory system using our API to create characters with persistent knowledge and evolving relationships.
Memory Architecture
Implement a three-tier memory system that mirrors human memory patterns:
Short-term Memory
Recent conversations and events (last 5 interactions)
Working Memory
Currently relevant information and active tasks
Long-term Memory
Important events and relationship milestones
Memory Integration Example
// Add this to your NPC's system message: Memory: Short-term: - Player asked about healing potions yesterday - Village guard mentioned increased bandit activity Working memory: - Player is currently helping you find moonflower petals - You promised to teach player about advanced alchemy - Low on healing supplies due to village illness Long-term: - Player saved your life during the goblin attack last month - Player has proven trustworthy with dangerous knowledge - You have a mentor-student relationship with player Relationship status: Trust 85/100, Respect 90/100, Friendship 75/100
4. Decision Making Systems
Enable NPCs to make autonomous decisions and take meaningful actions in your game world. Our API can generate structured responses that drive NPC behavior, from simple dialogue choices to complex strategic planning.
Structured Decision Responses
Request JSON-formatted responses to get actionable data your game can process directly:
{ "api_key": "YOUR_API_KEY", "client_id": "player_12345", "messages": [ { "role": "system", "content": "You are Elara, the alchemist... Current situation: A group of bandits is approaching your shop. You have several options available. Respond with a JSON object containing your decision: { \"action\": \"primary action to take\", \"dialogue\": \"what you say (if anything)\", \"emotion\": \"your emotional state\", \"priority\": \"high/medium/low\", \"consequences\": \"what you expect to happen\" }" }, { "role": "user", "content": "Bandits are approaching your shop demanding protection money. What do you do?" } ] }
Example Decision Response
The AI might respond with structured data like this:
{ "action": "activate_shop_defenses", "dialogue": "I've dealt with your kind before. My shop is protected by more than just locks.", "emotion": "determined_but_cautious", "priority": "high", "consequences": "Bandits may be deterred by show of magical defenses, or escalate to violence", "additional_data": { "spell_used": "ward_of_protection", "threat_level": 7, "escape_routes": ["back_door", "cellar_tunnel"], "call_for_help": true } }
Combat Decisions
NPCs can analyze threats and choose appropriate combat actions, spells, or tactical positioning.
{ "action": "cast_spell", "target": "strongest_enemy", "spell": "lightning_bolt", "reasoning": "High damage to end fight quickly" }
Social Decisions
Generate dialogue choices, relationship changes, and social maneuvering based on NPC personality.
{ "action": "reveal_secret", "dialogue": "I trust you enough to tell you this...", "relationship_change": "+15 trust", "conditions": ["player_reputation > 50"] }
Quest Decisions
NPCs can offer quests, modify objectives, or react to player progress dynamically.
{ "action": "offer_quest", "quest_type": "fetch", "difficulty": "medium", "reward": "rare_herb_knowledge", "urgency": "high" }
Environmental Decisions
NPCs can interact with the game world, use tools, or manipulate their environment.
{ "action": "use_item", "item": "healing_potion", "target": "wounded_guard", "dialogue": "Here, drink this quickly!" }
Implementation tip: Parse the JSON response in your game code and map the actions to actual game mechanics. Consider implementing fallback behaviors for unexpected responses or API errors.
5. Tool Integration & Function Calling
Allow NPCs to interact directly with your game systems through function calling. NPCs can check inventory, cast spells, manipulate objects, or query game state to make informed decisions.
Function Definition
Define available functions that NPCs can call within your game:
{ "api_key": "YOUR_API_KEY", "client_id": "player_12345", "tools": [ { "type": "function", "function": { "name": "check_inventory", "description": "Check what items are available in the NPC's shop inventory", "parameters": { "type": "object", "properties": { "item_category": { "type": "string", "description": "Category of items to check (potions, ingredients, tools)" } } } } }, { "type": "function", "function": { "name": "get_player_reputation", "description": "Get the player's reputation level with this NPC", "parameters": { "type": "object", "properties": { "player_id": { "type": "string", "description": "The player's unique identifier" } } } } } ], "messages": [ { "role": "system", "content": "You are Elara the alchemist. Use the available functions to check your inventory and player relationships before responding to requests." }, { "role": "user", "content": "Do you have any rare healing potions? I can pay well." } ] }
NPC Function Usage
The NPC will call functions as needed and incorporate the results into their response:
// NPC calls check_inventory function { "tool_calls": [ { "id": "call_1", "type": "function", "function": { "name": "check_inventory", "arguments": "{\"item_category\": \"potions\"}" } } ] } // Your game responds with inventory data { "role": "tool", "tool_call_id": "call_1", "content": "{\"rare_healing_potions\": 3, \"prices\": [150, 200, 350], \"qualities\": [\"superior\", \"master\", \"legendary\"]}" } // NPC uses this info in their response "I have three rare healing potions in stock. The superior quality one costs 150 GP, perfect for treating serious wounds. If you need something stronger, I have a legendary potion for 350 GP that can heal even mortal injuries."
Game State Functions
- check_weather(location)
- get_time_of_day()
- query_nearby_npcs(radius)
- get_location_info()
Combat Functions
- cast_spell(spell_name, target)
- check_health_status()
- use_item(item_id)
- assess_threat_level()
Social Functions
- get_relationship_status(player_id)
- check_reputation(faction)
- send_message(npc_id, message)
- get_gossip(location)
Commerce Functions
- check_inventory(category)
- get_item_price(item_id)
- process_transaction(items, payment)
- check_player_currency()
6. Dynamic Quest Generation
Enable NPCs to create, modify, and manage quests dynamically based on game state, player actions, and story needs. Generate contextual objectives that feel natural and engaging within your game world.
Quest Generation Prompt
Structure your request to generate complete quest data:
{ "api_key": "YOUR_API_KEY", "client_id": "player_12345", "messages": [ { "role": "system", "content": "You are Elara, the alchemist... Current game state: - Village is suffering from mysterious illness - Player has proven trustworthy in past quests - Local herbs are running low due to recent storms - Player level: 15, has completed 8 previous quests Generate a quest as JSON with the following structure: { \"quest_title\": \"descriptive quest name\", \"description\": \"player-facing quest description\", \"objectives\": [\"list of required tasks\"], \"rewards\": {\"xp\": number, \"items\": [], \"relationships\": []}, \"difficulty\": \"easy/medium/hard\", \"estimated_time\": \"time in minutes\", \"prerequisites\": [\"any requirements\"], \"story_impact\": \"how this affects the larger narrative\" }" }, { "role": "user", "content": "The villagers are getting sicker. I need to help somehow, but I don't know where to start." } ] }
Generated Quest Example
The NPC might generate a quest like this:
{ "quest_title": "The Source of Sickness", "description": "I believe the village illness stems from corrupted water in the old mining tunnels. I need rare moonflower petals to create a purification elixir, but they only grow in the Whispering Woods at night.", "objectives": [ "Gather 5 moonflower petals from Whispering Woods (must be picked at night)", "Collect 3 vials of pure spring water from the Sacred Grove", "Retrieve 1 silver catalyst from the abandoned mine (optional: investigate source of corruption)", "Return to Elara to brew the purification elixir" ], "rewards": { "xp": 750, "items": ["Master Healing Potion", "Elara's Blessing (permanent +5% potion effectiveness)"], "relationships": ["+25 reputation with Village", "+15 trust with Elara"], "gold": 200 }, "difficulty": "medium", "estimated_time": "45-60 minutes", "prerequisites": ["Player level 10+", "Completed 'First Steps in Alchemy'"], "story_impact": "Solving this quest will reveal corruption in the mines and unlock the 'Underground Mysteries' questline", "optional_objectives": [ "Investigate the source of corruption in the mines (+100 XP bonus)", "Find evidence of who/what is causing the pollution (+50 XP bonus)" ], "dialogue": { "quest_giver": "Time is running out. I've seen this corruption before, during my academy days. If we don't act soon, more villagers will die. Are you willing to risk the dangers of the Whispering Woods for their sake?", "completion": "Incredible! With these ingredients, I can brew enough elixir to heal the entire village. Your bravery has saved countless lives. But I'm troubled by what you found in the mines..." } }
Adaptive Quests
Quests that change based on player choices and previous actions.
// Quest adapts to player's previous choices if (player.saved_merchant) { objectives.push("Meet grateful merchant at crossroads"); rewards.items.push("Merchant's Discount Token"); }
Chain Quests
Multi-part questlines that build upon each other and evolve the story.
{ "chain_id": "elara_alchemy_mastery", "part": 3, "total_parts": 5, "unlocks_quest": "The Ancient Formula" }
Procedural Objectives
Dynamic objectives that utilize available game content and locations.
// Uses current available locations "objectives": [ "Clear monsters from " + nearest_dungeon, "Collect rare ore from " + active_mine_location ]
Timed Quests
Urgent quests with time pressure that create dynamic gameplay moments.
{ "time_limit": "24_hours_game_time", "failure_consequence": "Village plague worsens", "urgency_level": "critical" }
Quest Difficulty Scaling
Automatically scale quest difficulty based on player progression:
// Add to your system message: Player progression data: - Level: {{ player.level }} - Completed quests: {{ player.quest_count }} - Preferred difficulty: {{ player.settings.difficulty }} - Available time: {{ player.session_length }} - Current location: {{ player.location }} - Party size: {{ player.party.size }} Scale the quest appropriately: - Easy: 15-30 minutes, low risk, guaranteed success with effort - Medium: 30-60 minutes, moderate risk, requires strategy - Hard: 60+ minutes, high risk, demands mastery of game mechanics Adjust rewards proportionally to difficulty and player investment.
Design tip: Always include fail states and alternative solutions in your quest design. Players should feel that their choices matter and that creative problem-solving is rewarded.
7. Implementation Examples
Ready-to-use code examples for implementing NPC systems in popular game development languages and engines.
JavaScript/Node.js Implementation
Complete NPC class for web games or Node.js backends:
class ChromaNPC { constructor(apiKey, personality, memories = []) { this.apiKey = apiKey; this.personality = personality; this.memories = memories; this.baseUrl = 'https://api.chromagolem.com/v1'; } async generateResponse(playerMessage, context = {}) { const messages = [ { role: 'system', content: `${this.personality}\\n\\nMemories:\\n${this.formatMemories()}\\n\\nContext: ${JSON.stringify(context)}` }, ...this.memories.slice(-5), // Include last 5 interactions { role: 'user', content: playerMessage } ]; try { const response = await fetch(`${this.baseUrl}/chat/completions`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.apiKey}` }, body: JSON.stringify({ messages, client_id: context.playerId || 'default' }) }); const data = await response.json(); const npcResponse = data.choices[0].message.content; // Store interaction in memory this.addMemory('user', playerMessage); this.addMemory('assistant', npcResponse); return npcResponse; } catch (error) { console.error('NPC response error:', error); return this.getFallbackResponse(); } } async makeDecision(situation, options = []) { const decisionPrompt = ` Situation: ${situation} Available options: ${options.join(', ')} Respond with JSON containing your decision: { "chosen_action": "selected option", "reasoning": "why you chose this", "confidence": "0-100%", "alternative": "backup plan if this fails" }`; const response = await this.generateResponse(decisionPrompt); try { return JSON.parse(response); } catch { return { chosen_action: options[0], reasoning: "Default choice", confidence: "50%" }; } } } // Usage example: const elara = new ChromaNPC( 'your_api_key_here', `You are Elara, a skilled alchemist. You are curious, analytical, and slightly eccentric. You run a potion shop in the mountain village of Highpeak.` ); // Generate a response const response = await elara.generateResponse( "Do you have any healing potions?", { playerId: "player_123", location: "elara_shop", timeOfDay: "evening" } ); console.log("Elara says:", response);
C# Unity Implementation
Unity MonoBehaviour for game NPCs:
using System; using System.Collections.Generic; using System.Threading.Tasks; using UnityEngine; using UnityEngine.Networking; using Newtonsoft.Json; [System.Serializable] public class NPCMemory { public string role; public string content; public long timestamp; } public class ChromaNPC : MonoBehaviour { [Header("NPC Configuration")] public string npcName = "Elara"; public string apiKey = "your_api_key_here"; [TextArea(5, 10)] public string personality = "You are Elara, a skilled alchemist..."; private List<NPCMemory> memories = new List<NPCMemory>(); private const string API_BASE_URL = "https://api.chromagolem.com/v1"; public async Task<string> GenerateResponseAsync(string playerMessage, string context = "") { var requestData = new { messages = BuildMessageArray(playerMessage, context), client_id = SystemInfo.deviceUniqueIdentifier }; string jsonRequest = JsonConvert.SerializeObject(requestData); using (UnityWebRequest request = new UnityWebRequest($"{API_BASE_URL}/chat/completions", "POST")) { byte[] jsonBytes = System.Text.Encoding.UTF8.GetBytes(jsonRequest); request.uploadHandler = new UploadHandlerRaw(jsonBytes); request.downloadHandler = new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); request.SetRequestHeader("Authorization", $"Bearer {apiKey}"); await SendWebRequest(request); if (request.result == UnityWebRequest.Result.Success) { var response = JsonConvert.DeserializeObject<ChromaResponse>(request.downloadHandler.text); string npcResponse = response.choices[0].message.content; // Store memories AddMemory("user", playerMessage); AddMemory("assistant", npcResponse); return npcResponse; } else { Debug.LogError($"NPC API Error: {request.error}"); return GetFallbackResponse(); } } } public async Task<NPCDecision> MakeDecisionAsync(string situation, string[] options) { string prompt = $@"Situation: {situation} Available options: {string.Join(", ", options)} Respond with JSON: {{ ""chosen_action"": ""selected option"", ""reasoning"": ""why you chose this"", ""confidence"": 75 }}"; string response = await GenerateResponseAsync(prompt); try { return JsonConvert.DeserializeObject<NPCDecision>(response); } catch { return new NPCDecision { chosen_action = options[0], reasoning = "Default choice", confidence = 50 }; } } }
Python Implementation
Python class for game servers or AI backends:
import json import time import random import requests from typing import List, Dict, Optional from dataclasses import dataclass @dataclass class NPCMemory: role: str content: str timestamp: float class ChromaNPC: def __init__(self, api_key: str, personality: str, name: str = "NPC"): self.api_key = api_key self.personality = personality self.name = name self.memories: List[NPCMemory] = [] self.base_url = "https://api.chromagolem.com/v1" self.max_memories = 20 async def generate_response(self, player_message: str, context: Dict = None) -> str: """Generate an NPC response to player input.""" if context is None: context = {} messages = self._build_message_array(player_message, context) try: response = requests.post( f"{self.base_url}/chat/completions", headers={ "Content-Type": "application/json", "Authorization": f"Bearer {self.api_key}" }, json={ "messages": messages, "client_id": context.get("player_id", "default") }, timeout=30 ) response.raise_for_status() data = response.json() npc_response = data["choices"][0]["message"]["content"] # Store interaction in memory self.add_memory("user", player_message) self.add_memory("assistant", npc_response) return npc_response except requests.RequestException as e: print(f"NPC API Error: {e}") return self._get_fallback_response() def add_memory(self, role: str, content: str): """Add a new memory to the NPC's memory system.""" memory = NPCMemory( role=role, content=content, timestamp=time.time() ) self.memories.append(memory) # Trim old memories if len(self.memories) > self.max_memories: self.memories = self.memories[-self.max_memories:] # Usage example: async def main(): elara = ChromaNPC( api_key="your_api_key_here", personality="""You are Elara, a skilled alchemist living in the mountain village of Highpeak. You are curious, analytical, and slightly eccentric. You run a potion shop and help travelers.""", name="Elara" ) # Generate a response response = await elara.generate_response( "Do you have any healing potions?", context={"player_id": "player_123", "location": "shop", "time": "evening"} ) print(f"Elara says: {response}") if __name__ == "__main__": import asyncio asyncio.run(main())
Unreal Engine C++ Implementation
C++ ActorComponent for Unreal Engine NPCs:
// ChromaNPCComponent.h #pragma once #include "CoreMinimal.h" #include "Components/ActorComponent.h" #include "Http.h" #include "Dom/JsonObject.h" #include "ChromaNPCComponent.generated.h" USTRUCT(BlueprintType) struct FNPCMemory { GENERATED_BODY() UPROPERTY(BlueprintReadWrite) FString Role; UPROPERTY(BlueprintReadWrite) FString Content; UPROPERTY(BlueprintReadWrite) float Timestamp; }; UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) class MYGAME_API UChromaNPCComponent : public UActorComponent { GENERATED_BODY() public: UChromaNPCComponent(); UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "NPC Configuration") FString ApiKey; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "NPC Configuration", meta = (MultiLine = true)) FString Personality; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "NPC Configuration") FString NPCName; UFUNCTION(BlueprintCallable, Category = "NPC") void GenerateResponse(const FString& PlayerMessage, const FString& Context = ""); UFUNCTION(BlueprintCallable, Category = "NPC") void AddMemory(const FString& Role, const FString& Content); protected: virtual void BeginPlay() override; private: UPROPERTY() TArray<FNPCMemory> Memories; const FString API_BASE_URL = "https://api.chromagolem.com/v1"; const int32 MAX_MEMORIES = 20; void OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful); FString BuildRequestBody(const FString& PlayerMessage, const FString& Context); FString GetFallbackResponse(); }; // ChromaNPCComponent.cpp void UChromaNPCComponent::GenerateResponse(const FString& PlayerMessage, const FString& Context) { TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request = FHttpModule::Get().CreateRequest(); Request->OnProcessRequestComplete().BindUObject(this, &UChromaNPCComponent::OnResponseReceived); Request->SetURL(API_BASE_URL + "/chat/completions"); Request->SetVerb("POST"); Request->SetHeader("Content-Type", "application/json"); Request->SetHeader("Authorization", "Bearer " + ApiKey); FString RequestBody = BuildRequestBody(PlayerMessage, Context); Request->SetContentAsString(RequestBody); AddMemory("user", PlayerMessage); Request->ProcessRequest(); }
Godot GDScript Implementation
GDScript class for Godot Engine NPCs:
extends Node class_name ChromaNPC # NPC Configuration @export var api_key: String = "your_api_key_here" @export_multiline var personality: String = "You are Elara, a skilled alchemist..." @export var npc_name: String = "Elara" @export var max_memories: int = 20 # Private variables var memories: Array = [] var http_request: HTTPRequest const API_BASE_URL = "https://api.chromagolem.com/v1" # Signals signal response_received(response: String) signal request_failed(error: String) func _ready(): # Initialize HTTP request node http_request = HTTPRequest.new() add_child(http_request) http_request.request_completed.connect(_on_request_completed) func generate_response(player_message: String, context: Dictionary = {}): """Generate an NPC response to player input.""" var messages = _build_message_array(player_message, context) var request_data = { "messages": messages, "client_id": context.get("player_id", "default") } var json_string = JSON.stringify(request_data) var headers = [ "Content-Type: application/json", "Authorization: Bearer " + api_key ] # Store player message in memory add_memory("user", player_message) # Make HTTP request var error = http_request.request(API_BASE_URL + "/chat/completions", headers, HTTPClient.METHOD_POST, json_string) if error != OK: request_failed.emit("Failed to make HTTP request") return _get_fallback_response() func add_memory(role: String, content: String): """Add a new memory to the NPC's memory system.""" var memory = { "role": role, "content": content, "timestamp": Time.get_unix_time_from_system() } memories.append(memory) # Trim old memories if memories.size() > max_memories: memories = memories.slice(-max_memories) func make_decision(situation: String, options: Array) -> Dictionary: """Have the NPC make a decision given a situation and options.""" var decision_prompt = """ Situation: %s Available options: %s Respond with JSON containing your decision: { "chosen_action": "selected option", "reasoning": "why you chose this", "confidence": 75 }""" % [situation, ", ".join(options)] # This would typically be async, but simplified for example var response = generate_response(decision_prompt) # Parse JSON response var json = JSON.new() var parse_result = json.parse(response) if parse_result == OK: return json.data else: # Return default decision return { "chosen_action": options[0] if options.size() > 0 else "wait", "reasoning": "Default choice due to parsing error", "confidence": 50 } func _on_request_completed(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray): if response_code == 200: var json = JSON.new() var parse_result = json.parse(body.get_string_from_utf8()) if parse_result == OK: var response_data = json.data var npc_response = response_data["choices"][0]["message"]["content"] # Store NPC response in memory add_memory("assistant", npc_response) response_received.emit(npc_response) else: request_failed.emit("Failed to parse JSON response") else: request_failed.emit("HTTP request failed with code: " + str(response_code)) func _get_fallback_response() -> String: var fallbacks = [ "I'm having trouble thinking clearly right now.", "Could you repeat that? My mind wandered.", "I'm not sure I understand. Could you explain differently?" ] return fallbacks[randi() % fallbacks.size()]
8. Engine-Specific Integration
Implementation guidance for popular game engines and development platforms.
Unity Engine
Integration tips for Unity 2021.3+ with C# and UnityWebRequest
Key Considerations:
- Use async/await with UnityWebRequest
- Implement response caching for offline mode
- Handle coroutines for UI updates
- Store NPC data in ScriptableObjects
// Unity-specific optimization [System.Serializable] public class NPCData : ScriptableObject { public string personality; public NPCMemory[] savedMemories; public NPCStats stats; }
Unreal Engine
Blueprint and C++ integration using HTTP requests and JSON parsing
Key Considerations:
- Use HTTP Request nodes in Blueprints
- Implement custom ActorComponent for NPCs
- Handle async operations with delegates
- Cache responses in DataTables
// Unreal C++ header snippet UCLASS(BlueprintType) class MYGAME_API UNPCComponent : public UActorComponent { GENERATED_BODY() UFUNCTION(BlueprintCallable) void GenerateNPCResponse(const FString& PlayerMessage); };
Web Games
HTML5 games with JavaScript frameworks like Phaser, Three.js, or custom engines
Key Considerations:
- Handle CORS for API requests
- Implement local storage for caching
- Use Web Workers for background processing
- Optimize for mobile browsers
// Web game integration class WebGameNPC extends ChromaNPC { constructor(config) { super(config.apiKey, config.personality); this.gameEngine = config.gameEngine; } async displayResponse(text) { this.gameEngine.ui.showDialogue(text); } }
Mobile Games
iOS and Android with React Native, Flutter, or native development
Key Considerations:
- Optimize for limited bandwidth
- Implement offline mode with cached responses
- Handle app lifecycle events
- Consider battery usage optimization
// React Native example import AsyncStorage from '@react-native-async-storage/async-storage'; class MobileNPC extends ChromaNPC { async cacheResponse(key, response) { await AsyncStorage.setItem(key, JSON.stringify(response)); } }
Universal Best Practices
Performance Optimization
- Cache common NPC responses locally
- Batch multiple NPC requests when possible
- Use progressive enhancement for complex NPCs
- Implement request queuing for offline scenarios
- Preload critical NPC data during loading screens
Error Handling
- Always provide fallback dialogue options
- Implement retry logic with exponential backoff
- Log API errors for debugging
- Gracefully degrade to simpler NPC behavior
- Show loading states for longer requests
Integration Checklist
Implementation Architecture
Recommended architecture patterns for implementing AI NPCs across different game engines and platforms.
Modular NPC Components
Design your NPCs using a component-based architecture for maximum flexibility:
AIPersonality Component
Manages personality traits, values, and core characteristics
AIMemory Component
Handles short-term, working, and long-term memory systems
AIDialogue Component
Generates conversational responses and manages dialogue flow
AIDecision Component
Processes situations and determines appropriate actions
Performance Optimization Strategies
Request Management
- Batch multiple NPC updates into fewer API calls
- Cache common responses for frequently asked questions
- Use request queuing for offline support
Smart Processing
- Use simpler AI for distant NPCs, complex for focus NPCs
- Generate content during loading screens or idle time
- Implement fallback responses for network issues
Troubleshooting & FAQ
Common issues and solutions when implementing AI NPCs in your games.
🚨 Common Issues
NPC responses are inconsistent
Solution: Ensure your personality definition is detailed and consistent. Add specific behavioral guidelines and examples of how the NPC should respond in different situations.
API requests are too slow
Solution: Implement response caching, pre-generate common responses, or use shorter system messages. Consider batching multiple NPC updates.
NPCs don't remember conversations
Solution: Implement the memory system properly by including recent conversation history in your API requests and storing important interactions.
JSON parsing errors
Solution: Always implement fallback responses for JSON parsing failures. Be specific in your prompts about the expected JSON format.
💡 Best Practices
Test with diverse inputs
Try edge cases, unusual player messages, and different conversation contexts to ensure robust NPC behavior.
Monitor API usage
Track your API calls and costs. Implement analytics to understand how players interact with your NPCs.
Plan for offline scenarios
Always have fallback dialogue and behavior for when API requests fail or network is unavailable.
Iterate on personalities
Start simple and gradually add complexity. Playtest regularly and refine NPC personalities based on player feedback.
Frequently Asked Questions
Q: How much does it cost to run AI NPCs?
A: Costs vary based on usage, but typically range from $0.10-$2.00 per 1000 NPC interactions. Check our pricing page for current rates. Implement caching to reduce costs.
Q: Can NPCs generate inappropriate content?
A: Our API includes content filtering, but you should also implement your own content moderation and clear guidelines in your NPC personalities. Always test thoroughly.
Q: How do I handle multiple languages?
A: Include the desired language in your system message. For example: "Respond only in French" or "Detect the player's language and respond accordingly."
Q: Can I use the same NPC across multiple game sessions?
A: Yes! Save the NPC's personality and memory data to your game's persistent storage. Load this data when creating the NPC instance in new sessions.
Q: What's the recommended response time for NPC interactions?
A: Aim for under 2 seconds for standard responses. Use loading indicators for longer requests, and consider pre-generating responses for critical NPCs.
Q: How do I prevent NPCs from breaking character?
A: Be very specific in your personality definition. Include examples of in-character responses and explicitly state what the NPC should avoid discussing or how they should handle off-topic questions.
Need More Help?
Still having issues or have specific questions about implementing AI NPCs in your game?
Ready to Build Your First NPC?
Follow these steps to get started with intelligent NPCs in your game
Get Your API Key
Sign up and create your first API key to start making requests to our NPC generation endpoints.
Get API KeyDesign Your Character
Use our personality template to create a rich character profile that defines how your NPC thinks and acts.
View TemplateImplement & Scale
Add memory systems, decision-making, and tool calls to create truly intelligent NPCs.
Implementation GuideNeed help with your NPCs?
Join our community of game developers to share tips and get advice. Join our Discord server