Old School Ops
GoMMO

The GoMMO framework

Every server on this site is a Go program built on one shared core: accounts, databases, networking and scripting. Each game adds its own protocol and content on top, and speaks the original client byte for byte. A fix to the core reaches every game, and a game added later starts with all of it in place.

11games
4families
2.1Mlines of Go
20,330tests
2,844commits
How a server is put togetherpick a layer

Content

What a world is made of, kept outside the program so it can change without a rebuild.

  • Game data. Gate to Heavens keeps canonical JSON that gthdata validates and builds into the server's and the client's files. Each RF version ships a static content database built from that client's own tables. World of Kung Fu and DragonSoul read the original data files.
  • Lua scripts. .lua files in the server's scripts folder: RF's instanced dungeons are 45 of them per version.
  • Settings. One settings.cfg beside the server.

Game

Everything that belongs to one version of one game lives in its own tree, games/<game>.

  • One process per game. A single gameserver serves every world of its game, and terminates the client's connections itself.
  • Game logic and opcodes. Message handlers, struct layouts and formulas are per game, never shared, because the client changed between versions.
  • A control panel. Each game has a webserver beside it: RF trees build theirs from the shared games/gameweb, Gate to Heavens has its own.
  • Isolation. verify-split proves a game's binary holds no code from any other game.

Family

Versions of one title share what their clients have in common.

  • The wire. One games/*wire package per family: packet framing, ciphers and the codecs every message body is built from.
  • Scripting verbs. games/rfscript knows dungeons, missions and monsters; games/gthscript knows NPC conversations.
  • Launchers. Gate to Heavens, RF and DragonSoul have launchers of their own, and a single rflauncher serves every RF episode through games/launchwire.
  • Optional modules. games/rfmodule holds subsystems several RF trees opt into, such as the seasonal reset.

Core

Game-neutral packages under pkg/. None of them knows what a monster or a packet is.

  • pkg/account, pkg/auth. One accounts database shared by every game on a server, email login, argon2id hashing, per-game staff levels and bans that apply everywhere.
  • pkg/osoauth. Lets a Gate to Heavens or RF server sign players in with their oldschoolops.com account, using a key issued to that server.
  • pkg/database. SQLite by default and MySQL for production from one schema; the SQLite form is derived at run time, and a missing database is created on first start.
  • pkg/script. The sandboxed Lua host, with instruction and time budgets.
  • pkg/tcpnet, pkg/memnet. The listeners, and an in-memory network the tests run whole servers on.
What happens to one message
  1. 1

    The original client

    Sends exactly what it sent in its day. Nothing in it is changed.

  2. 2

    The family wire

    Reads the frame, removes the cipher and decodes the body into a Go struct.

  3. 3

    The game's handler

    Applies that game's rules: combat, items, quests, the world state.

  4. 4

    The core

    Accounts and characters are saved through pkg/database, to SQLite or MySQL.

  5. 5

    The reply

    Encoded back into the client's own format, byte for byte.

Four families, four wiresAll games

DragonSoul

Package
games/dswire
Transport
TCP, two connections
Cipher
RC5 and XOR4, zlib-compressed
Shared by every game
  • Accounts, staff levels and bans
  • SQLite and MySQL from one schema
  • The Lua host and its sandbox
  • Listeners, update checks and settings
  • Build, release and deploy scripts
Kept by each game
  • Opcodes and struct layouts
  • Game logic and formulas
  • Content and data files
  • Its control panel's game pages
  • Its version number and changelog
Every release is gated

Rule tests

One rule per test, each on its own small server in memory, so a result never depends on another test's traffic.

Live-world soak

One full-content server under a crowd of bots: no panics, no error logs, no leaked goroutines, and a watchdog client still gets in.

Build isolation

verify-split proves each game's binary holds no other game's code.

The registry

One table names every game's ports, databases and binaries, and every script reads it.

Top xp sources

How xp works
Loading…

Open the full search page