I build things that give people back their time.

Games that respect how little free time people have, tools that make repeated work disappear, and the testing that keeps both honest. Those are the three things I keep coming back to, and everything on this page is one of them.

I notice when a system wastes people's time, find out why, and fix it. I learned that on a support desk before I learned it as a tester, and I have kept doing it as a developer.

Reid Hansell. Denver, Colorado.

Background

2019 to 2022
Akerna. Tier I Technical Support, Tier II within three months, then Software QA Analyst.
2023
BS Computer Science, Colorado State University.
2023 to now
Volunteer Software Developer on the team running a live online game. Gameplay and backend work in Java and C++, internal web tools in Node, React and AWS Lambda, and two Discord bots.
2026 to now
Dire Fate LLC. Founder and Solo Game Developer. Cadence, below.

Work

Live online game, volunteer dev team

2023 to now. A few thousand weekly players. The community's Discord has twenty thousand members.

Match lobby

Lobby system replacing the competitive mode's queue.

The old queue and the lobby that replaced it BEFORE Queue up Wait for groups Prep timers Fight Match ends no rematch, stuck sometimes start over from the queue About five minutes from queue to fight, and it broke on many player states. AFTER Lobby Fight rematch a replacement player joins mid-match About thirty seconds from queue to fight. Several groups at once.
Built with
Java
When
2026
Time back
five minutes of waiting, now thirty seconds

The lobby replaced a competitive queue that made everyone wait about five minutes before a fight and broke on many player states.

The story

The old queue was built in the 2000s. It sat you in timers, broke whenever a third or fourth group was late, got worse with more than one group a side, sometimes left you stuck, and had no rematch, so every match paid the whole cost again. The lobby cuts queue-to-fight to about thirty seconds, takes several groups at once, has rematch built in, and lets a fresh player replace one who has dropped, which the old system could not do at all.

I rebuilt it because I play the mode and the queue was the worst part of it. That is most of how I choose what to fix.

Trade economy

Cargo runs between city markets, with guards, raiders and a black market.

What the trade economy is made of, and the two servers under a single run WHAT THE FEATURE IS MADE OF Vehicles and cargo capacity, speed, hit points three tiers by load raider vehicles: fast if empty Three jobs driver, guard, raider five ranks each small runs PvE, large runs PvP The market crafters build, brokers trade weekly refresh, pay by distance fencers buy cleaned cargo The loop a run raided stolen chased recovered again and again Rules and signals pay kept in line with the rest of the economy travel locks while carrying cargo big runs announced in game and on Discord deliveries feed the war score THE WORLD: ONE PLACE TO PLAYERS, SEVERAL SERVERS ON THE BACK END server 1 server 2 City A City B the driver the vehicle haul cargo from A to B at the line: who owns what, right now? usually together; at the line, one crosses first About 8,500 lines across a dozen scripts, touching travel, vehicles, combat and Discord.
Built with
Java, some C++
Spans
vehicles and cargo, three jobs with guilds and rankings, a market with weekly resets, PvE and PvP, several servers

A trade economy across the whole game: load a vehicle, buy low in one city, sell high in another, with other players paid to protect the run or to steal it, and everything that hangs off that, from guilds to a black market.

The story

Three constraints made it hard. Players already had a ceiling on what they could earn in an hour, and the feature could only sit a little above it. The game has many ways to travel, and a player carrying cargo had to be kept out of most of them. And every interaction crossed several servers, because the world only looks like one place, so each crossing needs a live answer to which server owns the vehicle, the cargo and the players on it. The arbitration already existed. The feature depends on the answer at every step.

The travel rule is the one I learned from. I blocked the paths I knew about one at a time. Players found the ones I had missed, finished a run in three minutes instead of twenty to forty, and support spent days clawing back money. The fix that held was to find the one place travel and vehicle storage pass through and put the check there. Guard the choke point, not the callers.

Chat bridge

Two-way chat between the game and Discord, inside the chat engine.

Two ways to connect a game's chat to Discord HOW OTHERS BRIDGED IT Discord bot process a headless user logged into chat chat system A workaround standing next to the product. OURS Discord chat engine one bot, a singleton with a permanent slot in chat a few lines changed elsewhere A feature in the product.
Delivery is instant in both directions, because the bot is inside the engine rather than beside it.
Built with
C++, a C++ Discord library
Reach
A few thousand weekly players
Time back
delivery is instant, both ways

Two-way chat between the game and Discord, so people on either side are reading one conversation.

The story

Polling was out first, because chat that arrives late is not chat. Discord's webhooks were out next: fast enough, but more complexity than volunteer hours could carry. A C++ Discord library gave instant delivery without the webhook work. Choosing C++ over something easier in JavaScript is what put the integration inside the chat engine instead of beside it. Other teams bridged theirs by logging a headless user into chat. Ours is one bot living in the engine as a singleton, with a permanent slot in the chat system.

Build and deploy tool

One window for the team's build, deploy and client sync steps.

The build and deploy loop as console commands, and as one window of buttons BEFORE $ build the tables (one command) $ build the Java code (another) $ build the engine code (another) $ build the appearance files (another) $ compile one file, if you know the flags $ copy the client file off the VM by hand $ point the test client at the dev server became AFTER Dev tools Build tables Build Java Build engine Build appearance Compile file Sync client dev connection: configured once
Sync brings the client to whatever state the virtual machine is in.
Built with
Python, Ant
Also
Java, C++, Node, React, AWS Lambda
Time back
seven commands and a file transfer, now one window

