| Crates.io | npc-neural-affect-matrix |
| lib.rs | npc-neural-affect-matrix |
| version | 0.0.1 |
| created_at | 2025-11-12 17:37:35.042724+00 |
| updated_at | 2025-11-12 17:37:35.042724+00 |
| description | A neural affect matrix system for NPCs |
| homepage | |
| repository | https://github.com/mavdol/npc-neural-affect-matrix |
| max_upload_size | |
| id | 1929686 |
| size | 237,490 |
Give each NPC persistent emotions and dynamic personalities that evolve through interactions.
Traditional NPCs rely on conditional logic and don't understand the source of their actions. This often leads to bugs or incoherent decisions that break immersion and make characters feel artificial. The goal is to make NPCs more human by giving them emotions as an important source of their behavior. Emotions that persist over time, creating unique personalities through experiences.
The system works as a simple api for any game engine or modding tools. You can instantly check how any NPC feels about specific characters or entity, then use that emotional data to create more believable interactions.
Here's what makes NPCs unique:
Think about how humans work: we feel first, then rationalize our decisions. NPCs should work the same way.
We use Russell's Circumplex Model, a proven scientific framework that maps human emotions onto a simple 2D coordinate system:
This creates an emotional landscape where every feeling can be precisely mapped and tracked over time.

