NPC contradiction detector and belief repair for game worlds
Project description
worldoracle
NPC contradiction detector and belief repair for game worlds.
Quick Start · How It Works · Features · CLI Reference · MCP · OpenAI Tools · Alternatives
Why
Game NPCs frequently end up with contradictory world models: the blacksmith "knows" the king is both alive and dead, the guard believes the bridge is passable while the quest log says it collapsed. These inconsistencies break immersion and cause dialogue bugs.
worldoracle gives every NPC a typed belief store with automatic contradiction detection and principled repair strategies — so your world stays consistent even when multiple event sources update the same facts.
How It Works
flowchart LR
A[Game event / quest trigger] --> B[WorldPredicate]
B --> C[WorldOracleStore]
C --> D{ContradictionDetector}
D -- contradictions found --> E[BeliefRepairer]
E --> F[RepairFrame]
F --> G[Updated BeliefState]
D -- no contradictions --> G
- WorldPredicate — a typed belief:
subject,attribute,value,source,confidence,timestamp. Content-addressed by SHA-256 ofsubject|attribute|str(value). - BeliefState — an NPC's full belief set; also content-addressed.
- ContradictionDetector — scans for predicates with the same
(subject, attribute)but different values. - BeliefRepairer — resolves each contradiction using strategies:
prefer_newer,prefer_higher_confidence,prefer_observation.
Features
| Feature | Status |
|---|---|
| Content-addressed predicates (SHA-256) | ✅ |
SQLite persistence (WorldOracleStore) |
✅ |
| Contradiction detection | ✅ |
| Belief repair (3 strategies) | ✅ |
| Rich CLI (7 subcommands) | ✅ |
| FastAPI REST server | ✅ |
| MCP server for Claude Desktop | ✅ |
| OpenAI function-calling tools | ✅ |
| 93 tests, >98% coverage | ✅ |
| Fully typed (py.typed) | ✅ |
Quick Start
pip install worldoracle
from worldoracle import WorldPredicate, BeliefState, ContradictionDetector, BeliefRepairer
# Build a belief state
state = BeliefState(npc_id="guard-1")
state.add(WorldPredicate(subject="king", attribute="alive", value=True, source="quest-giver", confidence=0.8, timestamp=1.0))
state.add(WorldPredicate(subject="king", attribute="alive", value=False, source="observation", confidence=1.0, timestamp=2.0))
# Detect contradictions
detector = ContradictionDetector()
pairs = detector.detect(state)
print(f"Found {len(pairs)} contradiction(s)")
# Repair — strategies are applied automatically in priority order:
# prefer_newer → prefer_higher_confidence → prefer_observation
repairer = BeliefRepairer()
for a, b in pairs:
frame = repairer.repair(a, b) # repair(pred_a, pred_b) → RepairFrame
print(f"Resolved: {frame.resolved_value!r} ({frame.strategy})")
CLI Reference
worldoracle [--db PATH] COMMAND [ARGS]
| Command | Description |
|---|---|
add NPC_ID SUBJECT ATTRIBUTE VALUE |
Add a predicate to an NPC's belief state |
check NPC_ID |
Detect contradictions |
repair NPC_ID |
Generate repair frames for all contradictions |
beliefs NPC_ID |
List all beliefs for an NPC |
consistency |
Run full consistency check across all NPCs |
diff NPC_ID TIMESTAMP_A TIMESTAMP_B |
Diff belief state at two points in time |
status |
Show database stats |
# Add beliefs
worldoracle add guard-1 king alive True --source observation --confidence 0.9 --timestamp 100
worldoracle add guard-1 king alive False --source rumor --confidence 0.5 --timestamp 50
# Check for contradictions
worldoracle check guard-1
# Found 1 contradiction(s) for guard-1:
# CONFLICT: king.alive: 'True' vs 'False'
# Repair
worldoracle repair guard-1
REST Server
Install the API extra and start the server:
pip install 'worldoracle[api]'
uvicorn worldoracle.api:app --reload
The OpenAPI docs are available at http://localhost:8000/docs. See openapi.yaml for the full schema.
Repo Tree
worldoracle/
├── src/worldoracle/ ← Python package
│ ├── predicate.py ← WorldPredicate, BeliefState, Detector, Repairer
│ ├── store.py ← SQLite persistence
│ ├── cli.py ← Click CLI
│ ├── api.py ← FastAPI server
│ ├── mcp_server.py ← MCP server
│ ├── report.py ← Rich + JSON + Markdown formatters
│ └── py.typed
├── tests/ ← 45+ tests
├── docs/
├── tools/openai-tools.json
└── openapi.yaml
MCP / Claude Desktop
Install the MCP server:
pip install "worldoracle[mcp]"
Add to ~/.config/claude/claude_desktop_config.json:
{
"mcpServers": {
"worldoracle": {
"command": "worldoracle-mcp"
}
}
}
Tools exposed: add_predicate, check_beliefs, repair_contradictions.
See docs/mcp.md and Smithery for hosted registry.
OpenAI Tools
The tools/openai-tools.json file defines function-calling schemas for GPT-4o and Codex CLI:
cat tools/openai-tools.json
See docs/openai.md for integration examples.
Alternatives
| Tool | Approach | worldoracle advantage |
|---|---|---|
| Manual quest flags | Unstructured booleans | Typed, content-addressed, auditable |
| Event sourcing logs | Append-only, no repair | Built-in contradiction detection + repair |
| Prolog / logic engines | Heavyweight runtime | Zero-dep Python, SQLite storage |
| LLM world models | Probabilistic, opaque | Deterministic, inspectable, fast |
Topics
This project is tagged: #npc #game-ai #belief-revision #llm #agents #mcp #fastapi
GitHub Topics: npc, belief-revision, game-ai, contradiction, agents, mcp, llmops
Case Studies
See how teams are using worldoracle in production:
- Eliminating Immersion-Breaking NPC Contradictions in a Narrative Game — Narrative Forge eliminates NPC belief contradictions across 300 NPCs with a 12ms consistency check
- Automated Contradiction Resolution Across 50+ Data Sources — Meridian Intelligence reduces manual reconciliation from 4 hours to 0 per report
Stay Updated
Subscribe to The Silence Layer — weekly dispatches on production AI infrastructure, new releases, and the failure modes that production AI systems don't surface until it's too late.
Star History
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file worldoracle-0.1.1.tar.gz.
File metadata
- Download URL: worldoracle-0.1.1.tar.gz
- Upload date:
- Size: 1.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54013cc8c502798b2f7c8508066c1bc9589802d08fd59484d1486484476842ca
|
|
| MD5 |
b85df3743ac155f1ba2697cf0f0a19e1
|
|
| BLAKE2b-256 |
5c1fb9b0e27ad154a27791797a776dd1cf0379567028f9416ea01bf19d518dc6
|
File details
Details for the file worldoracle-0.1.1-py3-none-any.whl.
File metadata
- Download URL: worldoracle-0.1.1-py3-none-any.whl
- Upload date:
- Size: 21.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ead02b92878af7f33f6a713ba1a870242ed371d158d42094ccc4f74fde3d7548
|
|
| MD5 |
3f1b1cd2c433c8f5d8f6fea792ba6141
|
|
| BLAKE2b-256 |
41b2e487ebad732a793fd3e8d1f7d0df514bcb1cd4119361bbd8a26ec0176a20
|