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>
302 lines
11 KiB
Markdown
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.
|