Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Feature 12: Factions & Reputation

Overview

Seven factions with a reputation system ranging from Hostile (-3000) to Exalted (21000+). Three conflict pairs where gaining reputation with one faction loses 50% with its opposite. Faction vendors sell exclusive recipes, consumables, and enchantments at reputation tiers. Daily faction quests provide the primary rep grind.

Dependencies

  • Feature 07 (Quests & Runs) — faction quests use the run system
  • Feature 03 (Items & Inventory) — faction vendor items

Technical Tasks

1. Static Game Data — Factions

  • Create data/factions/:
    • factions.toml: all 7 factions with:
      • id, name, description, zone, conflict_pair (opposing faction ID or null)
      • Factions: Iron Compact, Shadow Court, Arcane Conclave, Primal Circle, Order of the Dawn, Covenant of Dusk, Merchant Consortium
      • Conflict pairs: Iron Compact ↔ Shadow Court, Arcane Conclave ↔ Primal Circle, Order of the Dawn ↔ Covenant of Dusk. Merchant Consortium has no conflict.
    • reputation_tiers.toml: tier thresholds
      • Hostile: < -1000
      • Unfriendly: -1000 to -1
      • Neutral: 0 to 2999
      • Friendly: 3000 to 5999
      • Honored: 6000 to 11999
      • Revered: 12000 to 20999
      • Exalted: 21000+
    • faction_vendors/ — per faction TOML with items available at each rep tier
    • faction_quests/ — 3 daily quests per faction (templates, generated dynamically)
    • exalted_passives.toml: one unique passive ability per faction at Exalted

2. Reputation Logic (crates/game)

  • Create src/factions.rs:
    • gain_reputation(character_rep: &mut HashMap<String, i32>, faction_id: &str, amount: i32):
      • Add amount to faction
      • If faction has a conflict pair, subtract 50% from opposing faction
      • Clamp: minimum -3000, no maximum
    • get_reputation_tier(rep: i32) -> ReputationTier
    • can_access_vendor_tier(rep: i32, required_tier: ReputationTier) -> bool
    • get_exalted_passive(faction_id: &str) -> Option<PassiveEffect>: only if Exalted

3. Database — Already Exists

  • character_reputation table was defined in the base schema (Feature 02 migration area)
  • If not yet created, add migration 0011_create_reputation.sql:
    • character_reputation: character_id, faction_id, reputation (default 0), PK: character_id + faction_id

4. Reputation Queries (crates/db)

  • Create src/queries/reputation.rs:
    • get_all_reputation(pool, character_id) -> Vec<(String, i32)>
    • get_faction_reputation(pool, character_id, faction_id) -> i32
    • update_reputation(pool, character_id, faction_id, new_value)
    • batch_update_reputation(pool, character_id, changes: Vec<(String, i32)>) — for conflict pair updates

5. Faction Quest Generation (crates/game)

  • Create src/faction_quests.rs:
    • generate_daily_faction_quests(character: &Character, faction_id: &str, date: NaiveDate) -> Vec<FactionQuest>:
      • 3 quests per faction per day
      • Seeded by character_id + faction_id + date (deterministic per day)
      • Quest types: bounties themed to the faction’s identity
      • Requires Friendly rep to access faction quests
    • Each quest grants: reputation (150-250 per quest), gold, XP, chance at faction-specific materials

6. Faction Routes (crates/api)

  • Create src/routes/factions.rs:
    • GET /api/characters/:id/reputation:
      • Return all 7 faction standings with tier names
    • GET /api/factions/:faction_id/vendor?character_id=:
      • Return items available to buy based on character’s rep tier
      • Each item: name, cost (gold or faction tokens), rep requirement
    • POST /api/factions/:faction_id/vendor/buy:
      • Body: { character_id, item_template_id }
      • Validate rep tier, deduct cost, create item
    • GET /api/factions/:faction_id/quests?character_id=:
      • Return today’s 3 faction quests (if Friendly+)
      • Include completion status
    • POST /api/factions/:faction_id/quests/:quest_id/start:
      • Start faction quest as a run (uses Feature 07 run system)
      • On completion, grant rep (plus conflict pair penalty)

7. Update Run Completion for Reputation

  • In the simulation worker (Feature 07), after resolving a faction quest run:
    • Call gain_reputation with appropriate amounts
    • Handle conflict pair rep loss
    • Check for tier-up events (Friendly → Honored, etc.)
    • Create notification on tier change

8. Client — Factions UI

  • Create routes/(game)/factions/+page.svelte:
    • Faction list: 7 factions with current rep bar, tier badge, conflict pair indicator
    • Faction detail panel: description, current tier perks, progress to next tier
    • Vendor tab: items purchasable at current tier
    • Daily quests tab: 3 quests per day (if Friendly+)
    • Exalted passive display (if earned)

Tests

Unit Tests

  • gain_reputation: adds correct amount to faction
  • gain_reputation: subtracts 50% from conflict pair
  • gain_reputation: Merchant Consortium has no conflict penalty
  • gain_reputation: clamps at -3000 minimum
  • get_reputation_tier: correct tier at boundaries (2999 = Neutral, 3000 = Friendly)
  • generate_daily_faction_quests: returns 3 quests
  • generate_daily_faction_quests: same character + date → same quests (deterministic)
  • generate_daily_faction_quests: different date → different quests

Integration Tests

  • GET /api/characters/:id/reputation returns all 7 factions with rep values
  • GET /api/factions/:id/vendor returns items appropriate to character’s rep tier
  • POST /api/factions/:id/vendor/buy at sufficient rep → creates item, deducts cost
  • POST /api/factions/:id/vendor/buy at insufficient rep → 403
  • GET /api/factions/:id/quests returns daily quests when Friendly+
  • GET /api/factions/:id/quests returns empty when below Friendly
  • Completing a faction quest grants reputation and applies conflict penalty
  • Reputation tier change creates a notification