Files
settled-reach/docs/wiki/knowledge/entity-attributes.md
T
jpmschweitzerandClaude Opus 4.6 3776443e8a docs(wiki): establish Sova Transit District game world glossary
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>
2026-02-12 16:18:49 +01:00

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

  1. Initial state (Unknown NPC): No attributes. EntityKnowledge doesn't exist yet.
  2. First observation (Direct confidence): name (if visible via lattice query or introduction), role (inferred from context), species, routine_pattern starts accumulating.
  3. Repeated interaction (KnowsOf): relationship_type evolves, trust_level set, behavior_flags accumulate.
  4. Investigation depth (KnowsDetails): secret_held, tell_observed, contradiction_flagged added by detective. Smuggler gains faction clarity.
  5. 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 faction or relationship_type.
  • Tell system observations append to behavior_flags as 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.