Skip to content

A simple example of how to do networking using raylib and enet

License

Notifications You must be signed in to change notification settings

oblerion/raylib_networking_example

 
 

Repository files navigation

Raylib Networking Example

A simple example of how to do networking using raylib and enet.

About

This is a simple client/server networking demo that allows up to 8 players to connect to a server and move boxes around a fixed size area. It is written in Pure C using Raylib for graphics and window setup and the ZPL-C version of enet for networking.

When a client is started it will attempt to connect to the server (on localhost by default). Once conncected it will spawn a player with a peset color that the client can move around with the arrow keys. Different colored player objects for other clients will be shown in the window, updating with the respective client. Each client maintains a local simulation state that represents the gameplay state that it is aware of. The server also maintains a state of the last known positon of each connected player.

Notes

This example is not a robust networking system and is only intended as a simple example of how to setup a basic client/server system. Game networking is a very complex subject with many subtle nuances. Networking is not something that can just be attached to a single player game. A game needs to be built with networking in mind from the ground up. Even in this simple example, the core gameplay system is built into the networking layer, not the main application. Network games must be designed to take latency and data loss into account. If your game relies on every player having the exact same gamestate at the same time, then it will not work well in a network environment.

Different network setups are required for different kinds of games. For good networking you will need to research the best solution for game type. For action games a good place to start is the information released by Valve regarding how the game Half Life handled networking.

Building the Example

This example uses premake.

  1. Download Premake 5 for your platform https://premake.github.io/download
  2. Init raylib as a submodule (in the folder raylib)
  3. Run premake for your platform (A batch file for Visual Studio 2019 is included)
  4. Build the client and the server

Code Overview

Server

The server is entirely contained within the server.c file. It is very simple and just runs a loop looking for network events. When a player connects, disconnects or sends data, the server responds to the event, updates an internal player list, and sends out required updates to other players.

Client

The client is broken up into 3 files

  • main.c
  • networking.h
  • networking.c

main.c

The main file is where the normal raylib window is setup, input is checked and the game is drawn. Every frame the input is checked, the player is updated and the field is drawn with all players on it.

Due to conflicts between raylib and windows.h, it is not possible to include networking in the same source files as raylib. For this reason the gameplay and networking systems are put into a seperate file and accessed via an interface header.

networking.h

This is the interface between the network gameplay system and the main game application. It exists to keep raylib and windows files seperate. It contains defintions of all the functions and constants that are needed by the main game to run the game. Because raymath.h does not conflict with windows.h, the networking.h file includes raymath in order to use raylib structures, such as Vector2

networking.c

This is the implementation file for the network gameplay system. It uses enet to create a client connection to the server and keep the local simulation up to date. It sends out the local player's position 20 times a second using a server tick clock. This prevents the network from being overloaded with updates with every drawn frame and different update rates for players with different frame rates.

Network Commands

All network iformation is sent as commands. Commands are encoded into the network packet as a single byte, allowing up to 255 different commands. The command tells the receiving system what kind of data will be in the packet and what the requested action is.

Packet Data

In this example network data is packaged up in the native format for the sending computer. This means that computers with different byte ordering (https://en.wikipedia.org/wiki/Endianness) can not communicate with each other. A real game would encode all data into Network Byte Order on send and decode on receive.

Example Data Flow

Client -> Server Client startup and connects to server.

Server receives connection request and allocates a player ID for the new user If the server is full the new player is rejected.

Server -> Client Server sends Acccept messaage back to player with player ID Server sends Add Player message for all existing players to new player

Client receives accept message Client adds self to player list and marks connection as active Client gameplay loop starts polling for local player input

Client receives Add Player messages and updates local simulation state

Every frame on the client, input is polled and a new local player position is updated in the local simulation.

Client -> Server Every network tick (1/20th of a second), the local player's location is sent as an input update to the server.

Server -> Client When the server receiives an input update, it updates the server game state with the new position and sends an Update Player message to all players.

As clients receive update messages they set the local simulation to match the last known location of each remote player.

About

A simple example of how to do networking using raylib and enet

Topics

Resources

License

Stars

Watchers

Forks

Languages

  • C 98.9%
  • Lua 1.1%