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

302 lines
11 KiB
Markdown

# 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)
```rust
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)
```rust
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)
```rust
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.