Bobby Thompson.

Systems engineering & leadership · Head administrator since 2006 · Developer since 2021

Sea of Storms

Running continuously since 1998, Sea of Storms is a roleplay-focused, text-based multiplayer game set in the world of The Wheel of Time. I joined as a player in 2000 and grew into leading its community and developing its C/Linux codebase. It is also where my interest in coding and system administration began.

  • C
  • Python
  • Linux
  • SMAUG
My role Implementor (head administrator) & developer

01

From player to Implementor

I joined Sea of Storms in 2000, while I was in high school, because I wanted to experience the world of The Wheel of Time. What kept me there was the community: the characters people created, the relationships between them, and the stories we could tell together. Over time, I wanted to help create those experiences for other players.

In 2004, I became an administrator responsible for in-game clans and story events. In 2006, I was promoted to Implementor, the highest administrative role, and became the head staff member. My responsibilities grew to include the game’s direction, day-to-day player issues, and keeping the system running.

Sea of Storms was also what sparked my passion for coding and system administration. Wanting to understand and improve a game I cared about gave me a reason to learn how the software and servers worked. That interest eventually led me to pursue my degree at Washington State University and a career in software engineering.

  1. Joined as a player

    Discovered the game and its roleplaying community during high school.

  2. Became an administrator

    Took responsibility for in-game clans and story events, shaping experiences around player interests.

  3. Promoted to Implementor

    Became the highest-level administrator and head staff member, responsible for players, operations, and the game’s direction.

  4. Graduated from WSU

    Earned my B.S. in Computer Science, cum laude, and began my full-time software engineering career.

  5. Began codebase development

    Brought my experience with C and Linux into direct development, adding requested features and new systems while repairing legacy problems.

My work on Sea of Storms still comes from that same place: a love for the game and the community around it. I add features because I want people to have more ways to inhabit this world, tell their stories, and enjoy the time they spend together.

02

Building stories with a community

As an administrator, I began listening to what players wanted to experience beyond the game’s everyday activities. Some wanted large-scale battles; others wanted intrigue between factions or a chance for their character to matter in a larger story. My role was to turn those interests into situations the community could take part in together.

One major storyline brought rival clans together to resist a Shadow siege of Shol Arbela in the Borderlands. The city’s fall became the beginning of the next chapter: a campaign to reclaim it, followed by the work of rebuilding. Carrying the story through those stages gave players reasons to cooperate across faction lines and continue participating after the fighting ended.

That is the kind of continuity I want to create: events whose consequences become part of the world people return to. A new arc is beginning in the Aiel Waste, where players are investigating strange rumors. I continue to run these stories alongside player support and server administration, so the people using the game remain close to the decisions I make about its future.

One setting, three connected event arcs
  1. DefendBring conflicting clans together against the siege of Shol Arbela.
  2. ReclaimReturn to the fallen city and drive back the Shadow.
  3. RebuildCarry the story into the city’s recovery after the fighting.

03

Modernizing a legacy C codebase

Leading the community also made me increasingly aware of what the underlying software could make possible. I could create events through the existing game, but adding the features players asked for meant working directly with its code. In 2021, once I felt ready with C and Linux systems, I began developing the codebase myself.

A game that has been running since 1998 carries a long history in its source. New features had to coexist with older mechanics, saved characters, and the expectations players had built over years. I worked through long-standing bugs and hundreds of inherited compiler warnings, bringing the C/Linux build I maintain to zero warnings and errors.

I also built broad regression coverage so future changes could be checked against existing behavior. A clean build makes new diagnostics easier to notice, and repeatable tests give me a way to investigate changes before they reach players. Together, that work established a more dependable foundation for the larger combat, archery, and storytelling systems that followed.

The purpose of modernization is to let the game keep growing while respecting the time people have already invested in it. Preserving characters, progress, and familiar rules is part of delivering something new to this community.

04

Turning player ideas into complete systems

With that foundation in place, I could take on requests that required a whole system. I start with the experience a player or staff member wants: a different way to fight, a character concept the game does not yet support well, or a way to carry a story across events. That gives the technical work a purpose and helps define what a successful addition should do.

From there, I work through the rules, data, commands, integration points, and failure cases; implement them in the existing game; and build the tests and documentation needed to maintain them. The examples below show that process from several angles, from reworking a central combat mechanic to creating new tools for roleplay.

How a community idea becomes a maintained feature
  1. Understand the experienceListen to players and staff, identify what is missing, and define the outcome we want.
  2. Design & buildTurn that goal into rules, data, and working code that fits the existing game.
  3. Test & explainCheck behavior and failure cases, then document how the feature works for players and maintainers.
  4. Support & evolveStay involved with the community and use its feedback to guide the next improvement.

05

Rebuilding and balancing the forms combat system

Forms are the game’s signature combat techniques, and reworking them meant reconsidering how weapon choice, timing, defense, and stamina fit together. I wanted different weapons and builds to offer meaningful choices, with rules I could explain and balance through evidence. That required both a redesign of the combat system and a way to observe how it behaved across many combinations.

