Skip to main content
The cover image for "RVWP: Multiplayer Topdown Sandbox Game in C++"

RVWP: Multiplayer Topdown Sandbox Game in C++

Sidebar

For the last two years, I have been working on a [very ambitious game](https://rubenwardy.com/rvwp/). The game is a top-down sandbox with multiplayer support. I'm aiming towards a city-based game, where players can wander around a procedurally generated city. One of the main reasons I started creating this game is to learn about multiplayer networking at a low level - client-side prediction, server-side reconcilliation, cheat preventation, and reducing the visual effect of latency.

For the last two years, I have been working on a very ambitious game. The game is a top-down sandbox with multiplayer support. I’m aiming towards a city-based game, where players can wander around a procedurally generated city. One of the main reasons I started creating this game is to learn about multiplayer networking at a low level - client-side prediction, server-side reconcilliation, cheat preventation, and reducing the visual effect of latency.

A recent video demonstrating the current state of the game.
A recent video demonstrating the current state of the game.

The project is written in C++ using SFML. It’s the biggest project I’ve ever created, with 9,000 lines of code and 64 classes.

I decided to split the project into several milestones, each on iterating on the last and moving it towards a more complete game.

Features #

  • Infinite map
  • Multiplayer
  • Block placement
  • Multiple map z-levels (can go up and down stairs)
  • Doors and stairs
  • Player chat
  • Game controller support (only tested with Xbox 360 controller)
  • Inventory and dual wielding
  • Weapons (guns and melee)
  • Main menu

Milestone 1 - Foundations #

MS1 adds a foundation for future work, including: networking, MVC based architecture, basic entities, raytracer, materials to specify how to draw something, collison, and loads more.

I started off by writing the basic world model and spatial paritioning. I then wrote the client/server handshake.

Just some basic code with socket communication.
Just some basic code with socket communication.

After that, I added rendering so I could see the world, and start adding actual game features.

The first ever screenshot, just after adding rendering.
The first ever screenshot, just after adding rendering.

The next step is to add player movement and entity synchronisation, and then node placement:

Player movement and node placement.
Player movement and node placement.

I also decided to switch to Kenney’s texture pack during this time.

Switched to using one of Kenney's texture packs.
Switched to using one of Kenney's texture packs.

Milestone 2 and 3 - Doors, Entity Damage, and Interaction #

Adds the ability to open doors, highlight entities, and damage them.

Milestone 4 - GUI #

Next I needed a way to interact with the inventory, so I added an MVC framework to switch between windows and the game, and an inventory window to use the inventory.

Inventory GUI added, and the inv item position synchronisation.
Inventory GUI added, and the inv item position synchronisation.

I also added the ability for entities and players to die, and for players to be respawned.

Milestone 5 - Weapons and Tool Specs #

I allowed items to provide a ‘tool spec’. A tool spec is a struct which specifies what functionalities an item has - for example, whether it can damage tiles and entities, whether it can shoot bullets, and how much damage it gives.

Milestone 6 - Playability #

This was quite a big milestone. I added the following features:

  • Support for multiple Z-levels (ie: going up and down stairs).
  • Infinite map by adding chunk loading, and keeping track of whether a player knows about a chunk.
  • A main menu with the ability to type in a server URL and port.
  • Chat.
  • Xbox controller support.
  • Visual bullets using particles.
Controller support.
Controller support.

Where now? #

Since the last milestone, I have been working on increasing code coverage. The world logic is now at 97% covered, however the client (rendering, input, packet handling) and the server (packet handling, profiles, interaction logic) still need tests.

The client and server are both designed in an MVP style, which means that it shouldn’t be too hard to isolate and test them using dependency injection, which is something I’d like to get around to.

As for actual game progress, I’d like to work on making the server more scalable. I’m thinking of implementing a distributed architecture with chunk workers - processes that assigned to be the “truth” of a group of chunks, to update them based on logic, and to respond to any requests relating to them.

Another thing I need to investigate is lighting, as it’s good example of an algorithm that needs to propogate through chunk boundaries and so will help with making sure my workers can handle it.

Part of a series of blog posts about my game, RVWP

rubenwardy's profile picture, the letter R

Hi, I'm Andrew Ward. I'm a software developer, an open source maintainer, and a graduate from the University of Bristol. I’m a core developer for Luanti, an open source voxel game engine.

Comments

Leave comment

Shown publicly next to your comment. Leave blank to show as "Anonymous".
Optional, to notify you if rubenwardy replies. Not shown publicly.
Max 1800 characters. You may use plain text, HTML, or Markdown.