Categories
Programming

Building a MUD – Part 1

This is part 1 of N parts where I'll discuss my adventures in building a MUD (Multi-User Dungeon) in C++. I've always wanted to write games but never got around to it for a number of reasons I'll discuss over time. So when I decided to finally try my hand at creating one, I chose the language and tools I'm most familiar with, and which I use in my day-job.

You might be wondering why I chose a MUD over a platformer, or a shooter, or a mobile game of some kind. The reason is because I'm primarily a backend developer and a MUD seems more or less like a backend project to me. I have a buddy who's a JavaScript/3D expert and I figure possibly one day I can enhance the protocol to drive the MUD with a bit more flair down the road. It's a bit early for that.

I'm also choosing to make the repo public as I do this for two main reasons:

  • I'm chatting about my progress and I want to send code links to my friends and don't want to bother with adding them as special collaborators
  • I invite comments and criticism on the way I do things because this is a learning project above all else

The Stack

First, the repo is here: https://github.com/NickCody/cpp-game. Be warned, the repo is not clean, as it contains numerous little code projects tucked away in various directories as I played around with ncurses, graph algorithms, the game of life, etc. If you poke around, you may be surprised at how many little things are in there.

Visual Studio Code is the primary tool, and more specifically I started with one of their stock C++ dev containers (described here). I've heavily modified the container's Dockerfile to include the latest tools I could, among these are:

  • Debian Bullseye
  • gcc 10.2 (for C++ 20 compatibility)
  • vim, graphviz, ninja, clang-format, and a few other goodies
  • The CAF Actor Framework (more on this below)
  • Bazel for builds
  • Yaml for configuration
  • Redis as the primary store for user/game data
  • Google Cloud SDK for "production" deployments

Of these, I feel most people might shake their head at why I'm using an actor library for my C++ code. I'm a huge fan of the actor model having worked with Akka on Scala for years. The model makes sense to me and I wanted to learn more about this library for C++. I'll be speaking about it in detail in coming posts.

Home Setup

At home, I have my Windows desktop on which I have Docker Desktop and WSL2 installed. I don't find myself in WSL2 much, not directly, but the repo lives there and I spawn vscode devcontainer from WSL2.

For edit/compile/run cycles, I run the MUD on my desktop. Redis is running on a home Linux server I have tucked under my desk. It's only a Intel Core i5-3570K CPU @ 3.40GHz with 32GB RAM. Its plenty of power for what I need. This machine is my "QA" environment, where I can test my deploy scripts. I have a version running in the cloud, too, using Google's Cloud SDK.

Why Redis?

There may be better choices for my persistent store, since Redis is primarily a fast in-memory data structure storage, with persistence capabilities. I was curious to learn it so I figure if it turns out to not be the right choice, I'll eventually figure out why and then I'll have learned something.

For now, it's pretty amazing. Fast, lean, and no bullshit. I'm using hiredis, which is a bare-bones simple thin wrapper based on C. I considered one of the many "modern" C++ wrappers, but I felt like I could write my own wrapper and use my own wrapper as an abstraction around the storage engine that might help me move off Redis down the road if I eventually decide it's not the right storage engine for this project.

Conclusion

That's all for now. I'm not sure what the topic of the next post will be, as there are dozens of topics to discuss, but thanks for reading.