nbnet is a single header C (C99) library designed to implement client-server architecture, more precisely for online video games. The library is based on this great series of articles by Glenn Fiedler.
nbnet can target different protocols such as UDP or WebRTC through "drivers" (see below for more information).
The API is meant to be as straightforward as possible and relies on event polling, making it easy to integrate into a game loop.
Disclaimer: nbnet is in the early stages of its development and is, first and foremost, a learning project of mine as I explore online game development. If you are looking for a battle-tested, production-ready library, this is probably not the one.
You can see nbnet in action in this video.
If you want to discuss the library or need help, join the nbnet's discord server.
- Connection management
- Sending/Receiving both reliable ordered and unreliable ordered messages
- Sending/Receiving messages larger than the MTU through nbnet's message fragmentation system
- Bit-level serialization (for bandwidth optimization): integers (signed and unsigned), floats, booleans, and byte arrays
- Network conditions simulation: ping, jitter, packet loss, packet duplication, and out-of-order packets)
- Network statistics: ping, bandwidth (upload and download) and packet loss
- Web (WebRTC) support (both natively and through WASM using emscripten)
the native WebRTC driver relies on:
A fun action game that runs into a web browser, by Duncan Stead (@duncanstead86).
A WIP battle royal game playable in a web browser.
An online multiplayer RTS made for the Ludum Dare 49.
https://ldjam.com/events/ludum-dare/49/llamageddon
A little online tank game prototype.
A list of user-contributed bindings (they are not officially supported, so they may be outdated):
- nbnet-sunder by @ashn (Sunder is a modest systems programming language for Unix-like platforms)
nbnet does not directly implement any low-level "transport" code and relies on drivers.
A driver is a set of function definitions that live outside the nbnet header and provide a transport layer implementation for nbnet used to send and receive packets.
nbnet comes with three ready-to-use drivers:
- UDP: works with a single UDP socket, designed for desktop games
- WebRTC (WASM): works with a single unreliable/unordered data channel, implemented in JS using the emscripten API
- WebRTC (Native): works the same way as the WASM WebRTC driver but can be natively compiled
In exactly one of your source files do:
#define NBNET_IMPL
#include "nbnet.h"
Provide a driver implementation. For instance, for the UDP driver, just add:
#include "net_drivers/udp.h"
after including the nbnet header in the same source file where you defined NBNET_IMPL
.
nbnet does not provide any logging capabilities so you have to provide your own:
#define NBN_LogInfo(...) SomeLoggingFunction(__VA_ARGS__)
#define NBN_LogError(...) SomeLoggingFunction(__VA_ARGS__)
#define NBN_LogDebug(...) SomeLoggingFunction(__VA_ARGS__)
#define NBN_LogTrace(...) SomeLoggingFunction(__VA_ARGS__)
#define NBN_LogWarning(...) SomeLoggingFunction(__VA_ARGS__)
For memory management, nbnet uses malloc
, realloc
and free
. You can redefine them if needed:
#define NBN_Allocator malloc
#define NBN_Reallocator realloc
#define NBN_Deallocator free
All set, from here, I suggest you hop into the examples. If you are interested in WebRTC, go here.
nbnet comes with a primitive bit-level serialization system; but, if you want to use your own serialization solution, nbnet lets you send and receive raw byte arrays.
See the echo_bytes example.