45 files covering the v0.1 vertical slice content: 17 NPC profiles across 3 tiers, 5 triangles, 3 social sites, 7 factions, 6 technology entries, 3 contraband types, knowledge vocabulary (FactIds, entity attributes, relationship states), and monologue authoring guide. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
11 KiB
Entity Knowledge Attributes
Canonical keys for the EntityKnowledge.known_attributes BTreeMap (defined in server/src/knowledge/types.rs). These keys structure what one entity knows about another.
Overview
EntityKnowledge.known_attributes is a BTreeMap<String, String> — key-value pairs where:
- Key: Structured attribute name (defined below)
- Value: String representation of the attribute
The knowledge graph uses these attributes to determine:
- What the observer's monologue says about the target
- Which dialogue lines are available
- How the target renders in the observer snapshot (name vs. description)
- Whether secrets or contradictions are discovered
Identity Attributes
name
Value format: Full name as known to the observer.
Examples:
"Kael Davan"— observer knows full name"Kael"— observer knows first name only"the dock worker"— observer doesn't know name, only role
Usage: Monologue and dialogue rendering. If name is absent or generic, monologue says "the dock worker" instead of "Kael."
role
Value format: Occupational or social role.
Examples:
"dock worker""shift supervisor""bartender""off-duty security""ring coordinator"(if known)
Usage: Default descriptor when name is unknown. Access tier calculation (authority figures get different treatment).
faction
Value format: Institutional or organizational allegiance.
Examples:
"Commission"— Sera, Torek, Detective"civilian"— most NPCs"ring member"— if discovered"unknown"— not yet determined
Usage: Access tier logic. Commission-tagged individuals trigger different NPC behavior. Dialogue selection uses this for authority/peer filtering.
species
Value format: Species identifier (future-proofing — v0.1 is all human).
Examples:
"human"(default)- (Future: other species as defined)
Usage: Not load-bearing in v0.1. Placeholder for future non-human NPCs.
Social Attributes
relationship_type
Value format: Relationship category from observer's perspective.
Examples:
"colleague"— Kael to smuggler"friend"— Sera to detective"authority figure"— Voss to subordinates"suspect"— Kael to detective (post-discovery)"partner"— Hael to Kael"stranger"— new NPCs
Usage: Drives RelationshipState calculation (Unknown/Known/Friendly/PersonOfInterest/Hostile). Determines emotional tone of monologue.
trust_level
Value format: Trust assessment (subjective, observer's judgment).
Examples:
"trusted"— high trust, shares sensitive information"reliable"— professional trust"uncertain"— cautiously neutral"suspicious"— flagged for observation"compromised"— known to be under pressure or bought
Usage: Gates trust-tier dialogue (surface/real/secret). Detective tracking trust levels determines which NPCs can be turned.
Behavioral Attributes
routine_pattern
Value format: Observed routine description.
Examples:
"morning shift at logistics hub, bar after shift""arrives 06:00, break 10:30, departs 14:00""irregular schedule, seen at odd hours"
Usage: Deviation detection. When current behavior doesn't match known routine_pattern, monologue flags it.
behavior_flags
Value format: Comma-separated behavioral observations.
Examples:
"nervous,lattice_checking"— Kael during contradiction arc"avoidance_pattern,evasive"— Sera avoiding Torek"spending_beyond_means"— Torek buying rounds"reliable,punctual"— baseline normal behavior
Usage: Tell system. Multiple flags accumulate as evidence. Detective's analytical lattice auto-flags some behaviors.
Secret Attributes
secret_held
Value format: What the observer believes this entity is hiding.
Examples:
"ring membership"— detective's suspicion about Kael"unreported evidence"— smuggler's read on Sera (if observant)"gambling debt"— if Drin's vulnerability is discovered"exit attempt"— if Kael's unauthorized contact is discovered
Usage: Drives PersonOfInterest state. Gates confrontation dialogue. Smuggler and detective track different secrets about the same NPCs.
secret_confidence
Value format: How certain the observer is about the secret.
Examples:
"suspected"— behavioral flags suggest something, no proof"likely"— multiple indicators align"confirmed"— direct evidence or confession
Usage: Dialogue tone. "Suspected" secrets allow fishing questions. "Confirmed" secrets enable direct confrontation.
Investigation Attributes (Detective-Specific)
tell_observed
Value format: Specific tell noted by the detective.
Examples:
"looks left when lying"— Kael's tell"leaves when Torek arrives"— Sera's avoidance"checks lattice before answering"— nervous behavior"forced casualness after shift supervisor passes"— hypervigilance
Usage: Behavioral profiling. Accumulated tells build case strength. Monologue references specific tells when they recur.
contradiction_flagged
Value format: Boolean-ish flag (presence of key = true).
Examples:
"meeting_unknown_contact"— Kael contradiction"avoidance_inconsistency"— Sera contradiction"manifest_access_mismatch"— Maret handling cargo she shouldn't process
Usage: THE FRIEND arc trigger. When this attribute is set, monologue tone shifts. Dialogue options change. RelationshipState moves toward PersonOfInterest.
Examples: Full EntityKnowledge Entries
Smuggler's knowledge of Kael (early game, pre-contradiction)
EntityKnowledge {
last_known_position: Some(TilePosition { x: 45, y: 12 }), // logistics hub dock
last_observed_tick: 1200,
last_updated_tick: 1200,
confidence: KnowledgeConfidence::Direct, // currently in LOS
source: KnowledgeSource::DirectObservation { tick: 1200 },
state: KnowledgeState::Active,
relationship: RelationshipState::Friendly,
known_attributes: BTreeMap::from([
("name".to_string(), "Kael Davan".to_string()),
("role".to_string(), "dock worker".to_string()),
("faction".to_string(), "ring member".to_string()), // smuggler knows
("species".to_string(), "human".to_string()),
("relationship_type".to_string(), "close colleague".to_string()),
("trust_level".to_string(), "trusted".to_string()),
("routine_pattern".to_string(), "morning shift 06:00-14:00, bar after shift".to_string()),
("behavior_flags".to_string(), "reliable,punctual".to_string()),
]),
}
Detective's knowledge of Kael (mid-game, post-contradiction discovery)
EntityKnowledge {
last_known_position: Some(TilePosition { x: 45, y: 12 }),
last_observed_tick: 2400,
last_updated_tick: 2600, // updated via inference after observation
confidence: KnowledgeConfidence::KnowsDetails, // not currently in LOS, but detailed knowledge
source: KnowledgeSource::Inferred {
basis: vec![
FactId("investigation.manifest_discrepancy".to_string()),
FactId("investigation.shift_mismatch".to_string()),
],
},
state: KnowledgeState::Active,
relationship: RelationshipState::PersonOfInterest, // flagged
known_attributes: BTreeMap::from([
("name".to_string(), "Kael Davan".to_string()),
("role".to_string(), "dock worker".to_string()),
("faction".to_string(), "civilian".to_string()), // detective doesn't know ring membership yet
("species".to_string(), "human".to_string()),
("relationship_type".to_string(), "suspect".to_string()),
("trust_level".to_string(), "suspicious".to_string()),
("routine_pattern".to_string(), "morning shift, frequent late departures".to_string()),
("behavior_flags".to_string(), "nervous,lattice_checking,evasive".to_string()),
("tell_observed".to_string(), "looks left when lying".to_string()),
("secret_held".to_string(), "unauthorized meetings".to_string()),
("secret_confidence".to_string(), "confirmed".to_string()),
("contradiction_flagged".to_string(), "meeting_unknown_contact".to_string()),
]),
}
Smuggler's knowledge of Sera (if observant, mid-game)
EntityKnowledge {
last_known_position: Some(TilePosition { x: 78, y: 34 }), // bar
last_observed_tick: 1800,
last_updated_tick: 2100,
confidence: KnowledgeConfidence::KnowsOf,
source: KnowledgeSource::DirectObservation { tick: 1800 },
state: KnowledgeState::Active,
relationship: RelationshipState::Known, // not Friendly -- smuggler doesn't know Sera well
known_attributes: BTreeMap::from([
("name".to_string(), "Sera Venn".to_string()),
("role".to_string(), "Commission field tech".to_string()),
("faction".to_string(), "Commission".to_string()),
("species".to_string(), "human".to_string()),
("relationship_type".to_string(), "institutional presence".to_string()),
("trust_level".to_string(), "uncertain".to_string()),
("routine_pattern".to_string(), "bar regular, off-duty evenings".to_string()),
("behavior_flags".to_string(), "observant,avoidance_pattern".to_string()),
("secret_held".to_string(), "knows something about Torek or Hael".to_string()),
("secret_confidence".to_string(), "suspected".to_string()),
]),
}
Attribute Lifecycle
- Initial state (Unknown NPC): No attributes. EntityKnowledge doesn't exist yet.
- First observation (Direct confidence):
name(if visible via lattice query or introduction),role(inferred from context),species,routine_patternstarts accumulating. - Repeated interaction (KnowsOf):
relationship_typeevolves,trust_levelset,behavior_flagsaccumulate. - Investigation depth (KnowsDetails):
secret_held,tell_observed,contradiction_flaggedadded by detective. Smuggler gainsfactionclarity. - Knowledge decay: Attributes persist even as confidence decays. A KnowsOf entry retains all attributes; only positional certainty degrades.
Content Authoring Guidance
- Monologue prerequisites can reference specific attributes:
known_attributes["secret_held"] == "ring membership". - Dialogue access tiers can check
factionorrelationship_type. - Tell system observations append to
behavior_flagsas comma-separated values. - THE FRIEND contradiction is triggered by setting
contradiction_flagged.
Total canonical keys: 14 (4 identity, 2 social, 2 behavioral, 2 secret, 2 investigation, 2 detective-specific). Additional keys can be added as needed, but these 14 cover v0.1 requirements.