Achievements & Titles
Status: Design Date: 2026-04-04
Track player milestones and award titles. Titles display after the player’s name in room descriptions, who list, and inspect. Achievements use the existing player-flags system — no new state types needed.
How It Works
Achievements are defined as a static list in the agent. Each achievement has a flag name, display title, and a condition. When an event fires (kill, death, level up, quest complete, room enter, boss kill), the system checks all achievements against the player’s current state. If the condition is met and the player doesn’t already have the flag, the flag is set and the player is notified.
No new types in sur/mud.hoon. Achievements are hardcoded in the agent as a list of conditions checked against existing player data.
Achievement Definitions
Combat
| Flag | Title | Condition |
|---|---|---|
ach-first-blood | Blooded | Kill 1 mob |
ach-slayer-10 | Slayer | Kill 10 mobs |
ach-slayer-100 | Centurion | Kill 100 mobs |
ach-slayer-500 | Butcher | Kill 500 mobs |
ach-first-death | Fallen | Die once |
ach-died-10 | Death’s Familiar | Die 10 times |
ach-pvp-first | Duelist | Kill 1 player in PvP |
ach-pvp-10 | Gladiator | Kill 10 players in PvP |
Progression
| Flag | Title | Condition |
|---|---|---|
ach-level-5 | Apprentice | Reach level 5 |
ach-level-10 | Journeyman | Reach level 10 |
ach-level-20 | Veteran | Reach level 20 |
ach-level-30 | Master | Reach level 30 |
Exploration
| Flag | Title | Condition |
|---|---|---|
ach-explorer-25 | Wanderer | Explore 25 rooms |
ach-explorer-100 | Explorer | Explore 100 rooms |
ach-explorer-200 | Cartographer | Explore 200 rooms |
Bosses
| Flag | Title | Condition |
|---|---|---|
ach-boss-revenant | Ash Walker | Kill the Ashwick Revenant |
ach-boss-voss | Oathbreaker | Kill Commander Voss |
ach-boss-mordecai | Heretic | Kill Archpriest Mordecai |
ach-boss-osseus | Bone Breaker | Kill Osseus the Bone Lord |
ach-boss-harbinger | Covenant Breaker | Kill the Harbinger (final boss) |
Quests
| Flag | Title | Condition |
|---|---|---|
ach-quest-main | Savior | Complete the main quest line |
ach-quest-all | Completionist | Complete all quest lines |
Misc
| Flag | Title | Condition |
|---|---|---|
ach-pet-owner | Companion | Buy a pet |
ach-gold-1000 | Prosperous | Accumulate 1,000 gold |
ach-gold-10000 | Wealthy | Accumulate 10,000 gold |
ach-night-kill | Nightstalker | Kill a mob during the Night phase |
Title Display
Each player has an active title (the most recently earned achievement, or manually chosen). Titles appear after the player name:
Grendel the Veteran
In room descriptions:
Grendel the Veteran is here.
In who list:
Grendel the Veteran — Level 20 Warrior
In inspect/look player:
Grendel the Veteran — Level 20 Human Warrior PvP Kills: 7 Achievements: 12/25
Choosing a Title
title <name> — set your displayed title to any earned achievement title.
title — show your current title and list all earned titles.
The active title is stored as a player flag: title:{flag-name}. Only one title flag at a time.
Check Points
Achievements are checked at these events:
| Event | Achievements Checked |
|---|---|
| Mob kill | kill count, boss flags, night-kill |
| Player death | death count |
| PvP kill | pvp-kill count |
| Level up | level thresholds |
| Room enter | explored room count |
| Quest complete | quest flags |
| Pet buy | pet-owner |
| Gold change | gold thresholds |
Each check is a simple comparison against the character’s stats or flag set. No database queries — everything is on the session.
Notification
When an achievement is earned:
Achievement Unlocked: Centurion — Kill 100 mobs. Your title has been set to “Centurion”.
The title auto-sets to the newest achievement. The player can change it with title.
Implementation
Agent Code
A single arm ++ check-achievements that takes a character, player-flags set, and event type. Returns an updated flags set and a list of notification messages.
++ check-achievements
|= [c=character pflags=(set @tas) event=@tas]
^- [(set @tas) (list @t)]
Called inline after kills, deaths, level-ups, quest completions, room enters.
No Type Changes
- Achievement flags stored in
player-flags(already(map session-id (set @tas))) - Active title stored as
title:{flag}in player-flags - No changes to
character,player-session, orstate-0
Import
Achievement definitions are hardcoded, not in area JSON. Boss kill achievements reference specific mob template IDs — the designer knows which mobs are bosses.
Frontend
- Achievement notification as a system message (already handled)
- Title shown in room occupants and who list (backend appends to name)
titlecommand response shows earned achievements list
Not Included
- Achievement points. No numeric score. Titles are the reward.
- Achievement UI panel. No dedicated frontend component. Use
titlecommand to see earned list. - Per-world achievements. Achievements are world-specific (tied to player-flags which are per-session). Citizens keep them via flag persistence.
- Hidden achievements. All achievements are visible in the list. Could add a
hiddenflag later.