Helbreath Empire
What it is
Helbreath is a 2D isometric online role-playing game from 2000: two rival cities, open-world player versus player, guilds, dungeons, crafting and large-scale events. Its original code was left behind long ago. I took it and, since 2012, have rewritten its client and its server into an engine of my own, and I run it as a live game at helbreath.co.
Today it exists as two editions that share one codebase:
- Helbreath Millennium is the live game. Players log in every day, so it carries the proven rules, and anything that would change what they see or what the server decides arrives behind a switch, off until it has been tested.
- Helbreath Empire is the next generation: every capability Millennium has, plus the newest technology I have built, with threads and networking moved off the frame so that play feels free of latency. It is the edition the rest of my work points towards.
Both games are in English, Spanish and Chinese, ship with an auto-updater (players download, administrators upload new builds and data), and are served by the helbreath.co website and account portal.
Why it matters to me
Technically, this is my most important project. Nothing else I have built covers as much ground: real-time graphics, networking across continents, a game server with a database behind it, security, tools for content and administration, and a testing system, all written and kept alive by me, for real players, over more than a decade. It is where I learned most of what I know about C++, and it is still where I apply it most seriously.
The scale is part of it. The history on record starts in 2017 and holds about 2,500 commits on Empire and 1,200 on Millennium, plus the shared libraries, and the two games together are well over half a million lines of C++. Most of that code is not the code I started with: it has been rewritten, sometimes more than once, as I learned better ways and as C++ itself moved from the old standards to C++23.
The engine
The client I inherited drew with DirectDraw and kept its whole world in a handful of very long functions. I rebuilt it as a complete in-house game engine:
- Rendering on OpenGL with GLSL shaders for dyes, glows, the day and night cycle and blending, while a DirectDraw renderer is kept for old machines. The player can switch renderer and sprite set from the settings and the game relaunches itself into the new one.
- A rewritten movement and animation engine: units, effects and spells move smoothly on a frame clock with delta time instead of jumping tile by tile, while the server's decisions stay exactly those of the reference build. Every change is measured against that reference, frame by frame where it draws.
- An in-house user interface engine with its own menus, widgets, scaling from 50 to 200 %, resizable windows, tooltips, styles and a map zoom up to 300 %.
- Audio through two engines, SFML and DirectSound, chosen at launch.
- Built-in media: screen recording inside the client through FFmpeg, with quality presets and a recordings manager; in-game Twitch streaming built into the client with GStreamer, so a player could go live without installing anything else; and VoIP, players talking to each other in game over an audio stream of its own.
- A chat translator, Discord integration and in-game notices complete the client.
Networking
Helbreath is played from many countries at once, so latency is a first-class problem. The game talks over UDP through my own build of ENet, with reliable channels, memory pools and speed-ups that keep the wire format unchanged; TCP serves the side channels.
- Networking off the frame: a dedicated network thread owns the socket. It wakes the moment data arrives, acknowledges and sends at once, and hands the game the packets in the same order and at the same point of the frame as before. A packet no longer waits for the screen's vertical sync to be answered. Players see it in the settings as "Networking Acceleration".
- Packets sized before runtime: every message fits one of four tiers (256 bytes, 4 KB, 64 KB, 1 MB) chosen at compile time from the types it carries, so sending never resizes a buffer, and an oversized packet is reported instead of silently growing.
- One packet language: each family of messages (guild, party, trade, admin and so on) is declared once with its fields, read and written by the same definitions on client and server.
- Tools to simulate lag and packet loss let me test the game as a player on the other side of the world would play it.
Server
The server runs the world: maps of up to 550 by 550 tiles, monsters and their spawns, combat formulas, guilds, parties, quests, crafting, an auction house, banks, events such as Capture the Flag and Deathmatch, achievements and the in-game economy.
- MySQL behind a database thread: queries run off the game thread and their replies come back in order, with logs written in batches. The schema moves forward by versioned migrations, close to two hundred of them on the live game.
- Live editing: administrators edit items, monsters, spells, maps, crafting and loot from inside the game, one editor at a time; every save is a versioned change that every connected client receives without a restart.
- Security at several levels: validation of everything a client sends, limits on floods and logins, an anti-tamper system that checks the client's files away from the frame, and alerts and inspection tools for administrators.
- Exceptions on any thread are written to a report with the stack and a dump, so a fault in production leads straight to its line.
Performance
Speed comes before looks in this codebase. Hot pixel loops are written in SSE2 assembly, each with a plain C++ twin that it is checked against; tables are built at compile time; draws are batched; animations, text and sprites are cached; and allocations are kept out of the frame. Map files are read with SIMD on the client and assembly on the server.
Every replacing path is a named switch: on the client, any optimisation can be turned off to run exactly the old code, and the server can run old and new side by side and log any difference. A benchmark compares builds with A/B runs on both renderers, and a colour test proves a change to a blend or a shader draws the same pixels as before.
Tools
- A sprite editor and a map editor of my own. The map editor uses the game's own renderer, so what is edited is exactly what is played, and it builds the walkable areas the server reads at boot.
- In-game administration: player inspection, roles, live config tables and the editors above, with a design browser to review every menu.
- Testerino, a test framework I wrote for these games: scripted routines start the server and one or more clients, play the scenario, check the state and record screenshots or video. There are more than 400 routines between the two games, at three depths, from a quick check to every option on several clients.
- An economy panel and Combat Lab: a web panel over snapshots of the live database to plan drops, currencies and releases, and a combat calculator that follows the server's formulas.
- A launcher and auto-updater serving both games, and the helbreath.co website for accounts, downloads and the shop.
Architecture: two games, one codebase
Keeping two games alive by hand would mean fixing every bug twice. Instead, both are built on two libraries I own:
- kazilib, my general C++ library: networking and packets, threads and job queues, a command console, audio, video recording, user interface pieces and the Testerino core. My other games use it too.
- hb_lib, the Helbreath library: sprites and their formats, maps, effects, combat and server rules, guilds, the launcher, anti-tamper, texts in every language. Where the two games must differ, the same code is kept with a Millennium and an Empire variant behind one name.
The work of moving the games onto that shared code follows a written plan: Millennium is the reference for behaviour, because real players prove it every day, and Empire is the reference for design. Each topic is analysed on both sides, the better version is moved into a library, and both games call it. Empire therefore opens on code that is already proven live, and what Empire invents reaches Millennium behind a switch, so the live server tests it first.
Timeline
- 2012: I start working on the Helbreath client and server.
- 2017: the current history begins, with the OpenGL renderer, higher resolutions, the database thread and the VoIP already in it.
- 2018: the map editor joins the client.
- 2023: kazilib is born, ImGui comes into the tools and the sprite editor is written.
- 2025: Empire grows its modern engine: shaders for dyes and colours, SFML, threads and the new interface.
- 2026: the servers return with Millennium live, hb_lib unites the two games, the network thread, the recorder, the anti-tamper and the movement engine standardisation land, and over 2,000 commits are made across both games in a single year.
Technologies
- C++23
- OpenGL / GLSL
- ENet (UDP)
- MySQL
- SFML
- ImGui
- FFmpeg
- kazilib
From the blog
A C++ beautiful syntax evolution with packet serialization
A Helbreath packet that once took three lines per field now takes one line per packet. Here is how I watched C++ get there: from pointer casts and hand-moved cursors to variadic templates, tuples, structured bindings and objects that serialize themselves.