I mount hardware to benchmark CatchChallenger server (x86 Geode LX800, pentium 3, MIPS32r2, ARMv6-8, …), 80M of semi-structured data, concept confirmed by benchmark. Binary en release mode, Linux ELF without XML (datapack loaded from cache): 1.3MB binary + 670KB RAM, 1.3MB+650KB of Flash/DAX + 20KB RAM when compiled for microcontroler (ESP32). Now work on MS-DOS/FreeDOS too.
CatchChallenger is a free MMORPG, written in C++/Qt, that holds more than 1000 players without lag on hardware from another era (i486, Geode LX800, MIPS, ARM, RISC-V…) and now ships with an Android client. Version 4 has just been released — come play, run a server, draw monsters, translate.
What’s new in version 4
- Responsive Android client. I play on PC but also on my phone, and have for years. The WebAssembly port is on its way; since WebSocket support is already there, it will run natively in the browser.
- A Qt server that no longer feels like the 2000s: a new, readable GUI, real live metrics, one-click startup.
- Updated libraries. External libs remain usable, but they are also bundled to make compilation easier and to cover the platforms that don’t provide them.
- Big cleanup: every feature that was little used, too invasive, or hard to maintain has been removed.
- v4 isn’t mature yet: there are still bugs and things to do — all contributions are welcome.
Why play (and tinker)
- A complete MMORPG: turn-based battles, capture, breeding, crafting, quests, reputation, plants, city capture (TvT), day/night events.
- Everything is free, everything is moddable. When you connect to a server, you download its entire datapack (but not the player data). You can run your own, improve it, republish it… and collect them all.
- It runs everywhere. The client has an “Open to LAN” mode worthy of the name, the server fits on a tiny VPS, and even on a microcontroller.
Datapack
The datapack has become much flatter. I removed the files that referenced other files… endlessly. If you want that kind of chaining, define your own format and compile it down to the final format. Map-related IDs are now local to each map (no more global IDs), which is much easier to manage: today it’s just 1 map + 1 XML.
The philosophy hasn’t changed: simple files, universal format.
The generator for the datapack’s HTML explorer has been ported to C++ to take advantage of the existing loaders and unify the code.
Internal architecture
Performance
- The internal structures no longer use pointers but indexes — it’s safer (the code can check bounds) and makes it possible to load the cache directly into memory.
- Loading the datapack from the binary cache is 100× faster than from the files.
- Clarification and optimization work on the code that propagates player movements to other players: it’s a critical path for both CPU and network.
- Little or no memory allocation in the critical paths.
- Internal binary database for simple servers (no cluster).
- io_uring is now supported to maximize performance on Linux.
Portability
- Switched from qmake to CMake to make it easier to compile the server in CLI on a VPS.
- The server also runs on ESP32 (under certain conditions: NOXML, datapack from cache, no compression) and fits in about 1300 KB of flash.
- Tested in depth (Valgrind, Clang sanitizers…) on MIPS, ARM, ARM64, RISC-V, i486/i586/i686.
- On a Geode LX800, the server takes more than 1000 stress bots without flinching.
Hygiene
- Major code restructuring to cleanly separate the generic server code, the Linux-specific code, and the Qt code.
- Lots of deduplicated variables and blocks.
- Removal of obsolete tools or ones that were only experiments.
- More documentation — sometimes about things not yet implemented (the docs map out the target).
- More than 24h of continuous testing to exercise all the code through the test cases, on my AMD Ryzen 9 7950X3D + 128GB of RAM.
How to contribute (where to start)
You don’t need to be a C++ developer to help:
- Translate a datapack: a text file (XML), that’s all.
- Create a new datapack: your own universe, your own monsters, your own maps.
- Draw a monster sprite, a tile, an item icon — the format is open and documented.
- Run a public server and report bugs under real-world conditions.
15 years later
This project started as a playground for learning and experimentation (compression, protocols, file formats, databases…). 400,000 lines of code later, 3 datacenters, routers, servers, UPSes and a hand-built electrical installation, it recently got a new boost thanks to using AI to catch up on everything that was left to do — notably writing the test cases and setting up a real feedback loop in Python. (On the other hand, AI vision to reproduce a Qt UI design from a reference doesn’t work at all, and I had to patch llama.cpp to run MoE models 4× larger than my RAM…)
Links
- Site, binaries and documentation: https://catchchallenger.herman-brule.com/