← All work

Multiplayer game · Personal project · 2023–24

Kings

A small top-down building game in C++ where the host runs the server on its own thread and everyone else joins over UDP.

  • C++
  • SFML
  • ENet
  • cereal

Why I built it

My biggest motivation was The Cherno, a YouTube channel I watched in high school. Cherno loves building game engines and once worked at EA, and he really knows his stuff. Watching his videos, I thought: why can’t I do this too? So I started learning from them how a game engine is put together and what to watch out for, and then I started making this game.

The game logic isn’t fully finished yet, but it taught me how things work behind the scenes.

The game

You play as a square that keeps walking towards your mouse cursor, and you grow your kingdom by placing buildings: a Home raises your soldier capacity, a Mine earns money every second, and buildings can’t be placed too close to each other. One player picks Create Game to host, the others pick Join Game and add the host’s IP, and everyone sees each other’s movement and buildings in real time.

Architecture

  1. Every client Sends its moves, new buildings and chat. The host’s own client is just another client, over localhost.
  2. UDP
  3. Server thread An ENet host on port 7777, on its own std::thread. Keeps a copy of every player so late joiners get the current state.
  4. relay
  5. Other clients Receive the relayed packets and update their view of the world.
A listen server: whoever hosts runs the server in the background of their own game.
  • The host is a normal client. Create Game starts the server on a background thread, then connects to it over localhost like everyone else. So there is one client code path for all players, and the server thread only ever touches server state; drawing and input stay on the main thread.
  • Typed packets. Every message is a Packet<T> with a type (Join, Leave, Move, CreateHome, CreateMine, Chat), the sender’s id and its data. ENet handles the UDP connections and reliable delivery, and cereal binary archives turn packets, including the SFML types inside them, into bytes.
  • Scenes and layers. A scene is an ordered stack of layers, each with its own view and entities. Input travels from the top layer down and stops at the first entity that handles it; drawing goes from the bottom up. Pop-ups like the options menu are just a new layer on top, so they draw above the game and get input first.

Background

Kings started out on SFML’s own networking. In summer 2024 I wrote LearningEnet, a small terminal client and server, to learn ENet and cereal, then moved Kings over to them.

What’s still rough

Using singletons together with multithreading makes race conditions hard to fix.