One application replaced the list of console commands and the manual file transfer it took to build and deploy a change on that server.

The story

Every command became a button. The connection became a configuration you enter once. And a sync function brings the client to whatever state the virtual machine is in, so switching branches cannot leave you testing on stale files. That mismatch costs an afternoon before anyone suspects the code was never the problem.

For the same team I built an in-game creator for non-player characters, so the people writing content stopped waiting on a developer, and web tools for player metrics, player management and automated patch notes.

Discord bots

Two services run for years: event organizing for the community's Discord, and trade contracts.

A contract's life in one bot, and a match's life in the other ONE CONTRACT, IN THE TRADE BOT open in progress complete done un-accept returns it to open cancelled a crafter opens it: resource, quantity, price a miner accepts, delivers to a vendor the crafter registered, and marks it complete the crafter confirms; stale ones expire on a timer ONE MATCH, IN THE EVENT BOT scheduled posted queues fill both sides full ready played results image next week results arrive from the game's own scripts and go out as a decorated image
Built with
JavaScript, Discord.js, SQLite
Ran on
A Linux server I administer
Open
BF-03, Unkar-Plutt

One has organized over a thousand competitive matches and was adopted by the game's twenty-thousand-member Discord as its event tool. The other has generated over a thousand in-game trade contracts.

The story

Both exist for the reason everything else on this page does: the coordination was repeated work, and repeated work should disappear.

In the trade bot a crafter posts what they need, a miner takes the job, and the contract tracks itself to delivery, so the list keeps itself. In the event bot a match is a post with a button per side: players queue themselves, the post says when both sides are full, the schedule re-posts every week, and the results go out as an image when the match is over. The community's Discord adopted it as the event tool, which is what organizing over a thousand matches looks like.

Neither has a test suite. Both have years of uptime for real users on a box I administer myself, which is the other way to learn what breaks.

Market Mock, personal project

Market Mock

2023, revived in 2026 as the target for a test suite.

Market Mock

Paper-trading app, built end to end and covered by a risk-based test suite.

Market Mock: client, server and database, the price feed that drives orders, and the two test layers around them THE SYSTEM market data API, live prices Client React, TypeScript search and stock detail watchlist and portfolio order placer, quests login, email verification Server Node, Express, TypeScript routes: auth, ticker, order, portfolio, watchlist, quest cron: pull prices all day, fill open orders on a price hit MySQL users, orders, transactions holdings, watchlists net worth history prices, cached for an hour THE TESTS AROUND IT Playwright, end to end, against the whole stack in Docker Compose Jest units in GitHub Actions on every push, main gated on the check
Built with
TypeScript, React, Node, MySQL
Tested with
Playwright, Jest, GitHub Actions
Ran on
Docker, NGINX, AWS
Open
source, test plan, defects

A paper-trading app: real market structure, fake money, and quests that start simple and get harder. I built it end to end, ran it in production twice, and then tested it as if it were somebody else's product.

The story

A React front end over a Node and Express API and MySQL. Cron jobs pull prices from a market data API through the day and fill open orders against them, so a limit order placed in the morning executes on its own when the price arrives. Prices are cached in the database and only re-fetched once they are an hour old, or a day old for end-of-day history, because every call to the data provider costs money. Version one ran on a Linux server behind NGINX, version two on AWS, and being on the hook for uptime changed what I look for as a tester.

The test plan runs on one rule: effort goes where the risk is, scored as impact and likelihood separately. The failures worth the most effort are the ones that do not announce themselves, like a malformed order that is still accepted and moves the wrong money an hour later. The suite is Playwright over the interface and the API, against the whole stack in Docker Compose. The unit tests run in GitHub Actions on every push and gate main. Three defects are written up with steps and evidence. The worst was a reset never wrapped in a transaction, which I had read and called harmless until I reproduced it.

Akerna, compliance software

Akerna

2019 to 2022. Technical support, then QA analyst.

Partner Gateway

The product's API: live data access for clients' online stores and custom interfaces.

How
API testing in Postman, REST

I was the only tester on the API that clients' online stores and custom front ends ran on.

The story

Clients' stores and custom interfaces read the platform through the gateway. I tested it in Postman, request by request, and spent the rest of the QA year on manual and exploratory passes over the web application on its QA build.

Escalation ticket format

One standard shape for the bugs support hands to engineering.

Used for
Every issue support escalated to engineering

Writing it settled a running conflict between support and engineering over escalated bugs.

The story

Support wrote its escalations in the format from then on, so each one arrived carrying what engineering needed in order to take it.

A separate escalation was for a bug everyone had learned to work around. I added up its cost in support and engineering hours, about $50,000 a year, took the number to leadership, and the bug was fixed within a week.

Dire Fate, my studio

Dire Fate

2026 to now. One person, one game in development, and a rule on the front of its site: no grind, no punishment.

Cadence

Third-person action RPG in Unreal Engine 5.

Built with
Unreal Engine 5, C++
Configured in
Blueprints
Open
direfate.com

A third-person action RPG built to respect your time and reward your skill.

The story

C++ carries the systems and Blueprints sit above them as a thin configuration layer, so abilities, skills and stats are code with data on top rather than logic scattered through assets. The studio's rule is the same idea as everything above, pointed at play instead of work.

Getting in touch

Email is the best way to reach me, at reidhansell@gmail.com. I am glad to go into detail on any of this, including the parts I got wrong the first time.