chronicle
Event-centric narrative knowledge graphs with temporal verification.
A Rust crate for structured world-building: load authored narrative content into a typed, event-centric knowledge graph, validate it for consistency, and query it.
The Problem
World-building for narrative-heavy games accumulates as disconnected documents that drift into inconsistency. Characters contradict themselves across files, timelines break, and AI-generated content introduces plausible-sounding details that conflict with established canon. At scale, nobody can hold the world in their head.
The Approach
Replace disconnected prose with structured entity-relation graphs. Every piece of world-building — character, faction, location, event — is a typed node with explicit, validated relationships. Events are the connective tissue (adapted from CIDOC CRM, ISO 21127). Temporal consistency uses Allen's Interval Algebra.
Usage
use Chronicle;
use *;
// Load a world from RON files
let graph = from_directory?;
// Validate consistency
let report = graph.validate;
for error in &report.errors
// Typed queries
let kaine = graph.actor.unwrap;
let events = kaine.events;
let contacts = kaine.interactions.people;
let chain = graph.event.unwrap.causal_chain;
let status = graph.place.unwrap.status_at; // Destroyed
// Check if a proposed event is consistent
let proposed = Event ;
match graph.can_add_event
// Subjective accounts with fidelity ratings
let accounts = graph.accounts_of;
for account in accounts
Content Format
World data is authored as RON files in a directory structure. Entity type is inferred from the subdirectory name:
world/
├── actors/ # Vec<Actor> — characters, factions, organizations
├── places/ # Vec<Place> — settlements, regions, landmarks
├── events/ # Vec<Event> — battles, discoveries, political events
├── concepts/ # Vec<Concept> — religions, technologies, artifacts
└── accounts/ # Vec<Account> — subjective narrative text
Narrative text uses {entity_id} references:
(
id: "kaine_siege_journal",
source: "kaine_durgan",
fidelity: Biased,
event_refs: ["siege_of_silica"],
text: "We burned {silica}. The {mirror_order} call it a massacre. We call it sanitation.",
)
Features
- Event-centric model: All relationships pass through events (who, where, when, why)
- Temporal verification: Allen's Interval Algebra catches impossible timelines
- State tracking: Dead actors can't participate in future events; destroyed places can't host them
- Configurable policies:
ValidationConfigcontrols which statuses are terminal - Subjective fragments: Model unreliable narrators with fidelity ratings (Canonical, Partial, Biased, etc.)
- Typed queries: Method chains over structured data, not natural language
- Insertion verification:
can_add_event()checks proposed records against the existing graph
Custom Validation Config
use ;
let config = ValidationConfig ;
let graph = from_directory_with_config?;
Dependencies
| Crate | Purpose |
|---|---|
petgraph |
Graph structure and traversal algorithms |
allen-intervals |
Temporal consistency verification (Allen's Interval Algebra) |
serde + ron |
Deserialization of hand-authored content |
thiserror |
Error types |
No async, no database, no network, no GPU.
Status
Phases 1–4 complete. Not yet published on crates.io.
- ✅ Graph model, loading, edge construction
- ✅ Validation (referential, temporal, state, orphan detection)
- ✅ Typed query API (actor, event, place, concept queries)
- ✅ Insertion verification (
can_add_eventwithValidationConfig) - ✅ Subjective fragments (accounts with fidelity ratings)
- 🔲 Saltglass-steppe integration (first consumer)
License
MIT