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 10: Guilds & Social

Overview

Guilds (persistent groups up to 200 members with ranks, bank, leveling, and buffs), friends list, party formation for group content, and timed raid lobbies. Chat is handled externally via Discord — this feature covers the in-game social structures only.

Dependencies

  • Feature 02 (Character Creation)
  • Feature 09 (Economy) — guild bank, gold costs

Technical Tasks

1. Database Migrations

  • Create migration 0009_create_social.sql:
    • guilds: id, name (unique), tag (unique, 2-4 chars), leader_id, level, xp, bank_gold, active_buff, buff_expires, max_members, discord_invite_url, created_at
    • guild_members: guild_id, character_id (PK), rank (leader/officer/member/recruit), joined_at
    • Index: guild_members(character_id)
    • friends: character_id, friend_id (PK), status (pending/accepted), created_at
    • parties: id, leader_id, type (duo/standard/raid), max_size, status (forming/ready/in_run/completed), quest_id, scheduled_at, created_at
    • party_members: party_id, character_id (PK), role (tank/healer/dps/support), ready (bool)

2. Guild Logic (crates/game)

  • Create src/guilds.rs:
    • GUILD_CREATION_COST: u64 = 10_000 (gold)
    • guild_max_members(guild_level: u16) -> u16: starts at 50, increases with level
    • guild_xp_for_level(level: u16) -> u64: XP required for next guild level
    • guild_buff_options() -> Vec<GuildBuff>:
      • +10% XP for 24 hours
      • +10% gold for 24 hours
      • -10% crafting time for 24 hours
      • Only one buff active at a time
    • guild_buff_cost(buff: &GuildBuff) -> u64: gold cost from guild bank

3. Guild Queries (crates/db)

  • Create src/queries/guilds.rs:
    • create_guild(pool, name, tag, leader_id) -> Guild
    • find_guild_by_id(pool, id) -> Option<Guild>
    • find_guild_by_name(pool, name) -> Option<Guild>
    • find_guild_members(pool, guild_id) -> Vec<GuildMember>
    • find_character_guild(pool, character_id) -> Option<(Guild, GuildMember)>
    • add_member(pool, guild_id, character_id, rank)
    • remove_member(pool, guild_id, character_id)
    • update_member_rank(pool, guild_id, character_id, new_rank)
    • update_guild_settings(pool, guild_id, discord_url?)
    • activate_guild_buff(pool, guild_id, buff, expires_at, cost)
    • add_guild_xp(pool, guild_id, xp)

4. Party Queries (crates/db)

  • Create src/queries/parties.rs:
    • create_party(pool, leader_id, type, quest_id?, scheduled_at?) -> Party
    • find_party_by_id(pool, id) -> Option<Party>
    • find_character_party(pool, character_id) -> Option<Party>
    • add_party_member(pool, party_id, character_id, role)
    • remove_party_member(pool, party_id, character_id)
    • set_member_ready(pool, party_id, character_id, ready)
    • check_all_ready(pool, party_id) -> bool
    • update_party_status(pool, party_id, status)

5. Guild Routes (crates/api)

  • Create src/routes/guilds.rs:
    • POST /api/guilds:
      • Body: { character_id, name, tag }
      • Validate: name/tag unique, character not in guild, has 10K gold
      • Deduct gold, create guild, add creator as leader
    • GET /api/guilds/:id:
      • Public info: name, tag, level, member count, leader name
    • GET /api/guilds/:id/members:
      • Member list with names, ranks, last active
    • POST /api/guilds/:id/join:
      • Body: { character_id }
      • Add as recruit (open join — no invite required for now)
      • Validate: not already in a guild, guild not full
    • POST /api/guilds/:id/leave:
      • Remove from guild. Leader cannot leave (must transfer leadership first)
    • POST /api/guilds/:id/invite:
      • Body: { character_name } — officer+ only
    • PUT /api/guilds/:id/settings:
      • Body: { discord_invite_url? } — leader/officer only
    • POST /api/guilds/:id/promote:
      • Body: { character_id, new_rank } — leader only
    • POST /api/guilds/:id/kick:
      • Body: { character_id } — officer+ only, cannot kick higher rank
    • POST /api/guilds/:id/buff:
      • Body: { buff_id } — officer+ only, deducts from guild bank
    • POST /api/guilds/:id/bank/deposit:
      • Body: { character_id, amount } — deposit gold to guild bank
    • POST /api/guilds/:id/transfer-leadership:
      • Body: { new_leader_id } — leader only

6. Friends Routes (crates/api)

  • Create src/routes/social.rs:
    • GET /api/characters/:id/friends:
      • Return friends list with status (pending/accepted), names, levels
    • POST /api/friends/add:
      • Body: { character_id, friend_name }
      • Create pending friend request
    • POST /api/friends/accept/:friend_character_id:
      • Accept pending request (creates reciprocal entry)
    • DELETE /api/friends/:friend_character_id:
      • Remove friend (both directions)

7. Party Routes (crates/api)

  • Create src/routes/parties.rs:
    • POST /api/parties:
      • Body: { leader_id, type, quest_id?, scheduled_at? }
      • Create party, add leader
    • GET /api/parties/:id:
      • Party info: members, roles, ready status, quest, schedule
    • POST /api/parties/:id/join:
      • Body: { character_id, role }
      • Validate: party not full, correct type limits (duo=2, standard=4, raid=8)
    • POST /api/parties/:id/leave:
      • Remove from party. If leader leaves, disband.
    • POST /api/parties/:id/ready:
      • Body: { character_id } — toggle ready status
    • POST /api/parties/:id/start:
      • Leader only, all members must be ready
      • Start group run (uses Feature 07 run system with party_id)

8. Client — Guild & Social UI

  • Create routes/(game)/guild/+page.svelte:
    • Guild overview: name, tag, level, XP bar, member count
    • Member list: name, rank, last active, promote/kick actions
    • Guild bank: current gold, deposit button
    • Active buff display with “Activate Buff” selector
    • Discord link button
    • Settings (for officers+): Discord URL
  • Create routes/(game)/social/+page.svelte:
    • Friends tab: friends list, add friend input, pending requests
    • Parties tab: current party, create party, join party
  • Create party lobby view for group content coordination

Tests

Unit Tests

  • guild_max_members: 50 at level 1, scales correctly
  • guild_buff_cost: returns correct costs per buff type
  • Guild rank hierarchy: leader > officer > member > recruit

Integration Tests

  • POST /api/guilds creates guild, deducts 10K gold
  • POST /api/guilds rejects when already in a guild
  • POST /api/guilds rejects duplicate name/tag
  • POST /api/guilds/:id/join adds as recruit
  • POST /api/guilds/:id/join rejects when guild full
  • POST /api/guilds/:id/leave removes member
  • POST /api/guilds/:id/leave by leader → 409
  • POST /api/guilds/:id/promote changes rank
  • POST /api/guilds/:id/kick removes member (officer+)
  • POST /api/guilds/:id/kick rejects kicking higher rank
  • POST /api/guilds/:id/buff activates buff, deducts from bank
  • POST /api/guilds/:id/buff rejects when buff already active
  • POST /api/guilds/:id/bank/deposit adds gold to guild bank
  • POST /api/guilds/:id/transfer-leadership changes leader
  • POST /api/friends/add creates pending request
  • POST /api/friends/accept creates mutual friendship
  • DELETE /api/friends/:id removes both directions
  • POST /api/parties creates party with leader
  • POST /api/parties/:id/join adds member up to max
  • POST /api/parties/:id/start starts group run when all ready
  • POST /api/parties/:id/start rejects when not all ready