🔗 Visualize emotions: Interactive Valence-Arousal Explorer
[ Input Text ] → [ Neural Affect ML Model ] → [ Memory Retrieval ] →
[ Contextual Re-evaluation ] → [ Emotional Response (Valence, Arousal) ]
Language Support: Currently optimized for English text
Build for production
Since the majority of video game engines run on Windows, we've streamlined the build process to make integration as simple as possible.
chmod +x build.sh
./build.sh
Find your binaries
📁 dist/
├── npc_neural_affect_matrix.dll # Main file
├── onnxruntime.dll # AI runtime
└── onnxruntime_providers_shared.dll # AI providers
Note: Docker is required to execute build.sh
src/
├── api/ # C API endpoints
│ ├── services/ # Files that contain functions that communicate with modules
│ ├── endpoints.rs # All the functions that we can call
│ └── type.rs # The default types used
├── modules/
│ ├── emotion/ # Neural emotion prediction
│ └── memory/ # Memory management
├── config/ # Configuration handling
The Neural Affect Matrix provides a C API for seamless integration with game engines like Unity, Unreal Engine, and other C/C++ applications.
initialize_neural_matrixInitializes the shared neural model that powers emotion prediction. This function must be called before using any other API functions to ensure the AI model is properly loaded and ready for use.
ApiResult* initialize_neural_matrix();
Response Fields:
Important Notes:
create_npc_sessionInitializes a new NPC session with unique emotional state and memory storage. Each session represents an independent NPC instance that can maintain its own relationships, memories, and emotional evolution.
ApiResult* create_npc_session(
const char* config_json,
const char* npc_memory_json
);
Parameters:
config_json (const char*): JSON string containing NPC configuration (required)
npc_memory_json (const char*): JSON string containing existing memory data (optional)
get_npc_memory() to restore saved NPCsResponse Fields:
npc_id (string): Unique identifier for the NPC session, required for all subsequent API callsremove_npc_sessionCleanly removes an NPC session and frees all associated memory. This permanently deletes the NPC's emotional state and memory history.
ApiResult* remove_npc_session(const char* npc_id);
Parameters:
npc_id (const char*): Unique NPC session identifier (required)
create_npc_sessionResponse Fields:
evaluate_interactionThe core function that processes text input through the neural emotion prediction model, integrates it with the NPC's memory, and returns an emotional response. This function updates the NPC's memory with the new interaction.
ApiResult* evaluate_interaction(
const char* npc_id,
const char* text,
const char* source_id
);
Parameters:
npc_id (const char*): NPC session identifier (required)
text (const char*): Input text to process (required)
source_id (const char*): Identifier for who/what is causing this interaction (optional)
Response Fields:
valence (float, -1.0 to 1.0): Emotional pleasantness/unpleasantness of the responsearousal (float, -1.0 to 1.0): Emotional energy/calmness of the responseget_current_emotionRetrieves the NPC's current overall emotional state by calculating the weighted average of all memories, with recent interactions having more influence.
ApiResult* get_current_emotion(const char* npc_id);
Parameters:
npc_id (const char*): NPC session identifier (required)Response Fields:
valence (float, -1.0 to 1.0): Emotional pleasantness/unpleasantness of the responsearousal (float, -1.0 to 1.0): Emotional energy/calmness of the responseget_current_emotion_by_source_idRetrieves the NPC's emotional state toward a specific character or entity, based only on interactions with that source.
ApiResult* get_current_emotion_by_source_id(
const char* npc_id,
const char* source_id
);
Parameters:
npc_id (const char*): NPC session identifier (required)source_id (const char*): Identifier for the specific source (required)Response Fields:
valence (float, -1.0 to 1.0): Emotional pleasantness/unpleasantness of the responsearousal (float, -1.0 to 1.0): Emotional energy/calmness of the responseget_npc_memoryExports all memory data for an NPC in JSON format. This is essential for save/load systems and debugging emotional state.
ApiResult* get_npc_memory(const char* npc_id);
Parameters:
npc_id (const char*): NPC session identifier (required)Response Format:
[
{
"id": "mem_001",
"source_id": "player_character",
"content": "Thank you for saving my family",
"valence": 0.85,
"arousal": 0.45,
"past_time": 1440
}
]
clear_npc_memoryPermanently deletes all memory entries for an NPC, effectively resetting their emotional state to the base personality.
ApiResult* clear_npc_memory(const char* npc_id);
Parameters:
npc_id (const char*): NPC session identifier (required)free_api_resultCritical function that must be called after every API function to prevent memory leaks. Failure to call this will cause memory accumulation.
void free_api_result(ApiResult* result);
Parameters:
result (ApiResult*): Pointer returned from any API function (required)All functions return an ApiResult structure that provides error handling and data management:
typedef struct {
bool success; // Operation success status
char* data; // JSON response data (on success)
char* error; // Error message (on failure)
} ApiResult;
Field Descriptions:
success (bool): true if operation completed successfully, false if an error occurreddata (char*): JSON-formatted response data when success is true, NULL when operation failserror (char*): Human-readable error message when success is false, NULL on successful operationsConfiguration Fields:
identity.name (string): Display name for the NPC, used in logging and debuggingidentity.background (string): Character backstory that influences emotional responses and provides context for interactionspersonality.valence (float, -1.0 to 1.0): Default emotional disposition on the pleasant/unpleasant axis. Positive values create optimistic characters, negative values create pessimistic onespersonality.arousal (float, -1.0 to 1.0): Default energy level on the calm/excited axis. Positive values create energetic characters, negative values create calm onesmemory.decay_rate (float, 0.0 to 1.0): Rate at which old memories fade over time. Higher values make NPCs forget faster, lower values create longer-lasting impressionsNPCs are configured using JSON with the following structure:
{
"identity": {
"name": "Village Guard",
"background": "A loyal guard who protects the village from threats. Has served for 15 years and takes pride in maintaining order."
},
"personality": {
"valence": 0.2,
"arousal": -0.1
},
"memory": {
"decay_rate": 0.1
}
}
Each NPC maintains a local memory of interactions:
{
"source_id": "player_character",
"content": "Thank you for saving my life",
"valence": 0.85,
"arousal": 0.45,
"past_time": 1440
}
Fields Explained:
source_id: Who/what caused this emotional memoryvalence/arousal: Emotional coordinates for this specific interactionpast_time: Game time elapsed (in minutes) when this occurreddecay_rateWe welcome contributions! Here's how to get started:
git checkout -b feature/amazing-featurecargo testThis project is licensed under the MIT License - see the LICENSE file for details.