Oil painting of two heralds meeting on a stone bridge at dawn, each under his guild's banner, exchanging a wax-sealed charter

The Banner and the Charter

A deep dive into Shroud of the Avatar's guilds and guild wars, what Ultima Online and twenty-eight years of games since can teach them, and twenty-five concrete proposals.

A guild in SotA today is a 25,000 gold charter, a name, a roster, a chat channel, and a handshake war. That was also a guild in Ultima Online in 1997 — and UO invented all of it. What the genre built in the twenty-eight years since is the other half: the guild as an institution (a bank, a log you can read, ranks that mean something, a way for strangers to find you) and the war as a contract (terms both sides chose, a history that survives, stakes that are worth a banner but never someone's house). This document measures our guilds against that canon and proposes twenty-five improvements, from one-line client fixes to a seasonal ladder, every one grounded in the actual classes that would carry it.

0 · Executive summary 1 · Where we are today 2 · Lessons: Ultima Online to modern 3 · The twenty-five proposals    Tier 1 · Quick wins (S1–S7)    Tier 2 · Core upgrades (S8–S15)    Tier 3 · Server-backed flagships (S16–S25)    Considered and rejected 4 · Two windows and a web page 5 · Sequencing 6 · Appendix
Section 0

Executive summary

Ultima Online shipped the guildstone in 1997: a charter fee, a four-letter tag, ranks, and the mutual-consent guild war — a private PvP contract between two guilds that overrides the world's rules. It is still running, unchanged, twenty-eight years later, because it costs nothing, works between two five-person guilds, and cannot be used to grief anyone. The genre then spent two decades building the institutional half UO never had: WoW's guild bank with per-rank daily caps and a transaction log (2007), its calendar with signups (2008), guild finders with applications (ESO's is best-in-class), alliances, crests, contribution tracking, and — the newest layer — the guild's own web presence, which FFXIV made first-party with Lodestone Free Company pages in 2013. The genre also ran the expensive experiments for us: WoW added guild leveling in 2010 and removed it in 2014 as "a penalty and barrier to entry for new guilds"; New World bet on faction locks, 50v50 rosters and territory taxes and announced closure in 2025; Albion's own retrospective on instanced 5v5 territory fights concluded the "exclusivity was not good for the game."

SotA has the 1997 half and almost none of what followed. And our one war mechanic has a flaw UO never had: being at war flags you attackable by every open-PvP player in the world, not just your enemy — the single biggest reason guilds refuse wars. Measured against the canon, our gaps cluster in three places, with a fourth thread running through all of them:

  1. The guild as an institution — no bank, no log viewer (the audit trail exists but renders to a text file on disk), no join dates or last-online on the roster, no crest, no way to disband, no way for a new player to find a guild that wants them.
  2. The war as a contract — no terms beyond a duration slider, no scheduled starts (the server plumbing is fully built and the client never asks), no draws, no history (every war record deletes itself after 14 days), and the everyone-can-attack-you flag.
  3. Conflict for a small population — nothing between "duel" and nothing: no objectives, no seasons, no mercenaries, no alliances, and no way for a guild that never PvPs to compete at anything.
  4. The web thread — the genre's best guild systems cast a public web shadow (Lodestone, the WoW armory, Albion's killboard). Our guild web companion is already designed; these proposals feed it the data it needs and link the game to it.

Twenty-five proposals follow. Seven are quick wins — client work or a one-line enum fix, several of them simply surfacing data the servers already hold. Eight are core upgrades. Ten are server-backed flagships, each flagged with its database cost. The war designs are small-population-first throughout: mutual consent, defender-chosen windows, anti-farm cooldowns, cosmetic-only prizes, and a public ladder that counts PvE hunts so every guild appears on it.

#ProposalTierSizeServerOne-line pitch
S1Guild identity header1Snonedescription, MOTD, member count and leader on the guild tab
S2Activity log viewer1Snonethe 30-day guild log gets a window instead of a text file
S3Scheduled war starts1Snonedeclare now, fight Saturday; the server already supports it
S4MOTD permission + editor1Senum bitMOTD stops sharing a permission bit with the description
S5Honest war endings1Snonedraws shown as draws, a real end-of-war summary
S6Invite confirmation1Snonea confirm step before a guild invite goes out
S7Last-online column1Snonesee who has been gone a month; the data already arrives
S8Disband and heir2Mop + fieldretire a guild deliberately, name a successor
S9Kill-score integrity2Mop logickilling the same victim stops paying after five minutes
S10War-scoped attackability2Mnew opat war you are attackable by your enemy, not the world
S11Declare by name2Mop + TTLproposals wait three days for the enemy leader, not two minutes
S12Victory plaques2Marchetypea placeable plaque for every won war, a memento for both sides
S13Guild crest2Mfieldone blazon for the whole guild, on the tab, the scoreboard, the lot sign
S14Roster truth2Mfieldsjoin dates, persistent last-online, founded date, officer notes
S15Officer chat + channel auth2Mop logican officers-only channel, and guild channels that verify membership
S16Persistent war history3Lcollectionwars stop evaporating after fourteen days
S17Guild finder3Lcollectionbrowse guilds, apply with a message, review at leisure
S18Alliances3XLcollectiontwo small guilds can be allies on the record
S19Negotiated war terms3Lfieldsfirst to fifty kills, timed, or until surrender; counter-offers allowed
S20Mercenary enlistment3XLcollectionhired swords fight your war without joining your guild
S21Contested objectives3XLcollectiona war banner to hold, occupation scoring, defender-chosen windows
S22Seasons and the ladder3Lreads S16a quarterly ladder that hard-resets; rewards stay cosmetic
S23Guild hunts + first-clear ledger3Lcollectionweekly guild PvE and a permanent record of who did it first
S24Guild vault3XLcollectionshared storage with per-rank daily caps and a full log
S25Guild page bridge3Mfeedsthe guild's web page and the game meet in the middle
Section 1

Where we are today

Credit first, because a fair amount exists and none of it is re-proposed here. A guild is created through an NPC conversation with a 25,000 gold charter. It has a name, a 300-character description with its own editor window, a 200-character message of the day (chat command only), guild chat, a roster on the Social window's Guild tab with promote/demote/kick, invitation dialogs, an audit log that records every membership change for 30 days, and the Guild Chapter House lot flag that grants guildmates access to a designated property, with officer and leader tiers mapped to real property permissions and vendor authorization revoked automatically on kick. Wars exist: mutual consent, one to ten days, a kill-count scoreboard, and a trophy delivered to the winning leader's bank. The guild ranks epic (custom rank names and per-rank property permissions) is separately planned and already in progress, and a full guild and town web companion — one web page per guild, with login by game account — has a phased plan of its own. This page builds on all of it.

The Social window's Guild tab — the whole management surface
Social
FriendsIgnoredGuild
Knights of the Radiant Court
Filter
NameRoleStatusLocation
Aldric VaneLeaderOnlineCentral Brittany
Mira ThornOfficerOnlineOwls Head
Corwin SlateInvited
Wen AshbyOffline
Tam FletcherOffline
Invite playerInvite
PromoteDemoteKick
The Guild Wars window — the whole war surface
Guild Wars
YoursScoreOpponentScoreTime
KRC12Crimson Sails191d 04h
KRC41Iron Pact18ended
Declare WarScoreboardForfeit
Warning
While at war you can be attacked by any player flagged for open PvP.

The machinery every proposal plugs into

Guild state lives on its own server. The client's SocialListManager and GuildWarfareManager send Photon operations to the GroupServer (GroupClientPeer), which forwards guild mutations to the SocialServer, where each guild and each war runs on its own single-threaded fiber (Guild, GuildWar) over MongoDB. War kills take a separate, deliberately decoupled path: the GameServer writes each qualifying kill straight to the database, and the SocialServer polls them into scores every ten seconds — so a lost server link can never drop a war kill. Every proposal below extends one of these nodes; none forks the pipeline.

flowchart LR
  C["Client\nSocialListManager / GuildWarfareManager"] -->|Photon ops| GP["GroupServer\nGroupClientPeer"]
  GP --> SS["SocialServer\nGuild + GuildWar fibers"]
  SS --> DB[("MongoDB\nGuildStorage / GuildMember\nGuildWar / GuildWarKill\nGuildInteractionLog")]
  GS["GameServer\nkill attribution"] -->|writes GuildWarKill| DB
  DB -->|10s poll| SS
  GS2["GameServer sweep\nwar trophies"] --> DB
  W["Guild web companion\n(planned, separate program)"] -.->|read-only API| DB
The two hard constraints. First: every war record carries a 14-day time-to-live from creation — the database deletes it, kills and all, which is why there is no war history and why several proposals depend on S16's permanent record. Second: PvP legality is evaluated on the client under the game's trust model, which rules out any mechanic requiring the server to independently re-judge combat (that constraint shaped the rejected list, and it is why war-scoped attackability in S10 is a rules change, not an anti-cheat change).
Section 2

Lessons: Ultima Online to modern

UO's guildstone was a physical object in a house: all guild administration happened at the stone, wars were negotiated on a diplomacy page with counter-proposals, and the four-letter abbreviation after a name turned every nameplate into guild advertising. Its five fixed ranks included one nobody has properly copied since: the Ronin, a member who may fight the guild's wars but cannot vote and cannot open guild containers — the genre's first formal mercenary slot. UO then ran the full experiment ladder for us: the light systems (mutual war, elections) are still running after decades, while the heavy one — Factions, with its eight capturable cities, ten-hour sigil timers and harsh stat loss — collapsed as the population thinned and was replaced in 2014 by Vice vs Virtue, a system built explicitly for a small population: battles that ignite when just two enemies are online, four ways to score so a duo can matter, a five-minute anti-farm cooldown on kills, and rewards that are deliberately cosmetic. That arc, heavy dies and light survives, is the argument template for everything in Section 3.

Oil painting of a candlelit war council table: a campaign map with carved guild markers, an hourglass, and a treaty bearing two wax seals
The war as a contract: a map, an hourglass, and terms both sides sealed. UO shipped this idea in 1997; it is still the best-shaped guild war in the genre.
1997
UO guildstone
Charter fee, 4-char tag, ranks, mutual-consent war with negotiated terms. Still running.
1999
UO Factions
Territory, sigils, stat loss. The heavy system; it collapsed as Felucca thinned.
2003
Shadowbane
City sieges that transfer ownership instead of deleting it; 24h immunity after a defense.
2007
WoW guild bank
Per-rank per-tab permissions, daily withdrawal caps, transaction log. The storage standard since.
2010–14
WoW guild leveling
Added, then removed: perks became "a penalty and barrier to entry for new guilds."
2013
FFXIV Lodestone
Every Free Company gets a first-party web page: crest, roster, estate, recruitment.
2014
UO Vice vs Virtue
The small-population retrofit: population-triggered battles, multi-verb scoring, cosmetic prizes.
2015
GW2 halls · EVE Aegis
The guild as a place that grows; defense windows chosen by the defender, scaled by activity.
2018
EVE wardec reform
Consent expressed by property: own a structure and you are war-eligible; own nothing, untouchable.
2020
Albion "Queen"
Instanced 5v5 territory replaced by open sieges at defender prime time; outnumbering weakens you.
2025
New World closes
The receipts on 50v50 rosters, tax snowballs and faction locks at low population.

What each game contributes

Ultima Online: the mutual-consent war with negotiated terms (kill count, hour duration, or eternal-until-surrender, with counter-proposals), the Ronin mercenary rank, alliances with one hard rule (no active wars when joining), and Vice vs Virtue's whole small-population toolkit. WoW: the guild bank permission matrix with per-rank daily caps — theft becomes a bounded risk — plus the calendar with signup approval, the guild finder, and the genre's most important negative result: guild power perks calcify the guild landscape and were removed. FFXIV: Lodestone proves the first-party guild web page; Free Company credits prove passive shared income keeps casual members attached; its lack of an in-game guild search is the anti-pattern our finder avoids. ESO: the best guild finder shipped (listings with activities, core hours, applications with messages) and five-guilds-per-account, which turns guilds into services. GW2: guild missions — bounties and treks a five-person guild completes — and WvW's guild-claimed objectives flying guild banners. Albion: the 12-week season with a hard reset as the anti-dominance mechanism, guild logs, and Disarray, the debuff that punishes outnumbering the enemy. EVE: war eligibility through owned structures — consent expressed by property — the defender-only ally call, and the audit log. New World: the complete cautionary tale — mandatory 50-player rosters, faction locks, and weaponized territory taxes, closing after four years.

Capability matrix

CapabilityUOWoWFFXIVESOGW2AlbionEVENew WorldSotA todaySotA proposed
Ranks, custom titles, granular permissions● ranks epic
Guild bank with per-rank caps + log● S24
In-game activity log viewer◔ file dump● S2
MOTD and bulletin◔ command● S1/S4
Recruitment listing + applications● S17
Guild crest / nameplate tag◔ name only● S13
Alliances between guilds● S18
Mutual-consent war, negotiated terms◔ duration only● S19
War scoped to the enemy, not the world● S10
War scoreboard + persistent history◔ 14 days● S16
Territory / objective conflict◔ S21 light
Anti-snowball levers● S9/S20/S21
Seasons and ladder resets● S22
Guild PvE missions / non-PvP ladder● S23
Mercenary / war-only membership● S20
Calendar and event signup◔ web companion
First-party guild web presence● companion + S25

● native · ◔ partial or third-party · ○ absent. "SotA today" = the unity-6.5 migration branch, 2026-08. "SotA proposed" cells name the proposal or the separately planned program that closes the gap.

Section 3

The twenty-five proposals

The design stance, stated once so every card can lean on it: every conflict mechanic below is mutual-consent, works at two guilds of four players, and rejects the genre's population-hungry patterns — no faction locks, no fixed-roster instanced battles, no 24/7 vulnerability, no guild power perks, no stakes in anyone's property. The receipts for each rejection are in the considered-and-rejected list.

Tier 1 · Quick wins — client work or a one-line fix, data the servers already hold

S1 · Guild identity header

Tier 1Size SServer: none

The Guild tab finally says what your guild is. A header strip above the roster shows the description, the message of the day, the member count with how many are online, and the leader's name — today the tab shows the guild name over a flat list and nothing else. Every piece of this data already reaches the client; the tab just never asks for it.

Seen in: every genre guild pane since EverQuest; WoW's guild window; ESO's guild home tab.

Implementation notes

Header build in SocialWindow.BuildGuildTab / SocialWindowModel. Description via the existing GetGuildDescription op; MOTD is already client-held in SocialListManager with its 30-minute display expiry; member and online counts fall out of the roster the tab already renders. Founded date is deliberately excluded here — the guild record has no creation timestamp until S14 adds one.

client Sserver noneperf neutraltests SocialWindowModelTests

S2 · The activity log gets a window

Tier 1Size SServer: none

The guild audit trail — who invited whom, who was kicked, who was promoted, who changed the message of the day — becomes a scrollable, filterable panel. Today it exists, works, and is delivered to officers as a chat command that writes a text file into your game data directory.

Seen in: WoW's bank and event logs; Albion's guild log; EVE's audit trail.

Guild Log
AllMembershipOfficersWar
04 AugMira Thorn invited Corwin Slate
03 AugAldric Vane set the message of the day
01 AugTam Fletcher was promoted to Officer
22 JulWen Ashby joined the guild
Entries are kept for 30 daysLoad More
Implementation notes

The paged download already exists end to end: GetGuildInteractionLog / GetMoreGuildInteractionLog ops, 20 entries per packet, against the 30-day-TTL GuildInteractionLog collection. Replace the file dump in ChatUI.WriteGuildActivityLog with a UITK list window (pattern: the guild war list window and its model). The 30-day ceiling is a database TTL; the UI states it honestly. The same viewer is reused later for S24's vault log.

client Sserver noneperf paged, 20/packettests new log window model tests

S3 · Scheduled war starts

Tier 1Size SServer: none

Declare war today, fight Saturday. The declare window gains a "war begins in" choice — immediately, in 24 hours, in 3 days — so both guilds can rally their members, announce the fight, and actually show up for it. The remarkable part: the server fully supports delayed starts already, refuses kills before the start time, and has since the system shipped. The client hard-codes zero.

Seen in: Lineage 2's siege preparation periods; EVE's 24-hour war warm-up; Ashes of Creation's declaration periods.

Implementation notes

The wire already carries a start interval on the war invitation; the client passes TimeSpan.Zero unconditionally in GuildWarSendInvitationUIWindow. Add start options beside the existing duration options in GuildWarInviteFlowModel. One guard: the war record's 14-day time-to-live runs from creation, so the UI caps delay plus duration at 13 days until S16 lifts the ceiling. Extend GuildWarScoreboardAndInviteTests.

client Sserver none, already builtperf neutraltests GuildWarScoreboardAndInviteTests

S4 · The MOTD gets its own permission bit, and an editor

Tier 1Size SServer: enum bit

Leaders can finally delegate "post the daily message" without also handing over the guild description — today the two permissions are literally the same bit in the permissions enum, a known collision. And the message of the day gets a text field beside the description editor instead of living only in a chat command.

Seen in: WoW and ESO, which separate MOTD rights from guild-info rights.

Implementation notes

GuildUserPermissions.SetMessageOfTheDay currently equals SetDescription (both 16). Move MOTD to a free bit, update the role-to-permissions mapping, and split the server-side gates in the guild fiber's set-MOTD versus set-description handlers. The enum lives in the shared client/server mirror, so both copies change together; the existing enum-parity ratchet test catches drift. UI: add the MOTD field to the existing description editor window — the set/get ops and the cross-shard MOTD broadcast already exist. This also frees clean permission-bit space that S24 later uses.

client Sserver enum + gate splitperf neutraltests enum parity ratchet

S5 · Honest war endings

Tier 1Size SServer: none

A tied war currently ends in silence: no record is written, no notification fires, and the war list tints the row as a defeat because it treats any unknown outcome as a loss. Every war should end with a proper closing screen — winner, draw, or forfeit, with the final score — and a draw should look like a draw.

Seen in: UO's war win and loss records; every ranked mode ever shipped.

Implementation notes

The server's victory recorder no-ops on a tie at expiry; the list model's row tint treats unknown as defeat (a documented NGUI-parity holdover); the scoreboard model already computes a Draw status nothing displays. Fix the tint, and drive a summary popup from the existing war-ended client event. Persisting draw records is deferred to S16 — the current victory record can only express a single winner.

client Sserver noneperf neutraltests GuildWarListConversionTests

S6 · Invite confirmation

Tier 1Size SServer: none

A one-line confirmation before a guild invite goes out, so "Invite To Join Guild" stops being one misclick away from "Invite to Party" in the player context menu. A direct ask from the community wishlist.

Seen in: standard confirmation UX everywhere; wishlist items from the 2026 forum sweep.

Implementation notes

Context-menu entry in PlayerController; send path SocialListManager.InviteToGuild; the shared invitation-dialog base class already used by the guild invite prompt supplies the dialog.

client Sserver noneperf neutraltests none needed

S7 · The last-online column

Tier 1Size SServer: none

Officers can see at a glance who has been gone a month. The last-online timestamp already ships to the client for every roster member; the roster just never grew the column. This is the minimum viable tool for the "how do I tend a guild full of ghosts" problem the wishlist keeps raising.

Seen in: WoW, ESO and Albion rosters, all of which lead with last-online.

Implementation notes

The value arrives per member in the social-list payload and sits unused in SocialListUserInfo; add a sortable column in the guild roster build. One honesty note: today the value is server-memory only — it resets on a server restart and when the last guildmate logs off — so the column shows "unknown" gracefully until S14 persists it.

client Sserver noneperf neutraltests SocialWindowModelTests

Tier 2 · Core upgrades — the management spine and the war worth fighting

S8 · Disband, and a designated heir

Tier 2Size MServer: op + field

A leader can retire a guild deliberately instead of everyone leaving one by one, and can name an heir so leadership does not automatically fall to whoever joined longest ago. Succession exists today, but its only rule is seniority; disbanding does not exist at all — a guild dies only when its last member walks out.

Seen in: UO's succession failsafes; WoW's inactive-leader transfer.

Implementation notes

New disband and set-heir ops through the standard five-file guild op pattern (client manager, group-server interface and peer, social-server interface, guild fiber). Heir is one additive field on the guild record with a targeted update helper. Disband is destructive: it needs the confirmation dialog, must run the existing vendor-authorization revocation for every member on any guild lot, and appends new audit-log entry types so S2's viewer shows it.

client Sserver Mdb 1 additive field, ledger rowtests guild fiber succession tests

S9 · Kill-score integrity

Tier 2Size MServer: op logic

War score stops being farmable: killing the same person again within five minutes scores nothing, so a war cannot be won by feeding an alt to the scoreboard. Today score is plus one per kill with no dedupe of any kind. This is the quiet card everything competitive stands on — the ladder, the terms, the objectives are only worth building if the number under them is honest.

Seen in: UO Vice vs Virtue's five-minute per-victim kill cooldown, the canonical anti-farm rule.

Implementation notes

Kills flow from the GameServer's death path into the database and are polled into the war fiber every ten seconds; the cheapest correct home for the cooldown is a recent-victim map held on that single-threaded fiber, consulted as kills drain — no new database query, since kill rows already carry victim and timestamp. Surface "on cooldown" in the scoreboard kill feed so a skirmish does not read as a broken scoreboard. Preserve the existing bot-war force-expire path or the functional test harness breaks.

client S feed noteserver Mdb nonetests war fiber cooldown tests

S10 · War-scoped attackability

Tier 2Size M–LServer: new op

Being at war makes you attackable by the enemy guild — not open-PvP to every flagged player on the shard, which is what the current implementation does and even warns you about in the declare window. This is the single biggest reason guilds refuse wars, it is the community's most-repeated guild-war ask, and it is how UO has run wars since 1997: a private PvP contract between two guilds that overrides the global ruleset.

Seen in: UO guild war, twenty-eight years of proof; Albion, EVE and New World all scope war PvP to the participants.

Implementation notes

The whole current mechanic is one property: the player's effective open-PvP state is "flagged open PvP, or in any guild war." Because every nearby player's guild id is already replicated in the guild state property, enemy-scoped attackability is computable client-side: attackable if and only if the war manager finds a live war against the target's guild. The declare flow offers the choice per war — open-world rules or war-scoped — as a new declare op variant, since operation codes are name-and-parameter hashes and existing signatures must never change. Scene PvP layer assignment needs the same gating, and the misleading warning text is replaced. This is a rules change within the existing client trust model, not an anti-cheat change; the rejected list covers what that model rules out.

client Mserver Mdb nonetests war-flag matrix tests

S11 · Declare war by guild name, with a real proposal lifetime

Tier 2Size MServer: op + TTL

Declaring war stops requiring both leaders to physically find each other online inside a two-minute window. You declare against a guild by name; the proposal waits up to three days and greets the enemy leader at their next login. War declaration becomes diplomacy instead of a scheduling coincidence — which, for two guilds in different time zones, it currently is.

Seen in: UO's Diplomacy page, where wars are declared from a menu; EVE's asynchronous war declarations with 24-hour notice.

Implementation notes

Today's gate requires the target leader online with a game session, and the invitation's database TTL is two minutes. New declare-by-guild-name op through the five-file pattern; raise the invite TTL to about 72 hours (a TTL is an index change: one migrations-ledger row); deliver to offline leaders through the existing cross-shard message pattern the MOTD broadcast uses; show incoming and outgoing proposals as rows in the war list. Proposal spam is naturally capped: the store is already upsert-if-no-live-war per guild pair.

client Mserver Mdb TTL/index change, ledger rowtests GuildWarScoreboardAndInviteTests

S12 · Victory plaques and war mementos

Tier 2Size MServer: archetype

War outcomes become something you can hang on a wall: the winners can craft a placeable victory plaque naming both guilds and the final score, and both sides receive a campaign memento. Today one trophy is deposited into the winning leader's bank, and nobody else ever sees it. Cosmetic, permanent, and visible in the world — exactly the prize shape UO's Vice vs Virtue settled on.

Seen in: UO VvV's deliberately cosmetic silver rewards and house add-ons; WoW's Hall of Fame.

Implementation notes

Reuse the existing war-trophy payload and bank-deposit path on a new placeable decoration archetype; mint one plaque per winning side and one memento per participant, keeping the existing rule that a war must have run at least 23 hours to pay out. While in the sweep: fix the existing race where the victory row is removed before the trophy grant is attempted, so a failed grant loses the victory forever — award first, then remove.

client Sserver M + artdb nonetests trophy sweep tests

S13 · The guild crest

Tier 2Size M–LServer: field

Guilds get one shared crest — shown on the guild tab header, the war scoreboard, and the Chapter House lot sign — so the guild finally has a face that is not a text string. It extends the game's existing per-character heraldry system rather than inventing a second pipeline, and it answers the wishlist's guild-blazon asks.

Seen in: UO banners; WoW tabards; GW2 emblems flying over claimed objectives.

Implementation notes

Heraldry today is per-character; the guild record has zero identity fields beyond its two name forms. One additive crest field plus a targeted update helper (the record deliberately has no whole-document store). Render on the guild tab, the scoreboard, and the lot sign. Deliberately not in the replicated per-player guild state in v1 — that channel fans five fields out to every actor in view on every change, and a crest id there is pure bandwidth; nameplate crests are a follow-up behind the existing nameplate option. S21's war banner and S25's web page header both consume it.

client Mserver Sdb 1 additive field, ledger rowtests crest render model tests

S14 · Roster truth

Tier 2Size MServer: fields

The roster stops hiding what the servers know and starts remembering what they forget: every member row shows a join date (stored since day one, never once sent to a client) and a last-online that survives server restarts; the guild gains a founded date; and officers get a shared free-text note per member — "recruits", "on leave until fall", "vault steward".

Seen in: the universal roster columns of WoW, ESO and Albion; the game's own per-friend social notes, which set the pattern.

Implementation notes

Persist last-online as an additive member field written exactly where the in-memory value is maintained today; ship member-since and last-online in the roster payload; add a founded timestamp to the guild record; officer notes follow the existing social-note op shape, guild-scoped. Two guard rails: roster delivery is byte-budgeted at 3,500 characters per packet, so two compact timestamps per member mean more login packets for large guilds — measured, not assumed; and the roster load path already makes two per-member database fan-outs, so no new per-member reads.

client Mserver Mdb additive fields, ledger rowstests roster payload tests

S15 · Officer chat, and channels that check membership

Tier 2Size MServer: op logic

Officers get a private channel for the conversations that should not be in guild chat. And while we are in that code: joining a guild chat channel gets verified against actual membership on the server, which today it is not — the only gate is the client's own honesty.

Seen in: WoW's officer chat; the officer-channel convention in every guild game since.

Implementation notes

Chat channels are string-keyed; guild chat is the guild-kind prefix plus the guild name, gated only client-side. Add an officer channel kind and enforce membership and role server-side in the enter-channel handler against the peer's member state — the same state the war-declare gate already reads. The unauthenticated-join gap is pre-existing for guild chat; an officer channel makes it exploitable, so the server check is non-optional here. No schema change. S18 reuses this for alliance chat.

client Sserver Mdb nonetests channel auth tests

Tier 3 · Server-backed flagships — each carries its database cost openly

S16 · Persistent war history

Tier 3Size LServer: new collection

Wars stop evaporating. A permanent record of every war — final score, per-member kills and deaths, outcome including draws and forfeits — with a History tab on the war window. Today the entire war record deletes itself 14 days after creation (a ten-day war leaves four days of history), the kill rows expire with it, and the victory row is consumed by the trophy sweep before anyone can read it. This is the data foundation: the honor roll, the seasons, the ladder, and the guild web page's war history all read from it.

Seen in: UO's war records; WoW's guild-attributed Hall of Fame; WarcraftLogs proving public records create a metagame for free.

Implementation notes

New war-record collection written by the victory recorder for all end reasons including ties; embed the war descriptor snapshot exactly as the current victory row does. Per-member kill and death tallies aggregate on the war fiber as kills drain from the ten-second poll, then freeze into the record at war end — beating the kill rows' own TTL, and giving the scoreboard a server-computed tally for the first time. New paged read op for history; History tab on the war window. Retention is declared explicitly in the migrations ledger (permanent, or a 365-day TTL — a deliberate decision, not a default). Optionally lift the live war record's 14-day TTL in the same change, which S3 and S19 want anyway.

client Mserver Ldb new collection + indexes, ledger rowstests record writer + pagination tests

S17 · The guild finder

Tier 3Size LServer: new collection

New players can browse guilds that want members — headline, description, member count, playstyle tags, core hours — and apply with a message; officers review applications at their leisure. Today membership is invite-only, the invite dies in sixty seconds, and the target must be online. For a small population, recruitment friction is an existential problem, and this is the highest-leverage retention feature in the catalog.

Seen in: ESO's Guild Finder, best-in-class (activities, core hours, applications with messages); WoW's finder with 30-day requests. FFXIV's lack of in-game search is the anti-pattern.

Guild Registry
Search guildsRecruitingAll
GuildMembersStyleListing
Knights of the Radiant Court23PvE, craftingWe fish, we craft, we fight on Tuesdays
Crimson Sails15PvPWars welcome, all sizes honored
The Quiet Anvil8CraftingSmall shop, patient teachers
Apply to Knights of the Radiant Court
Longtime fisherman, new to war. Evenings mostly.
Send ApplicationCancel
Implementation notes

There is no op today to list guilds, read another guild's member count, or apply; the only public read is the exact-name description fetch. Add: additive listing fields on the guild record (listed flag, headline, tags), a new applications collection (applicant, guild, message, 30-day TTL), and browse/apply/answer ops through the five-file pattern with the standard paged-read idiom. Listing text runs through the same blacklist the guild-name check uses. One deliberate coordination: the web companion plan already claims a persisted-invitation feature for the web path — this builds one shared store, not two parallel ones. The listing renders in-game and on the companion's public guild directory from the same fields.

client Lserver Ldb new collection + fields, ledger rowstests application lifecycle tests

S18 · Alliances

Tier 3Size XLServer: new collection

Two eight-person guilds can be friends on the record: shared alliance chat, allied highlighting, and — in a second phase — fielding a war side together. Small guilds stay small and stop being alone. The constraints are UO's, kept deliberately: one alliance per guild, at most four guilds, no joining while you have active wars, and only the alliance leader speaks for the alliance.

Seen in: UO alliances, ported whole. Deliberately not EVE coalitions — the "blue donut" where everyone allies and nobody fights.

Implementation notes

Greenfield: the word does not appear in the server source. New alliance collection plus an additive alliance-id field on the guild record; the join guard checks the guild's live wars for the no-active-wars rule; alliance chat rides S15's authenticated channel join; allied highlighting is client-side, since every nearby player's guild id is already replicated — the client only needs its own alliance's guild list, pushed through the same cross-shard event pattern the MOTD uses. Guild events already broadcast to all group servers and filter per peer; alliance events multiply that fan-out, which is why the size cap is hard and alliance mutations are rare by design. Alliance wars — two guilds on one side of a single war — are phase two, gated on S19 and S20, because the war record is strictly pairwise today.

client Lserver XLdb new collection + field, ledger rowstests alliance guard tests

S19 · Negotiated war terms

Tier 3Size LServer: fields

Wars get terms both sides actually agreed to: first to N kills, timed (today's only mode), or open-ended until surrender — and the challenged guild can counter-offer instead of just accepting or declining. The war becomes a contract. This is the whole reason UO's version has run for twenty-eight years: nobody is ever in a war whose shape they did not sign.

Seen in: UO Diplomacy — counter-proposal negotiation, war begins only when both sides accept identical terms, kill-count / duration / eternal-war win conditions.

Declare War on Crimson Sails
Terms:First to 50 killsTimedUntil surrender
Start:In 24 hoursImmediately
While at war you can be attacked by Crimson Sails members only.
Send TermsCancel
Implementation notes

Additive win-condition and kill-target fields on the war record; terms ride the invitation, and a counter-offer is a new answer op that rewrites the invite with inviter and target swapped — viable only because S11 made proposals long-lived. Enforcement is one check in the kill handler (target reached, record victory) plus the existing forfeit path for surrender-only wars. All new op signatures, never changed ones: operation codes are name-and-parameter hashes and a changed signature breaks the wire. Eternal wars require S16's TTL lift — a 14-day record cannot hold an open-ended war. The war descriptor gains appended fields; the shared mirror syncs both sides.

client Mserver Ldb additive fields, ledger rowtests terms enforcement tests

S20 · Mercenary enlistment

Tier 3Size XLServer: new collection

Unaffiliated players can sign onto one side of a declared war as hired swords: they fight, they score, they appear on the scoreboard — and they never touch the guild's trust surface and never had to leave their own social guild. In a small population this is how forty bystanders become war participants. The underdog detail worth keeping from EVE: the challenged guild opens mercenary slots first.

Seen in: UO's Ronin rank (war participation only, no vote, no containers); Lineage 2's mercenary recruitment board; EVE's defender-only ally system.

Implementation notes

Deliberately not a new guild role — the three-value role enum is frozen (a guard test fails if it widens), and the ranks epic's rank axis is orthogonal. Enlistment is per-war state: a small enlistment collection keyed by war and user, join and approve ops, slot caps, and per-enlistee approval by the enlisting side. The kill-attribution block in the GameServer — the most load-bearing code in the war system — must also consult enlistment, and the client's war-flag path must set for enlistees with no guild. Requires S10 so mercenaries are enemy-scoped, not world-flagged; S9 so merc kills cannot farm; S11 for the board to live on.

client Lserver XLdb new collection + index, ledger rowtests attribution matrix tests, heaviest coverage

S21 · Contested objectives

Tier 3Size XLServer: new collection

An optional war mode adds a place to fight over: a war banner in a scene both sides agreed to, scoring by occupation ticks and captures as well as kills, active only during windows the challenged guild chose. A duo of crafters can win a tick by holding the banner while the fighters brawl — nobody's only verb is "kill." This expands the roadmap's structured-PvP idea on the guild side; arenas and ratings stay with that parent idea.

Seen in: UO VvV — battles that ignite from population, multi-verb scoring, consequences in minutes not hours; EVE's defender-chosen prime-time windows. Rejected precedents: permanent territory with taxes (New World), fixed rosters (Albion's own retrospective), 24/7 vulnerability (ESO night-capping).

Implementation notes

A war-mode flag and scene/window terms on S19's terms payload. Objective scoring reuses the proven decoupled hop: the war-kill collection exists precisely so a lost server link cannot drop war scoring — scene servers write objective-tick rows to a sibling collection, drained by the same ten-second poll into the same score fields. Capture logic lives scene-side; the known perf constraint is that the scene's guild-identity lookup is an uncached blocking read per call, so the objective caches combatant guild identity for the window. The banner flies S13's crest. Sequenced last of the war items; the scene-server work is the unknown and gets a spike first.

client Lserver XL + scenedb new collection + TTL, ledger rowtests tick scoring tests

S22 · Seasons and the public ladder

Tier 3Size LServer: reads S16

A quarterly season rolls every guild's wars, objectives and hunts into one public standings page — in the game and on the web — then hard-resets, so a dominant guild must re-earn its title and a brand-new guild gets a visible entry point four times a year. Rewards are strictly cosmetic: crest frames, plaque variants, a title line on the guild tab. Never power. WoW ran that experiment for four years at a hundred times our population and removed it.

Seen in: Albion's 12-week guild seasons with hard resets; WoW's guild-perk removal as the binding constraint; WarcraftLogs and Raider.io proving public data builds the metagame at zero cost.

Implementation notes

Computed entirely from S16's war records plus S21 objective points plus S23 hunt points, so guilds that never PvP appear on the same board. A season-boundary config, a paged standings read op, a Standings tab beside the History tab, and a public read-only page on the guild web companion. The dead-ladder risk at low war volume is handled by construction: kills alone never decide the board.

client Mserver Ldb none beyond S16 (or 1 summary collection)tests season rollup tests

S23 · Guild hunts and the first-clear ledger

Tier 3Size L–XLServer: new collection

Weekly guild-scale PvE: hunt a named roaming boss, or race to find a set of world locations before the timer — content a five-person guild completes together, with an authoritative, timestamped, guild-attributed record of who did it first. Guild competition for the majority who will never flag for PvP, and the PvE feeder for S22's ladder.

Seen in: GW2 guild missions — Bounty and Trek, which run with five people and reward guild and individual both; WoW's move from individual realm-firsts to the guild Hall of Fame; FFXIV proving the community builds the race if the record is public.

Implementation notes

Completion detection is server-side in the existing kill and discovery paths, writing guild-attributed completion rows; attribution reads the killer's guild membership exactly as the war-kill block does. Storage patterns exist (the guild-keyed audit log), but this is a new collection with real retention — a 30-day TTL that suits an audit log is wrong for a hall of fame, so retention is an explicit ledger decision. A Firsts panel joins the guild tab; the ledger publishes to the web companion. The code is the smaller half; curating the boss and location lists is the real cost.

client Mserver L + contentdb new collection + indexes, ledger rowtests attribution + rollup tests

S24 · The guild vault

Tier 3Size XLServer: new collection

A real guild bank: shared item storage in named tabs and a gold ledger, with per-rank daily withdrawal caps and a full transaction log — so trusting a new member is a bounded risk instead of a leap of faith. It is the single most-requested guild feature in the genre, the reason the WoW model became the standard, and it is completely absent here today.

Seen in: WoW's guild bank — per-rank per-tab view, deposit and withdraw, daily item and gold caps by rank, transaction logs. Deliberately not EVE's theft-as-content.

Implementation notes

A new guild-keyed vault collection modeled on the item-store shape (the personal store's schema is not touched — changing it is a breaking migration), plus a guild gold balance with targeted update helpers. Server-minted deposits into bank storage are proven viable by the existing war-trophy path. Per-rank caps are the point, so the full version depends on the ranks epic's rank axis; a version gated on the three frozen roles can ship first using the permission-bit space S4 freed. The audit trail gets its own collection with dispute-friendly retention, rendered by S2's viewer. All mutations serialize through the guild's single-threaded fiber, which is also the anti-race guarantee on withdrawals. Highest exploit surface in this catalog — every shared-container system in MMO history has shipped a dupe — so it carries the heaviest test investment and server-side invariant checks on every mutation.

client XLserver XLdb new collections + field, ledger rowstests invariant + cap suite, heaviest in catalog

S25 · The guild page bridge

Tier 3Size MServer: feeds

Every guild is getting its own page on the web — roster, calendar, message board, recruitment listing, with login by real game account — under the separately planned guild web companion. This card is the seam neither plan covers: the game links out (a Visit Guild Page button on the guild tab and the lot sign), the game reads back (the Events tab shows the web calendar's upcoming events, read-only, so the calendar has one source of truth), and the game feeds the page the data that makes it worth visiting — S16's war history, S22's ladder standing, S13's crest, S17's shared listing and applications.

Seen in: FFXIV's Lodestone, the first-party Free Company page every guild simply has; the WoW armory; Albion's killboard.

Implementation notes

The companion program owns everything web-side (its plan covers identity, authorization, and the read-only game-data API). This card's game-side work: the link-outs; a small read-only events view backed by the companion's calendar API rather than a second in-game calendar data model; and making sure the S16/S22/S13/S17 schemas ship with the companion's read patterns in mind. Without S16, the web page's war history section would be near-empty forever — war records currently self-delete in 14 days — which is why the bridge card and the history card travel together.

client Mserver API coordinationdb none of its owntests events view model tests
Section 3b

Considered and rejected

Section 4

Two windows and a web page

Twenty-five proposals must not become twenty-five windows. Everything above composes into three surfaces: the Guild Ledger (the Social window's Guild tab grown into a real home), the War Council (today's war list, scoreboard and declare windows absorbed into one), and the guild's web page (delivered by the companion program, fed by the game). Tier 1 lands inside today's windows; Tier 2 builds the shells; Tier 3 fills the tabs.

Surface A · The Guild Ledger

Knights of the Radiant Court
[Crest]Leader: Aldric VaneMembers: 23 (7 online)Founded: 12 Mar 2026War CouncilGuild Page
MOTD: Fishing contest Saturday at the guild dock. Bring your own bait.Edit
RosterRanksVaultLogEventsRecruitment
NameRankJoinedLast OnlineNote
Aldric VaneLeader12 Mar 26Onlinefounder
Mira ThornOfficer14 Mar 26Onlinerecruits
Tam FletcherQuartermaster02 Apr 262 days agovault steward
Wen AshbyMember19 Jun 2631 days agoinactive
Pending invites (2): Corwin Slate, Bess HarrowCancel Invite
Invite PlayerPromoteDemoteSet NoteKick

Surface B · The War Council

War Council
Declare WarAlly BoardSeason 3 ends in 24 days
Active WarsTermsScoreEnds
vs Iron PactFirst to 50 killsKRC 31 : 24 IPat 50 kills
vs Crimson SailsTimed, 3 daysKRC 12 : 19 CS1d 04h
IncomingHouse Meridian proposes: timed, 5 days, starts in 24hAcceptCounterDecline
Scoreboard: vs Crimson SailsKillsDeathsLast Kill
KRC · Mira Thorn6214m ago
KRC · Aldric Vane451h ago
CS · Red Anne9314m ago
Kill credit on the same victim has a 5 minute cooldown.
Honor RollDateResult
Won against Iron Pact22 Jul 2641 to 18Craft Plaque
Draw against House Meridian12 Jun 2616 to 16
Lost against Crimson Sails30 Jun 269 to 30
Auxiliaries: 1 hired (war only, no vault access)Hire board: 4 swords for hire

Surface C · Your guild's page on the web

catnipgames.net/guilds/knights-of-the-radiant-court
[Crest]Knights of the Radiant Court[KRC]23 members · Season 3 rank 4
We fish, we craft, we fight on Tuesdays. Core hours 7pm to 11pm central.Apply to Join
OverviewRosterWar HistoryCalendarBoard
War HistoryDateResult
Won against Iron Pact, first to 5022 Jul 2641 : 18
Draw against House Meridian, timed12 Jun 2616 : 16
UpcomingSat 09 Aug 8pm: Fishing contest at the guild dock (9 signed up)
Public summary. Roster detail and the board are member-only.Sign in with your game account
Section 5

Sequencing

PhaseShipsTheme
1S1–S7See your guild. The whole quick-win tier: client work and one enum fix, independently shippable in any order. S3 is the sleeper — a war feature shipped by deleting one hard-coded zero.
2S8, S13, S14, S15 · S16 beginsThe management spine. The additive-field wave: heir, crest, roster truth, authenticated channels. S16's record collection starts writing invisibly now, so later features launch with real history instead of an empty ladder.
3S9, S10, S11, S12 · S16 shipsWar integrity. Make the existing war mode worth playing before extending it: honest scoring, enemy-scoped flagging, asynchronous declaration, tangible mementos, and the History tab.
4S17, S19, S18 · S24 with ranks · S25 tracks the companionCommunity growth. The recruitment funnel first — it is the retention feature — then negotiated terms, then alliances. The vault starts the moment the ranks epic's rank axis lands.
5S20, S21, S22, S23Flagship conflict. Mercenaries, the objective mode (scene-server spike first), and the first season opening with three point sources — wars, objectives, hunts — so every guild archetype appears on the board.
flowchart TD
  T1["Phase 1: S1..S7 quick wins"] --> LEDGER["Guild Ledger shell"]
  LEDGER --> S17["S17 finder"] & S24["S24 vault"] & S14b["S14 roster truth"]
  RANKS["Ranks epic (external)"] -.-> S24
  COMP["Web companion (external)"] -.-> S25["S25 guild page bridge"]
  S16["S16 war history"] --> S19["S19 terms"] & S22["S22 seasons"] & S25
  S11["S11 declare by name"] --> S19
  S19 --> S21["S21 objectives"]
  S10["S10 war-scoped flagging"] --> S20["S20 mercenaries"] & S21
  S9["S9 score integrity"] --> S22
  S15["S15 channel auth"] --> S18["S18 alliances"]
  S13["S13 crest"] --> S21 & S25
  S21 --> S22
  S23["S23 hunts"] --> S22

The dependency spine in one line: the war history record feeds the terms, the seasons and the web page; declare-by-name feeds terms feeds objectives; war-scoped flagging gates mercenaries and objectives; channel auth gates alliances; the ranks epic gates the vault's caps; and score integrity underwrites every scoreboard on the page.

Section 6

Appendix

The numbers as they stand

ConstantTodayProposal
Guild charter price25,000 goldunchanged
Description / MOTD length300 / 200 charsunchanged
Roles3, frozenunchanged; ranks epic adds the display axis
Pending invites16 max, 60 s, in memory, target onlinepersisted applications, 30 days (S17)
War proposal lifetime2 minutes, leader online72 hours, offline delivery (S11)
War duration1–10 days, timed onlykill target / timed / until surrender (S19)
War start delaysupported by the server, never sent0 / 24 h / 3 days (S3)
War record retention14 days from creationpermanent record collection (S16)
Kill scoring+1 per kill, no dedupe5-minute per-victim cooldown (S9)
While at warattackable by all open-PvP playersattackable by the enemy guild (S10)
Activity log30 days, text-file dump30 days, in-game viewer (S2)
War trophy1, to the leader's bank, wars over 23 hplaque + mementos, both sides (S12)

Credit ledger

Separately planned work this page builds on and does not re-propose: the guild ranks and property permissions epic (custom rank names, per-rank permissions — the Ranks tab and the vault's caps host it); the guild and town web companion (per-guild web pages, calendar, message board, web applications — Surface C is its delivery, S25 is the seam); the roadmap's structured and ranked PvP idea (S21 expands its guild-objective half); the roadmap's recurring engagement loops idea (S23 is its guild-attributed layer); and the community wishlist sweeps that supplied the invite-confirmation, opt-in war flagging, victory plaque and guild-blazon asks.

Test surface

Existing EditMode suites extended rather than replaced: the social window model tests, the war scoreboard and invite tests, the war list conversion tests, the role-enum parity ratchet and the role-guard test that fails if anyone widens the frozen enum, and the guild-lot grant revocation tests. New pure-logic targets, in rough order of value: the kill-cooldown drain, the terms enforcement check, the season rollup, and the vault's cap and invariant suite.

Sources

UO guild creation and diplomacy · UO Vice vs Virtue · UO Factions · WoW guild bank · WoW guild leveling removed · ESO Guild Finder · GW2 guild missions · GW2 guild halls · Albion guild seasons · Albion Disarray · EVE war declaration reform · EVE ally system · Lineage 2 castle sieges · New World wars and small companies · FFXIV Free Companies · DAoC relic rubber-banding

This page is one of a series of design proposals at catnipgames.net/blog/proposals. Vote on the cards you care about and leave a comment — which parts matter to you changes what gets built first.

Feedback

General comments

No account needed. Every proposal above also has its own Discussion box for talking about that one alone; this thread is for the plan as a whole. Comments are plain text, held to basic decency, and may be trimmed.