I've been working on ANAVIR, my RPG project, and I've reached the point where having everything running on one server isn't going to cut it anymore.
Sure, one server is easy. One database, one process handling everything, and life is reasonably simple. Until you start adding more players, more worlds, more stuff happening at once, and suddenly that nice simple setup becomes a rather large pile of things that can break together.
I've spent enough years dealing with infrastructure to know where that road leads. Usually somewhere unpleasant, at an inconvenient hour.
So I'm splitting things up.
I want a central system that handles accounts, authentication, server management, updates, monitoring, and the other boring but necessary stuff. Then I want independent game servers that run their own worlds, maintain their own data, and don't need to ask permission from the mothership every time somebody swings a sword at a goblin.
A world server should be able to run on a machine in my house, a rented server somewhere, or a host on the other side of the planet. As long as it can securely communicate with the central system, it should work.
I've put together eight diagrams showing how I'm approaching this. They're intentionally high-level. I'm not trying to document every API call, database table, or bit of network traffic here. I just want to show how the pieces fit together and, more importantly, where the responsibilities belong.
01 · System map
The Big Picture
At the top is the central server. That's where players log in, where worlds register themselves, where the admin tools live, and where I can see what's going on across the whole environment.
The website uses the central API. Downloads and releases live in object storage. Messaging and coordination are handled separately.
Then there are the game servers.
Each one runs its own world. Its own maps, creatures, players, economy, and everything else that makes the game a game.
When somebody logs in and selects a world, their game client connects directly to that world server. The central server doesn't need to sit between the player and the game processing every movement, spell, or interaction.
That would be a pretty efficient way to build a bottleneck for no good reason.
I want one place to manage things, not one place that has to do everything.
02 · Authority
Who Owns What?
This is probably the part I care about most.
I've seen what happens when multiple systems think they're in charge of the same data. It works great right up until it doesn't, and then everybody gets to spend their weekend figuring out which database is telling the truth.
I'm trying to avoid that.
The central system owns player accounts, credentials, world registrations, and global configuration.
The individual worlds own their characters, inventories, quests, economies, maps, and game state.
If you pick up a rusty sword in World A, World A is responsible for knowing you have that rusty sword. The central server doesn't need to know about it unless there's some legitimate reason to expose that information.
And World B certainly shouldn't be wandering into World A's database and changing things.
One owner for each piece of data. Clear boundaries. Fewer opportunities for something to turn into a complete mess.
There will eventually be things that need to move between those boundaries. That's where explicit APIs and controlled transfers come in.
Not shared databases and crossed fingers.
03 · Player flow
Logging In and Getting Into a World
I don't want players managing separate accounts for every game server. That's ridiculous.
You create an account, log in, and get a list of available worlds.
Pick one, and the central server checks whether you're allowed to connect. If everything looks good, it issues a short-lived connection ticket.
The client takes that ticket to the world server, the world validates it, and you're in.
From that point on, you're talking directly to the game server.
Movement, combat, NPCs, inventory, quests, and all the other things happening while you play stay between the client and that world.
The central system handles getting you through the door. It doesn't need to follow you around the dungeon.
Besides reducing unnecessary traffic, this also means different worlds can run on different hardware, in different places, without forcing gameplay through one central machine.
04 · Trust lifecycle
Adding New Worlds Without Losing My Mind
If this works the way I want, adding a new world should be relatively painless.
Bring up a new server, give it the information it needs to contact the central system, and enroll it.
Of course, I'm not letting random machines announce themselves as legitimate game servers. That's an excellent way to create a problem you could have avoided.
An administrator has to authorize the new world. The server generates its own keys and gets credentials from the central system.
Once enrolled, it has an identity, can get its configuration, report its health, and receive whatever management instructions it's authorized to handle.
I also want to be able to rotate credentials or kick a compromised server out without having to rebuild everything.
The important thing here is that a world server can live somewhere remote without needing the keys to the kingdom.
It should have exactly the access it needs. No more.
05 · Control flow
Managing Everything From One Place
I really don't want to SSH into fifteen different machines every time I need to do something.
I've done enough of that in my life.
The plan is to have a central administrative interface where I can see all the worlds, who's connected, what version they're running, whether they're healthy, and what needs attention.
From there I should be able to put a world into maintenance, change configuration, issue approved administrative commands, and handle the routine work of keeping everything running.
That doesn't mean giving the central system an unrestricted shell on every host.
I want defined commands, proper authorization, logs, acknowledgments, and a record of who did what.
The individual world server still decides how to safely apply an operation to its game state.
If I tell a world to start maintenance, it should know how to stop new connections, deal with existing players, save its state, and shut down properly.
Not just have some remote script come along and murder the process.
There's a difference between remote management and remote recklessness.
06 · Release flow
Updates, Releases, and the Joy of Breaking Things
Game servers need updates. Sometimes frequently.
I'm not manually uploading files to a bunch of servers and hoping I got the right versions everywhere.
The central system manages approved releases, and the world servers download the appropriate packages from object storage.
Packages get verified before installation. Updates can be staged, health checks run, and servers can be brought in and out of maintenance in a controlled way.
I also want rollback.
If I deploy something and a server immediately falls over, I should be able to return to the previous working version without turning it into a three-hour archaeological expedition.
Database changes make this more interesting. You can't always roll a database backward just because you rolled the application backward.
So compatible schema changes, migration planning, and recovery procedures have to be part of the release process.
This stuff isn't particularly exciting compared to building an entire fantasy world.
But it becomes very exciting when a bad release takes your fantasy world offline.
I'd rather have the boring solution ready before that happens.
07 · Data safety
Backups, Because Players Tend to Like Their Stuff
Imagine somebody spending six months building a character, collecting gear, completing quests, and generally wasting a perfectly respectable amount of their life in your game.
Then the server dies and you tell them their character is gone.
Yeah. No.
Every world owns its own database, and that means every world needs a reliable way to back it up.
The central system coordinates backups, but the world server is responsible for producing a consistent copy of its own data.
That backup gets encrypted, moved to appropriate storage, and checked.
And I don't consider a backup useful just because some scheduled task says it completed successfully.
You have to be able to restore it.
The restoration process I'm designing brings the data back into a separate database first. Validate it, check that it's usable, and only then consider replacing the active world data.
I also want routine restore testing. A backup nobody has ever restored is more of a comforting theory than a recovery plan.
Players put time into these worlds. Protecting that work is part of running the game.
08 · Resilience
What Happens When Something Breaks?
Because something will break.
The internet will have a bad day. A central service will restart. A host will die. Somebody will deploy something stupid.
Possibly me.
The architecture needs to account for that without treating every little failure like the end of civilization.
If the central authentication service becomes temporarily unavailable, players who are already connected to healthy worlds should generally be able to keep playing.
The world already knows who they are, and it has enough local information to maintain the existing session.
New logins might have to wait. Global services may not work. Administrative operations that require central authorization may be unavailable.
That's acceptable.
What's not acceptable is letting a connectivity problem turn into a security bypass or corrupt the game state.
The same thinking applies to updates, backups, recovery, and planned maintenance.
I want each component to fail in a way that's understandable and recoverable.
A broken website shouldn't automatically kill an active game world. One crashed world shouldn't take down all the others. And a disconnected server shouldn't start making up its own security rules because it can't reach home.
Distributed systems are going to fail in interesting ways whether you plan for them or not.
I'd prefer to do some planning.
The design boundaries
Why Am I Doing All This?
It's a fair question.
For a small game, this is probably more architecture than strictly necessary.
I could run everything on one reasonably powerful server, keep it simple, and move on to making more monsters, quests, and questionable NPC dialogue.
But that's not really what I'm trying to build.
I want ANAVIR to support large, independent worlds. I want to be able to put those worlds on different machines, give them different resources, move them around, and eventually support a much larger game environment without having to rip the entire backend apart.
I also want the game infrastructure to be something I can operate without turning it into a second full-time job.
And frankly, I enjoy building this stuff.
I've spent a good chunk of my career working on distributed systems, security, infrastructure, and figuring out how to make complicated things behave themselves. Applying those lessons to a game is actually pretty entertaining.
There are three boundaries I keep coming back to:
- Identity: Who are you, and what are you allowed to do?
- Management: What exists, where is it running, and how do I control it?
- The world: What's happening in the game, and who's responsible for keeping it consistent?
I don't want those responsibilities tangled together.
Separating them doesn't magically make the system simple. Distributed infrastructure has plenty of complexity of its own. But at least that complexity has somewhere sensible to live.
And when something goes wrong, I have a better chance of knowing where to look.
Work in progress
Where Things Stand
This is still a work in progress.
The diagrams represent the architecture I'm building toward, not a claim that every service is finished, tested, and running in production.
I'm working through the client, central services, world servers, and the connections between them. Some pieces will change. Some will probably get thrown away and rebuilt when I discover a better approach.
That's normal.
I tend to work from the outside in. Draw the big picture, figure out who owns what, identify the trust boundaries, think through what happens when things fail, and then start building.
That's why I make diagrams.
It's a lot easier to erase a box on a whiteboard than explain to a bunch of players why their characters have disappeared.
Besides, the whole point is to build a game where people can explore worlds, fight monsters, find treasure, and have fun.
They shouldn't have to care about the infrastructure underneath it.
If I've done my job properly, they won't.
And I won't have to spend every weekend fixing it.