--- title: "Relationship States and Transitions" description: "Five RelationshipState values, THE FRIEND contradiction arcs, KnowledgeState integration, and dialogue access tier filtering" slug: relationship-states category: concept status: canonical created: 2026-02-12 updated: 2026-02-13 concept_type: mechanical tags: [] decision_refs: [D-041] cross_refs: [] --- # 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`: ```rust 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 them. 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, close colleagues, trusted contacts. **Why same color as Known**: Visual simplicity in early implementation. 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. "{THE FRIEND}'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**: 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 a cargo handler. Unknown (first sight) → Known (lattice query: "dock worker, logistics") → PersonOfInterest (observed in restricted corridor, evasive answers) → Hostile (confrontation: "I know you're involved. You need to cooperate." / handler: "Stay away from me."). --- ### THE FRIEND Contradiction Arc (Smuggler's Perspective) ``` Friendly → PersonOfInterest → [resolution: Friendly-but-contaminated OR Hostile] ``` **Phase 1: Friendly (baseline)** - {THE FRIEND} 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: "{THE FRIEND}'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 {THE FRIEND} meeting an unknown contact off-route. - `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. {THE FRIEND}, what are you doing?" - Dialogue options change: confrontation unlocks, trust-tier content locks ({THE FRIEND} is evasive). **Phase 4: Post-Confrontation** - **Path A (understanding)**: Smuggler confronts {THE FRIEND} gently. {THE FRIEND} confesses: trying to exit the ring to protect someone close to them. `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 {THE FRIEND} to ring leadership or applies harsh pressure. {THE FRIEND} turns defensive. `RelationshipState` → `Hostile`. Color → red. {THE FRIEND} avoids the smuggler, might actively obstruct. **THE FRIEND pattern**: Friendly → PersonOfInterest is the emotional core. The player trusted {THE FRIEND}. Now {THE FRIEND} is amber. That color shift IS the narrative moment. --- ### THE FRIEND Contradiction Arc (Detective's Perspective) ``` Friendly → PersonOfInterest → [resolution: Friendly-but-contaminated OR Known-distanced OR Hostile] ``` **Phase 1: Friendly (baseline)** - {THE FRIEND} 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` ({THE FRIEND} leaves when a suspect arrives). - Monologue: "That's the third time. {THE FRIEND} leaves when that person shows up." - State unchanged (still Friendly), but `EntityKnowledge.known_attributes["behavior_flags"]` updates. **Phase 3: The Contradiction (Friendly → PersonOfInterest)** - Trigger: Detective asks {THE FRIEND} directly about their avoidance. {THE FRIEND} 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: "They're not lying. But they're not telling me everything. {THE FRIEND}, what do you know?" - Dialogue options change: pressing questions unlock, casual warmth diminishes. **Phase 4: Post-Confrontation** - **Path A (loyalty test)**: Detective confronts {THE FRIEND} about concealment. {THE FRIEND} confesses: sitting on evidence to protect a third party. Detective can choose: report {THE FRIEND} (Hostile), use the information without reporting them (PersonOfInterest → Known, relationship damaged), or protect {THE FRIEND} and accept the information gap (PersonOfInterest → Friendly-but-contaminated). - **Path B (institutional)**: Detective reports {THE FRIEND} immediately. `RelationshipState` → `Hostile`. {THE FRIEND} is reprimanded or reassigned. Color → red. The detective loses their only local ally. **THE FRIEND pattern**: The detective's trust in {THE FRIEND} is tested. Amber means "my contact is hiding something." The resolution determines whether the friendship survives. --- ## Contradiction Patterns: Smuggler vs. Detective Paths Both THE FRIEND NPCs follow the same structural arc, but the **nature of the contradiction differs**: | Dimension | {THE FRIEND} — Smuggler Path | {THE FRIEND} — Detective Path | |-----------|------------------------------|-------------------------------| | **Contradiction type** | Spatial deviation (meeting unknown contact) | Behavioral avoidance (leaving when a suspect arrives) | | **Discovery method** | Direct observation in restricted area | Pattern recognition over multiple visits | | **What they're hiding** | Attempt to exit the ring (protect someone close) | Unreported evidence (protect a third party) | | **Sympathetic motivation** | Personal protection (someone they care about) | Friendship loyalty (mutual third-party connection) | | **Third-party connection** | {THE FRIEND}'s personal life | {THE FRIEND}'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 a **shared third party** as the emotional anchor — someone both THE FRIEND NPCs are trying to protect, approached from opposite sides of the case. --- ## 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 {THE FRIEND} 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 "{THE FRIEND} operates within ring protocol" contradicts with new observation "{THE FRIEND} meeting unauthorized contact." Both entries become `Contradicted`. Monologue fires. {THE FRIEND}'s `RelationshipState` → `PersonOfInterest`. --- ### 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 {THE FRIEND} at the hub 7 hours ago. `last_known_position` becomes Stale. Monologue: "{THE FRIEND} should be off-shift by now. Probably at the bar, but I haven't seen them." --- ## 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 the maintenance tech." **Shift**: Identification. Observer now has context. --- ### Known → Friendly - **Before**: "They're over there." - **After**: "Good to see them. Always fixes things without making a fuss." **Shift**: Warmth. Personal regard. --- ### Friendly → PersonOfInterest (THE FRIEND) - **Before**: "There's {THE FRIEND}. Good — I was starting to worry." - **After**: "{THE FRIEND}'s here. But they've been acting strange. What's going on?" **Shift**: Doubt contaminates warmth. The fond observation is now analytical. --- ### PersonOfInterest → Hostile - **Before**: "{THE FRIEND}'s avoiding me. Something's wrong." - **After**: "{THE FRIEND} just signaled security. They've 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: ```yaml prerequisite: relationship_state: PersonOfInterest subject: {npc_id} ``` - **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**: Unknown → Known (universal), Known/Friendly → PersonOfInterest (THE FRIEND), PersonOfInterest → Hostile (confrontation failure). Other transitions exist but are less structurally critical.