Chroma Golem API Documentation

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?"
      }
    ]
  }'
1. Define Personality

Start with core traits, background, and motivations in your system message

2. Add Context

Include current situation, location, and recent events

3. Scale Up

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.

U

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;
}
UE

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);
};
JS

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

1

Get Your API Key

Sign up and create your first API key to start making requests to our NPC generation endpoints.

Get API Key
2

Design Your Character

Use our personality template to create a rich character profile that defines how your NPC thinks and acts.

View Template
3

Implement & Scale

Add memory systems, decision-making, and tool calls to create truly intelligent NPCs.

Implementation Guide

Need help with your NPCs?

Join our community of game developers to share tips and get advice. Join our Discord server

Back to your dashboard
View my API keys