Long-Term Memory
NPCs can remember past conversations with individual players across play sessions.
Overview
Without memory:
Day 1 - Player: "My name is Alex"
NPC: "Nice to meet you, Alex!"
Day 7 - Player: "Do you remember me?"
NPC: "I'm sorry, have we met?" ❌With memory:
Day 1 - Player: "My name is Alex"
NPC: "Nice to meet you, Alex!"
Day 7 - Player: "Do you remember me?"
NPC: "Of course, Alex! Good to see you again!" ✓How It Works
Memory Storage
During conversation, important moments are automatically extracted:
Player: "I'm searching for my lost sister."
→ Memory stored: "Player is searching for their lost sister"Memory Retrieval
When an NPC responds, relevant past memories are automatically recalled and used to personalize the response.
Example:
Current message: "Have you seen any strangers around here?"
Retrieved memories:
- "Player is searching for their lost sister"
- "Player mentioned sister has red hair"
Response: "No strangers lately, but I'll keep an eye out for
someone with red hair, like you mentioned."Enabling Memory
In Game Engine SDKs
Example (C#):
npc.EnableMemoryRetrieval = true; // Retrieve past memoriesMemory storage is automatic: when a playerId is provided and memory is enabled for the project, important moments are extracted and stored server-side.
Requirements:
- Production backend setup (see Server Integration)
playerIdprovided in requestsentityMindIdset on NPC
In API Requests
{
"text": "Hello!",
"entityMindId": "clxyz_blacksmith",
"playerId": "player_001",
"memory": {
"retrieve": true
}
}Player IDs
Player IDs uniquely identify individual players for memory storage.
Good choices:
- Platform IDs:
steam_76561198012345678 - Game account IDs:
account_12345 - Persistent UUIDs:
550e8400-e29b-41d4-a716-446655440000
Avoid:
- Temporary session IDs (memories won’t persist)
- Email addresses or real names (PII concerns)
- Device IDs (players switch devices)
Example Implementation (C#)
public static string GetPlayerId()
{
var playerId = PlayerPrefs.GetString("LoreMind_PlayerId");
if (string.IsNullOrEmpty(playerId))
{
playerId = $"player_{System.Guid.NewGuid()}";
PlayerPrefs.SetString("LoreMind_PlayerId", playerId);
PlayerPrefs.Save();
}
return playerId;
}For multiplayer with accounts:
return $"steam_{SteamUser.GetSteamID()}";
// or
return $"account_{GameAccount.CurrentUser.Id}";Memory Extraction
What Gets Extracted
- Personal information (names, professions, background)
- Relationships (friends, family, allies)
- Goals and quests (what player is doing)
- Preferences (likes, dislikes)
- Past events (things that happened)
What Doesn’t Get Extracted
- Trivial greetings (“Hi”, “Hello”)
- Generic questions (“What do you sell?”)
- PII (emails, phone numbers, addresses)
PII Filtering
Personally identifiable information is automatically filtered to protect player privacy. Sensitive data like contact information is never stored in memories.
Memory Checkpoints
When conversations exceed maxSessionLength (default: 20 turns):
- Platform extracts memories from conversation
- Stores them in long-term memory
- Returns
memoryCheckpoint: truein response
var response = await npc.RespondAsync("...");
if (response.metadata.memoryCheckpoint)
{
// Safe to trim conversation history
conversationHistory.RemoveRange(0, 10);
Debug.Log("Memories auto-saved - conversation hit max session length");
}Cost Impact
Memory operations add incremental costs for retrieval and storage. Costs are typically a small percentage of total interaction cost.
See Billing for cost monitoring.
Testing Memory
In Dashboard Playground
The Playground has a full memory-testing workflow — enable memory with a test player ID, hold a conversation, clear the session, and verify recall. The step-by-step walkthrough is in Playground → Testing Long-Term Memory.
In Code (C# Example)
async void TestMemory()
{
// First conversation - establish memory
var response1 = await npc.RespondAsync("Hi! My name is Alex and I'm a blacksmith.");
Debug.Log(response1.response);
// Second conversation - test recall
npc.ClearConversationHistory(); // clears session history, not memory
var response2 = await npc.RespondAsync("Do you remember me?");
Debug.Log(response2.response); // Should reference Alex / blacksmith
}Use the same test player ID across both conversations, and allow a moment between them (memories are embedded asynchronously). Inspect what was stored in the dashboard’s Test Players view.
Best Practices
When to Use Memory
Good use cases:
- Main story NPCs
- Recurring side characters
- Merchants/shopkeepers players visit often
- Quest givers with long arcs
Skip memory for:
- One-off NPCs (random encounters)
- Generic guards/servants
- Tutorial NPCs
Memory-Aware Dialogue
Memory retrieval is transparent: the NPC’s response text naturally reflects what it remembers, so you don’t need to branch on it. If you want first-meeting logic, track it in your own game state:
if (!playerData.HasMetNPC(npc.EntityMindId))
{
// First meeting - introduction flow
playerData.MarkNPCMet(npc.EntityMindId);
}Troubleshooting
Memories not being stored
- Check
playerIdis provided - Check
entityMindIdis provided - Verify project has memory enabled (Long-Term Memory in project settings)
- Say something memorable - trivial greetings aren’t extracted
Memories not being retrieved
- Check
memory.retrieveistruein the request - Same
playerIdin both conversations - Same
entityMindId(memories are per-NPC) - Allow time between storage and retrieval (embeddings process async)
Wrong memories retrieved
The system found different memories more relevant. Check memory content in the dashboard or adjust retrieval settings.
Next Steps
- Entity Minds - Configure NPC personalities
- Billing - Monitor memory costs
- Unity SDK - Implementation guide