Project Sulphur

Exposing multiplayer functionality

 
Joren Bolhuis

Introduction

This blog post is about exposing the functionality for multiplayer to the end-user (gameplay programmer) through our scripting API. Providing an networking system is one of the features of our engine. The end-user shouldn’t have to worry about packet sizes, TCP or UDP, or any other low-level questions, he should be able to focus on gameplay instead. The system uses a client-host model.

Entity system

Our engine makes use of an entity component system, so our multiplayer functionality needs to fit that model. The idea is that there are a ton of objects in a scene, but only the ones that are dynamic need to be synced. You would give these objects the “NetworkComponent”. So now not all things about the object we need to sync, maybe only the position or only the rotation. This can be manually set through the scripting API.

Next to syncing values of components, the user can create functions that can be invoked remotely, so called RPC (Remote Procedure Call). Thinks about an instantiating and explosion somewhere, or losing some hit-points. RPCs are created on the start and can be invoked by their identifier. Clients can send RPCs to the host only, and hosts can send to specific clients or all of them.

Global functions

Next to the functionality in the components, we have a bunch of global functions to connect / disconnect and create hosts or clients. This is different from the Unity engine, where they have this behaviour in a script. We don’t want to limit this functionality to a single component only, but making it globally accessible like input or time.

Flow

Below is a flow diagram that guides the end-user.

Flow diagram

By settings up the system this way, we give full control to the end-user, without having the struggle to know technical low-level details. It’s easily extendable and iterations should be quick.