I treated form selection, attacks, counterattacks, equipment, and recovery as one connected design, while retaining the 1,000-point player movement limit and compatibility with existing characters and form catalogs. Ordinary attacks and counterattack readiness have separate timing, fractional recovery preserves smaller differences between actions, and repeated defenses have a bounded effect on the defender’s next attack. A separate monotonic combat clock skips missed ticks instead of releasing a burst of catch-up attacks.

To understand the effects of those decisions, I built a Python-backed browser dashboard for configuring duels, managing isolated local servers, launching campaigns, and inspecting progress and results. The fleet reached 96 concurrent server processes. Each had its own runtime and a continuous runner assigned a specific set of cases, making large controlled experiments practical.

The planner expresses build combinations as a test matrix: six weapon families, form levels, fixed or mixed form selection, stances, proficiencies, weapon-forging and power-forging profiles, encumbrance levels of 25, 50, and 75, and eligible one-handed, two-handed, shield, and dual-wield arrangements. It keeps repetitions, alternating openers, and equivalent reversed matchups together when distributing the work. Each campaign selects a defined part of that matrix; the total volume does not mean every possible character build was exhaustively tested.

For the results to guide changes, I needed to know what each test actually ran. Telemetry records the setup, code and tool fingerprints, and observed combat policy. The reporting system validates that evidence, excludes incomplete or conflicting cases, and keeps incompatible versions and controls separate. A background collector and SQLite cache support matchup tables, win-rate heatmaps, coverage checks, equal-opponent weapon comparisons, and comparisons with saved baselines.

That let me investigate why a build struggled: attack cadence, damage after mitigation, defensive recovery, counters, movement use, or exhaustion. Native C release and sanitizer fixtures check the rules themselves, while player and maintainer documentation make them explainable. For the community, the goal is a wider range of viable combat choices; for the codebase, the lasting addition is a repeatable way to audit and tune those choices. The instrumented testing environment was archived separately from the production game after the campaign work.

The architecture behind a balance experiment
  1. Define the matrixChoose builds and controls, generate case IDs, and preview the distribution before running anything.
  2. Distribute & executeAssign intact matchup groups across isolated servers; record each runner’s configuration and progress.
  3. Capture & validateReconcile raw telemetry, completion markers, saved summaries, and runtime policy into validated results.
  4. Compare & iterateInspect coverage, heatmaps, exhaustion, and baseline differences; use the findings to guide the next change.
The scale of the local forms-testing effort
local servers running concurrently at peak
96
run records containing completed test cases
1,427
completed cases recorded in the run index
791,796
recorded combat exchanges
71.48 million

Historical evidence from September–October 2026. The October 6 archive index contains 1,488 run records in total, including 61 with no completed cases; its exact exchange count is 71,482,911. These totals span repeated experiments and different code versions. Individual comparison reports validate and separate compatible results.

One completed campaign carried this process through 105,840 validated cases and 6,622,875 recorded exchanges, with all 96 runner jobs successful and zero validation errors or unfinished case folders. These cases belong to the broader testing effort shown above. The scale gave me evidence to guide balance decisions, while the coverage and validation rules kept the limits of that evidence visible.

06

Making archery a complete combat path

Archery offered another opportunity to turn a character idea into something the game could support more fully. The projectile system had been neglected, leaving room for a richer ranged play style. I wanted a player to be able to choose archery as a complete specialization, or combine it with an existing talent to create a different kind of fighter.

I expanded that foundation and added Archery Mastery, bringing together carefully aimed Snipe attacks, Rapid Shot bursts, Pinning Shot control, the passive Deadeye damage bonus, and Camouflage that works with existing concealment skills. The abilities give the player different decisions to make: commit to a precise shot, apply pressure, limit an opponent’s movement, or use stealth and positioning to choose an opening.

Making a ranged talent reliable meant following a projectile through the whole game. I worked through bow and ammunition compatibility, range and line of fire, targeting across rooms, defenses, quiver access, ammunition selection, wear, recovery, and saved preferences. An aimed shot can be interrupted, and the system rechecks the target, weapon, path, and resources before firing. Native regression fixtures and controlled comparisons support the integration and tuning work.

The result opens up character concepts that draw on more than one talent. An Assassin can use archery to become a sniper; a Weapon Master can play an archer in an army; and a Woodsmanship character can bring a ranger concept to life. The value to the community is that an underused mechanic now supports more of the ways people want to experience the world.

Character concepts opened up by Archery Mastery
  1. Assassin + Archery MasteryBuild a sniper who uses concealment, positioning, and carefully aimed shots to engage targets from beyond melee range.
  2. Weapon Master + Archery MasteryPlay a trained military archer: a member of an army’s archery company with both ranged and existing combat expertise.
  3. Woodsmanship + Archery MasteryCreate a ranger-style character who combines woodland skills with a developed ranged-combat toolkit.

This addition brings a full ranged-combat lifecycle into the codebase and gives players another way to express their character through mechanics. Its connections to existing talents are part of the design, so archery can stand on its own or contribute to a broader build.

07

Building a shared-story platform

The same desire to give players richer experiences extends beyond combat. Running connected story arcs raised a different design problem: staff needed to manage shared prophecies, visions meant for particular characters, and rumors spread by NPCs. Those stories needed consistent authoring and history, while still respecting who should be able to encounter each one.

