Files
settled-reach/wiki/concepts/relationship-states.md
T
jpmschweitzerandClaude Opus 4.7 25eb8bd096 content(wiki): purge v0.1 Sova/Van Maanen residue (#865)
Spring-cleaning accumulated v0.1 vertical-slice residue across the
wiki. Scope per Jeroen's pre-decisions on 2026-04-21:

- Delete outright: wiki/star-systems/GJ-35/sova/ subtree (5 files +
  2 dirs) — v0.1 Station Sova / Transit District content.
- Strip example blocks in authoring guides and _templates/ that
  cited dropped v0.1 NPCs (Kael Davan, Sera Venn, Nils Davan, Devra,
  Torek, Renn, Pell, Tav, Lera Sessik, Sabel). Replaced with short
  "v0.1 examples removed — D-122" notes pointing authors to the
  active NPC roster.
- Rewrite canonical-lore references file-by-file: faction pages,
  technology pages, contraband pages, concepts pages, corp pages
  that cited v0.1 names/places. Preserve institutional/structural
  content, drop specific-name citations.
- Commission name drift: replace "Concord Commission" and "Assembly
  Commission" with "the Lattice Commission" (D-193) throughout.
- Van Maanen's Star cultural references: the canonical in-game name
  is Vuurkloof. "Van Maanen's Star" is retained only as an
  astronomical designation (glossary + GJ-35 Calibration Note).
  All cultural/system references converted to Vuurkloof across
  culture-authoring-guide, cultural-generation-guide, founder-gates,
  and star-system adjacent-system descriptions.
- Strip `v0.1` from faction/triangle frontmatter tags (8 files).
- wiki/triangles/hub-power.md and wiki/factions/the-ring.md:
  rewritten using role-name exemplars (Ring Coordinator / Shift
  Supervisor / THE FRIEND) instead of named v0.1 NPCs. Triangle
  pattern preserved as a structural reference.

Also applies drive-by Commission drift fixes and minor cross-ref
updates to canonical corps (gate-corporation, mastroianni-vehicle-group,
stalownia-kowalski, prometheus-labs, ferreira-monteiro, vins-de-grand-vide,
and 13 others).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 10:26:45 +02:00

347 lines
15 KiB
Markdown

---
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.