Files
settled-reach/docs/wiki/knowledge/relationship-states.md
T
jpmschweitzerandClaude Opus 4.6 64fea5139a docs(wiki): rename Hael to Naia Tamm, apply canonical full names, standardize shortcodes
Wave 0 wiki maintenance for Sprint 3:
- #372: Rename Hael → Naia Tamm across 16 living wiki files (phonetic collision fix)
- #371: Apply canonical full names to 11 single-name NPC headers and roster table
- #375: Replace hub_m_ → terminal_m_ shortcodes, add shortcode reference table,
  situation overlap rules, and mood exclusivity rules to monologue guide

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 17:45:04 +01:00

14 KiB

Relationship States and Transitions

How RelationshipState (defined in server/src/knowledge/types.rs) evolves during gameplay, with specific patterns for THE FRIEND contradictions and KnowledgeState integration.

Canonical States

From server/src/knowledge/types.rs:

pub enum RelationshipState {
    Unknown,    // Teal #4a9ebb
    Known,      // Soft green #6bc9a6
    Friendly,   // Soft green #6bc9a6 (same color, different semantics)
    PersonOfInterest,  // Amber #e8c547
    Hostile,    // Red #d45d5d
}

Visual rendering: D-033 entity color system. The client maps these states to colors. The knowledge graph determines the state.


State Semantics

Unknown

What it means: No prior knowledge of this entity. First encounter.

Monologue tone: Observational, neutral. "Who's that?"

Dialogue availability: Public-tier only. No trust-gated content.

Color: Teal — visually distinct from all other states.

Typical duration: First 30 seconds to 2 minutes of gameplay (until first direct interaction or lattice query).


Known

What it means: Recognized, neutral-to-positive. Not a threat, not a close ally.

Monologue tone: Casual acknowledgment. "There's Drin. Maintenance tech."

Dialogue availability: Public + peer-tier (if appropriate). No insider/secret content yet.

Color: Soft green — "safe enough."

Typical entities: Coworkers (smuggler), routine contacts (detective), flat NPCs, bar regulars.


Friendly

What it means: Positive relationship, trusted. Emotional connection or reliable professional rapport.

Monologue tone: Warm, personal. "Good to see Kael. Always reliable."

Dialogue availability: Public + peer + insider-tier. Trust-gated content unlocks. Some secret-tier content if relationship deepens.

Color: Soft green (same as Known — the distinction is semantic, not visual).

Typical entities: THE FRIEND NPCs (Kael to smuggler, Sera to detective), close colleagues, trusted contacts.

Why same color as Known: Visual simplicity for v0.1. Future refinement could add subtle shader variation (warmth, pulse, saturation).


PersonOfInterest

What it means: Flagged. Something's wrong. Under observation or suspicion.

Monologue tone: Analytical, cautious. "Kael's meeting someone I don't recognize. That's not normal."

Dialogue availability: Shifts. Trust-gated content may become unavailable. Confrontation options unlock.

Color: Amber — "pay attention."

Typical entities: NPCs caught in contradictions, suspects under investigation, people who've triggered tells.

THE FRIEND trigger: When THE FRIEND's contradiction is discovered, they transition from Friendly → PersonOfInterest. This is the emotional gut-punch moment.


Hostile

What it means: Character KNOWS there is danger. Threat confirmed.

Monologue tone: Alarm, threat assessment. "That's security. They're moving toward me."

Dialogue availability: Hostile-tier only (threats, demands, final warnings). All trust content locked.

Color: Red — "danger."

Typical entities: NPCs who've turned on the player, authority figures during a confrontation gone bad, exposed ring members cornered by the detective.

Rare in v0.1: Most NPCs don't reach Hostile. It's the endgame state for failed social maneuvering.


Transition Paths

Standard Progression (No Contradiction)

Unknown → Known → Friendly

Triggers:

  • Unknown → Known: First direct interaction OR lattice query identifies them.
  • Known → Friendly: Repeated positive interactions, shared drinks at bar, successful cooperation, trust-building dialogue.

Example: Detective meets a bar regular. Unknown (first visit) → Known (second visit, exchanged names) → Friendly (third visit, regular offers unprompted gossip).


Investigation Progression (Detective)

Unknown → Known → PersonOfInterest → Hostile (if confrontation fails)

Triggers:

  • Unknown → Known: Lattice query, case file match, first observation.
  • Known → PersonOfInterest: Behavioral flags accumulate, tells observed, manifest discrepancy linked to this NPC.
  • PersonOfInterest → Hostile: Confrontation attempt rejected, NPC realizes they're under investigation, escalation.