I designed one versioned catalog to provide the shared foundation, with separate eligibility and delivery rules for each story type. Staff can draft, preview, revise, publish, and archive content. The published version stays available while a replacement is edited, and stale concurrent edits are rejected. Player commands and NPC scripts use the same delivery rules, including the source, intended audience, and relevant clan or council membership.

Keeping a story coherent also means preserving it when something goes wrong. Updates use temporary files and atomic replacement; failed saves and corrupt reloads leave the valid published catalog intact. Delivery history survives restarts, and rename or retirement operations keep character-bound stories from silently attaching to someone else.

I carried the work through C modules, command and NPC integration, import tools, administrator documentation, and native regression fixtures. Recorded local checks cover release and sanitizer runs, failed writes, malformed files, private delivery, and reloads in a fresh process. This gives staff a common set of tools for maintaining a narrative, with continuity and audience rules built into the software.

A story is being revised
Players can still encounter the published version while staff prepare the next one.
A rumor has a limited audience
Its source and audience rules are enforced consistently, even when a specific story is requested.
Saving or reloading fails
The valid published story remains available instead of being replaced by incomplete data.
The game restarts or a character is renamed
Delivery history and character bindings are retained through the supported lifecycle.

The platform is intended to let staff spend more attention on the story while giving players a consistent experience of how it reaches their characters. Its catalog, delivery rules, persistence, and tests are implemented and verified locally; that verification is separate from a live rollout.

08

Designing a separate True Power system

Some story possibilities also call for new mechanics. I wanted the True Power to become a distinct tool for advancing plots, with abilities and consequences that fit its place in The Wheel of Time. The books leave many mechanics only partly described, so the challenge was to translate limited lore into consistent game rules without losing the source’s identity.

I designed and implemented a separate channeling system with its own access rules, power state, techniques, costs, and lasting consequences. Its techniques can serve roles familiar from One Power weaves, but have different mechanics and requirements. Making the source explicit allows the game to distinguish what is being used when applying effects, spending resources, and deciding what a character can perceive.

The new system still shares characters and a world with the existing one. During normal play, a character cannot hold the One Power and the True Power at the same time. I added checks in both directions and ongoing validation, so acquiring one source, releasing it, or losing access leaves the character in a coherent state. Maintained effects belong to their source and are cleaned up when it is released; lasting character state is saved, with death, departure, and extraction handled as part of the integration.

For staff, this creates controlled ways to introduce new abilities and consequences as a story develops. For players, its purpose is to make those developments something they can encounter through the game’s systems as well as its narrative. Where the books leave an interaction uncertain, an explicit design decision and deliberate story control help keep the addition compatible with the lore.

From limited lore to an integrated game system
  1. Interpret the source materialIdentify what the setting establishes and where game rules require careful extrapolation.
  2. Model a distinct sourceDefine separate access, state, techniques, costs, and consequences.
  3. Integrate shared boundariesEnforce source exclusivity and connect effects, character lifecycle, and persistence.
  4. Support story progressionGive staff deliberate control over how the system enters and develops within a narrative.

The addition expands what a story can do while keeping the two channeling systems distinct. It also leaves the codebase with clear rules for source ownership, effect lifetime, persistence, and shared character state, so future work has a defined foundation to build on.

09

Regression tests, step by step

Every new feature adds more interactions to a game people already depend on. I want to keep improving it without quietly breaking the behavior players know. A regression test makes an established rule repeatable, so a later change can be checked against it. The forms experiments help evaluate balance; these focused tests check whether a particular interaction still works correctly.

One example comes from the archery work. Snipe takes time to aim, so a target can change rooms between the player starting the action and the shot being released. The old aim must then be canceled without firing a delayed shot or charging the archer for an attack that never happened. Checking only the command’s initial response would miss the problem; the test has to follow the action as the world changes around it.

I exercise the actual C implementation in isolated fixtures, using disposable characters and controlled randomness. The existing Snipe regression follows the sequence below. Release builds check the behavior, while sanitizer builds add checks for memory errors.

One regression example: the target leaves during Snipe
  1. Set up a known starting stateCreate a test archer and target. Equip a bow, give the archer two arrows and 1,000 movement points, and place the characters in the test world.
  2. Start the real commandInvoke Snipe through the game’s C command handler. Check that beginning the aim has not consumed an arrow or spent movement.
  3. Change the world before releaseMove the target into another room through the real character-transfer functions. Advance the aim-update loop 20 times, past the point when the original shot would have fired.
  4. Assert the resultCheck that the archer still has both arrows and all 1,000 movement points. A failed assertion makes the test fail, exposing a delayed shot or an incorrect resource charge.

A small, repeatable test protects a player-facing promise: an interrupted shot should not cost an arrow or stamina. I use Codex and AI agents to help investigate code, implement changes, and extend this coverage, while I define the requirements, review the work, and verify the results. That is how I keep connecting new ideas back to the community that made me want to build them.

Let’s connect

Something useful
starts with a conversation.

Have a software engineering role in mind?
I’d be glad to hear what you’re building.