Example: Detective observes Kael. Unknown (first sight) → Known (lattice query: "Davan, K., dock worker") → PersonOfInterest (observed in restricted corridor, evasive answers) → Hostile (confrontation: "I know you're involved. You need to cooperate." / Kael: "Stay away from me.").


THE FRIEND Contradiction Arc (Kael — Smuggler's Perspective)

Friendly → PersonOfInterest → [resolution: Friendly-but-contaminated OR Hostile]

Phase 1: Friendly (baseline)

  • Kael is the smuggler's trusted colleague.
  • Monologue: fond, casual.
  • Color: soft green.
  • Dialogue: insider-tier, warm.

Phase 2: First Crack (still Friendly, but flags accumulating)

  • Behavioral flags: lattice_checking,distracted.
  • Monologue shifts slightly: "Kael's been quiet lately."
  • State unchanged (still Friendly), but EntityKnowledge.known_attributes["behavior_flags"] updates.

Phase 3: The Contradiction (Friendly → PersonOfInterest)

  • Trigger: Direct observation of Kael meeting unknown contact in Corridor B-7.
  • EntityKnowledge.known_attributes["contradiction_flagged"] = "meeting_unknown_contact".
  • RelationshipState transitions to PersonOfInterest.
  • Color shifts: soft green → amber.
  • Monologue: "That wasn't anyone from our rotation. Kael, what are you doing?"
  • Dialogue options change: confrontation unlocks, trust-tier content locks (Kael is evasive).

Phase 4: Post-Confrontation

  • Path A (understanding): Smuggler confronts Kael gently. Kael confesses: trying to exit the ring to protect Naia. RelationshipState remains PersonOfInterest but monologue tone shifts to conflicted sympathy. Color stays amber (still a problem), but dialogue reflects empathy.
  • Path B (betrayal): Smuggler reports Kael to Nils or pressures Kael harshly. Kael turns defensive. RelationshipStateHostile. Color → red. Kael avoids the smuggler, might actively obstruct.

THE FRIEND pattern: Friendly → PersonOfInterest is the emotional core. The player trusted Kael. Now Kael is amber. That color shift IS the narrative moment.


THE FRIEND Contradiction Arc (Sera — Detective's Perspective)

Friendly → PersonOfInterest → [resolution: Friendly-but-contaminated OR Known-distanced OR Hostile]

Phase 1: Friendly (baseline)

  • Sera is the detective's institutional contact and social anchor.
  • Monologue: professional warmth, relief.
  • Color: soft green.
  • Dialogue: peer-tier, cooperative, helpful.

Phase 2: Pattern Observation (still Friendly, but flags accumulating)

  • Behavioral flags: avoidance_pattern (Sera leaves when Torek arrives).
  • Monologue: "That's the third time. Sera leaves when Torek shows up."
  • State unchanged (still Friendly), but EntityKnowledge.known_attributes["behavior_flags"] updates.

Phase 3: The Contradiction (Friendly → PersonOfInterest)

  • Trigger: Detective asks Sera directly about Torek. Sera deflects unconvincingly.
  • EntityKnowledge.known_attributes["contradiction_flagged"] = "avoidance_inconsistency".
  • EntityKnowledge.known_attributes["secret_held"] = "unreported evidence" (detective's inference).
  • RelationshipState transitions to PersonOfInterest.
  • Color shifts: soft green → amber.
  • Monologue: "She's not lying. But she's not telling me everything. Sera, what do you know?"
  • Dialogue options change: pressing questions unlock, casual warmth diminishes.

Phase 4: Post-Confrontation

  • Path A (loyalty test): Detective confronts Sera about concealment. Sera confesses: sitting on evidence to protect Naia (friend of Sera, partner of Kael). Detective can choose: report Sera (Hostile), use the information without reporting her (PersonOfInterest → Known, relationship damaged), or protect Sera and accept the information gap (PersonOfInterest → Friendly-but-contaminated).
  • Path B (institutional): Detective reports Sera immediately. RelationshipStateHostile. Sera is reprimanded or reassigned. Color → red. The detective loses their only local ally.

THE FRIEND pattern: The detective's trust in Sera is tested. Amber means "my friend is hiding something." The resolution determines whether the friendship survives.


Contradiction Patterns: Kael + Sera

Both THE FRIEND NPCs follow the same structural arc, but the nature of the contradiction differs:

Dimension Kael (Smuggler's FRIEND) Sera (Detective's FRIEND)
Contradiction type Spatial deviation (meeting unknown contact) Behavioral avoidance (leaving when Torek arrives)
Discovery method Direct observation in restricted area Pattern recognition over multiple visits
What they're hiding Attempt to exit the ring (protect Naia) Unreported evidence (protect Naia)
Sympathetic motivation Family protection (Naia is Kael's partner) Friendship loyalty (Naia is Sera's friend)
Naia as connection Kael's personal life Sera's social network
Color shift timing Single observation event (immediate) Third occurrence (cumulative)
Confrontation stakes Ring security vs. personal loyalty Institutional duty vs. personal loyalty
Resolution spectrum Understanding ↔ Betrayal Protect friend ↔ Report corruption

Common structure: Both contradictions involve Naia as the emotional anchor. Naia is worried about Kael. Sera knows why (unreported evidence). Kael is trying to protect Naia (exit attempt). The smuggler and detective approach the same NPC web from opposite sides. THE FRIEND, in both cases, is the person caught in the middle trying to protect someone they care about.


KnowledgeState Integration

RelationshipState (social assessment) is orthogonal to KnowledgeState (logical validity).

Active (default)

What it means: The knowledge is currently believed true.

Effect on relationship: None directly. A Friendly NPC with Active knowledge remains Friendly.

Example: Smuggler's knowledge of Kael as "trusted colleague" is Active until the contradiction.


Contradicted

What it means: Conflicting information exists. Both the original belief and the contradiction receive this state.

Effect on relationship: This is the trigger for Friendly → PersonOfInterest.

When KnowledgeState becomes Contradicted, the system:

  1. Sets EntityKnowledge.state = KnowledgeState::Contradicted on the conflicting knowledge entries.
  2. Triggers a monologue event: "Wait, that doesn't match what I thought I knew."
  3. Evaluates RelationshipState transition. If the contradicted knowledge is about a Friendly NPC, transition to PersonOfInterest.

Example: Smuggler's knowledge "Kael operates within ring protocol" contradicts with new observation "Kael meeting unauthorized contact." Both entries become Contradicted. Monologue fires. Kael's RelationshipStatePersonOfInterest.


Stale

What it means: Knowledge has aged beyond the stale threshold (default 3600 ticks = 6 game-hours).

Effect on relationship: Degrades confidence but doesn't change relationship state. A Friendly NPC remains Friendly, but positional knowledge becomes unreliable.

Example: Smuggler last saw Kael at the hub 7 hours ago. last_known_position becomes Stale. Monologue: "Kael should be off-shift by now. Probably at the bar, but I haven't seen him."


Relationship State and Dialogue Selection

The dialogue system (D-028, D-035) uses RelationshipState as a filter:

Dialogue access tag Unknown Known Friendly PersonOfInterest Hostile
public
peer
insider
authority ✓ (if detective) ✓ (if detective) ✓ (if detective)
hostile

Key insight: PersonOfInterest locks out peer and insider content. When THE FRIEND transitions to PersonOfInterest, trust-gated dialogue disappears. The NPC becomes guarded. This is mechanically expressed through access-tier filtering.


Monologue Tone Shifts per State

Unknown → Known

  • Before: "Who's that?"
  • After: "That's Drin, the maintenance tech."

Shift: Identification. Observer now has context.


Known → Friendly

  • Before: "Drin's over there."
  • After: "Good to see Drin. Always fixes things without making a fuss."

Shift: Warmth. Personal regard.


Friendly → PersonOfInterest (THE FRIEND)

  • Before: "There's Kael. Good — I was starting to worry."
  • After: "Kael's here. But he's been acting strange. What's going on?"

Shift: Doubt contaminates warmth. The fond observation is now analytical.


PersonOfInterest → Hostile

  • Before: "Kael's avoiding me. Something's wrong."
  • After: "Kael just signaled security. He's turned on me."

Shift: Assessment → alarm.


Implementation Notes for Content Authors

  • Contradiction discovery sets EntityKnowledge.state = KnowledgeState::Contradicted AND triggers RelationshipState transition if applicable.
  • Monologue lines should reference RelationshipState in prerequisites:
    prerequisite:
      relationship_state: PersonOfInterest
      subject: kael_davan
    
  • Dialogue lines filter on access tier, which is derived from RelationshipState + character type (smuggler/detective/NPC role).
  • Color shifts are client-side rendering, but the knowledge graph determines the state. Content authors write to the state; the client handles the color.
  • THE FRIEND arc requires:
    • Friendly baseline (relationship history)
    • Observable contradiction (spatial deviation or behavioral pattern)
    • contradiction_flagged attribute set
    • Monologue shift (analytical doubt)
    • Dialogue shift (confrontation options unlock, trust options lock)
    • Resolution paths (multiple endings based on player choice)

Total states: 5. Load-bearing transitions for v0.1: Unknown → Known (universal), Known/Friendly → PersonOfInterest (THE FRIEND), PersonOfInterest → Hostile (confrontation failure). Other transitions exist but are less structurally critical.