🚀 Making multi-player gamedev simpler since 2017

Overview
librg
build status version discord license

Making multi-player gamedev simpler since 2017. Single-header cross-platform world replication in pure C99.
Built with love using zpl • Brought to you by @inlife, @zaklaus and other contributors

Introduction

librg is a lightweight library that serves as a middleware between data-transferring libraries (networking, file-streaming, etc.) and core application/game logic.

Main responsibilities of the library include:

  • entity tracking (tracks which entity belongs to what world, and what states do they have)
  • owner tracking (tracks which participant owns what entity)
  • area of interest management (controls what can and cannot be seen a participant)
  • world replication (re-creates a limited representation in a destination world of what is considered visible to a participant in the source world)

The library was born to solve complexities of setting up and managing the flow of multi-player games and dedicated game servers. It came a long way of stripping out things that were non-essential, slowly sculpting into its current form, which you are able to see and use today.

Features

  • cross-platform support
  • lightweight, single-header
  • supports 2d/3d worlds of various sizes
  • compile- and run-time configurable
  • written in C99 (portability reasons)
  • no external dependencies
  • built-in unit test coverage

F.A.Q.

  1. Is this a networking library?

    • Not really, no. It is intended to be used with netwoking in mind, but it does not have any networking capabilities on its own.
  2. Can I use any networking library with it?

    • Yes. All you need is an ability to read data to and from the buffer, and most libraries do support that. Theoretically it can be anything as low level as pure UDP, and up to Websocket/WebRTC.
  3. The repository contains a bunch of *.h and *.c files, and yet you suggest it is a single-header library, how is that possible?

    • The library is spread into multiple files so it is easier to work with it while developing, however each time a new release is created, a "bundled" version of the header file is created and pushed directly to the releases page.
  4. Does librg offer an entity system?

    • No, the library does not manage nor actually create its own entities, it rather expects you to provide your own entity/object handle to attach some internal data onto it, which in context of the library is called "tracking".
  5. How do I pack data, do you provide methods for that?

    • No, the library does not provide any data-packing/serialization methods. It's recommended you use some existing library for that (protobuf, flatbuffers, msgpack, etc.), or make your own implementation.
  6. I see you mention chunks, does it mean my game/app should be chunk-based?

    • No. Chunks are only used internally, to artificially divide the space of the world on statically sized squares/cubes so that querying would work efficiently. Even if your game does use chunks, their amount/sizes/offsets are not required to much and be the same.

Documentation

To read detailed documentation about the library, see examples and quick start guide, please visit our documentation page.

Additionally you can check code/apps folder for actual code examples.

Illustration

Here is a simple illustration that attempts to describe how the library works on a simple 2d world of 4x4 chunks. For a 3d world of bigger size everything would work in a very similar way, just in 3 dimensions.

librg illustration
(click on the image to view full-size)

Migration

If you've used the library before version v6.0.0, it is recommended to read the migration guide located here.

Support

We are testing the library for various platforms. This table provides some sort of description for compatibility. If you have tested it, and your result is different from the one in the table, please feel free to describe the issue in the issues.

Platform / Result Windows macOS Linux iOS Android Raspberry Pi OpenBSD FreeBSD Emscripten
clang clang gcc, clang gcc, clang gcc, clang
msvc, mingw gcc, clang gcc, clang emcc

Legend:

  • - Library was not tested on this platform/compiler yet
  • - Library successfully compiles and all tests are executed properly

Development

If you wish to contribute, add new feature, optimizations, or overall improvements, here are the instructions on how to do that:

  1. Clone the repo, f.e.: git clone https://github.com/zpl-c/librg.git
  2. Run make to build all projects, and verify everything works
  3. Develop a feature, add tests for it in code/tests/
  4. And eventually run make test again to check

In case you are working from Windows, and/or are not able to use make, you can also use built-in cmake config file to generate a Visual Studio solution, to do that:

  1. mkdir build
  2. cd build
  3. cmake ../misc -G"Visual Studio 16 2019" (or any configuration you have)
  4. cmake --open . (opens VS with the solution)
  5. And repeat steps from above
Issues
  • How to properly install and add this lib to C++ project?

    How to properly install and add this lib to C++ project?

    The documentation says just to include "librg.h". But when I do just that and add this to my c++ project I got error:

    librg/code/source/query.c: In function ‘int32_t librg_world_fetch_chunk(librg_world*, librg_chunk, int64_t*, size_t*)’:
    error: taking address of temporary array
        39 |    return librg_world_fetch_chunkarray(world, (librg_chunk[]){chunk}, 1, entity_ids, entity_amount);
          |                                                                                                  ^~~~~~~
    

    What I need to do to inlude library in c++ project? Maybe somehow link library like -lrg. Maybe I need add include some directories -I./librg/code. Or maybe I need to install somehow compiled lib. I use Ubuntu linux.

    bug 
    opened by JustVic 7
  • librg_network_stop on server doesn't trigger disconnect event on clients

    librg_network_stop on server doesn't trigger disconnect event on clients

    Hello,

    I could be missing something, but when I shutdown my server, none of the connected clients receive any event; they all just timeout. Looking at librg_network_stop, there doesn't appear to be anything to handle currently connected clients. They just get deleted with the zpl table.

    Would be happy to contribute here, but not sure if I am missing something.

    Thanks.

    bug 
    opened by eddiejames 7
  • Your are using eNet code which does not exist

    Your are using eNet code which does not exist

    This not exist in eNet code (ENET_EVENT_TYPE_DISCONNECT_TIMEOUT)

    case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT: {                                                                                                                                                                                 
     
    

    and this function :

    enet_packet_create_offset
    

    using latest version of eNet from github

    opened by meiry 5
  • Disconnected client entities trigger entity update once

    Disconnected client entities trigger entity update once

    When a client disconnects (or timeouts, doesn't matter) from the server there is one entity update event triggered after the disconnect event.

    ...
    Update entity 1 for client 1773685128
    Update entity 0 for client 647576079
    Update entity 1 for client 1773685128
    Update entity 0 for client 647576079
    Update entity 1 for client 1773685128
    Update entity 0 for client 647576079
    Update entity 1 for client 1773685128
    Update entity 0 for client 647576079
    client 647576079 disconnected
    Update entity 1 for client 1773685128
    Update entity 0 for client 647576079
    
    opened by markatk 4
  • How to generate different ID for different clients?

    How to generate different ID for different clients?

    Just a question. In example-enet.c server and all clients in one file and ID's generation is easy:

            for (int i = 0; i < MAX_CLIENTS; ++i) {
                client_update(i, clients[i]);
            }
    

    in that case i is ID. But in real case clients on different computers don't know about each other and therefore can't generate id's by itself. But to recieve(read) something or to send(write) something it needs an ID as I understand.

       librg_world_read(
            world,
            ID,
            (char *)event.packet->data,
            event.packet->dataLength,
            NULL
        );
    
        librg_world_write(
            world,
            ID,
            buffer,
            &buffer_length,
            NULL
        );
    

    I assume It's somehow must be generation on server. How to generate different ID for different clients? Maybe It's silly question and I don't understand something...

    opened by JustVic 3
  • Noob question: How does a single header library not cause mutiple symbol definitions?

    Noob question: How does a single header library not cause mutiple symbol definitions?

    Please excuse my naivety but I've never encountered single-header libraries till now.

    I think this is a very nice library but I am rather confused about how I would go about using it.

    I understand that if all the functions are 'inline' then there really isn't any true symbol definitions that could collide when linking multiple object files... But looking at the source of librg I am seeing functions which do not have any inline keyword specified anywhere, for example:

    u64 librg_event_add(librg_ctx *ctx, u64 id, librg_event_cb callback) {
            librg_assert(ctx);
            librg_event_block *block = librg_event_pool_get(&ctx->events, id);
    
            if (!block) {
                librg_event_block arr;
                zpl_array_init(arr, ctx->allocator);
                librg_event_pool_set(&ctx->events, id, arr);
                block = librg_event_pool_get(&ctx->events, id);
            }
    
            u64 offset = zpl_array_count(block);
            zpl_array_append(*block, callback);
            return offset;
    }
    

    I assume that there must be some non-conventional use of this header necessary to get it working otherwise if I were to include this file in multiple C files and then link them together I would get linker errors for multiple symbol definitions with the same name, wouldn't I?

    Sorry if this is the wrong place to ask this question but I wasn't sure where else would be appropriate.

    Also, why the #if 1 statements wrapping sections of code? Those seem pointless and I can't grasp what their purpose would be, other than to manually toggle the compilation of specific sections... But wouldn't that be better achieved by using actual #ifdef SOME_MACRO switches where all the switches can be listed at the top of the file for ease of toggling?

    opened by Dan782 3
  • Ownership information in reader OnCreate event

    Ownership information in reader OnCreate event

    In clients librg_event_owner_get(w, e) in client_read_create or client_read_update owner_id always the same for all entities_id. I tested it in example-enet.c. Maybe it work like expected, but in that case client can't get real owner of entity... Maybe it's more related with enet than librg.

    feature 
    opened by JustVic 2
  • Can't get position data when entity created.

    Can't get position data when entity created.

    Can't get position data when entity created. In example example-enet.c I try to get position in client_read_create function but librg_event_size_get always returns actual_length 0.

    librg_event_set(world, LIBRG_READ_CREATE, client_read_create);

    int32_t client_read_create(librg_world *w, librg_event *e) {
        int64_t owner_id = librg_event_owner_get(w, e);
        int64_t entity_id = librg_event_entity_get(w, e);
        printf("[client] An entity %d was created for owner: %d\n", (int)entity_id, (int)owner_id);
       
        size_t actual_length = librg_event_size_get(w, e);
        printf("[client] actual_length = %zu", actual_length);
        if (actual_length != sizeof(vec3)) return 0;
       
        char *buffer = librg_event_buffer_get(w, e);
        
        vec3 position = {0};
        memcpy(&position, buffer, actual_length);
    
        return 0;
    }
    
    
    opened by JustVic 2
  • Does not work using C++

    Does not work using C++

    I'd like to use this library in my C++ project but due to some conversions that are only valid in C it won't compile:

    ext/librg/librg.h|19756 col 20| error: cannot initialize a variable of type 'librg_world_t *' with an rvalue of type 'void *'
    ||     librg_world_t *wld = LIBRG_MEM_ALLOC(sizeof(librg_world_t));
    ||                    ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ext/librg/librg.h|19918 col 45| error: cannot initialize return object of type 'librg_event_type' with an rvalue of type 'int'
    ||     LIBRG_ASSERT(event); if (!event) return LIBRG_EVENT_INVALID;
    ||                                             ^~~~~~~~~~~~~~~~~~~
    ext/librg/librg.h|2177 col 41| note: expanded from macro 'LIBRG_EVENT_INVALID'
    || #define LIBRG_EVENT_INVALID             (-0x0006)
    ||                                         ^~~~~~~~~
    ext/librg/librg.h|19921 col 12| error: cannot initialize return object of type 'librg_event_type' with an lvalue of type 'uint8_t' (aka 'unsigned char')
    ||     return e->type;
    ||            ^~~~~~~
    ext/librg/librg.h|20656 col 14| error: cannot initialize a variable of type 'int64_t *' (aka 'long *') with an rvalue of type 'void *'
    ||     int64_t *results = LIBRG_MEM_ALLOC(LIBRG_WORLDWRITE_MAXQUERY * sizeof(int64_t));
    ||              ^         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    || 4 errors generated.
    
    opened by sarahkittyy 2
  • Possible WebRTC support?

    Possible WebRTC support?

    A bit of a big thing, but if it can be implemented it will truely make librg cross-platform.

    There is the Intel WebRTC Datachannel Microstack, a C99 little library which is conveniently also licensed under Apache 2.0: https://github.com/HumbleNet/webrtc?files=1

    And Humblenet has an example of a shared ABI between it and browser's RTC implementation: https://github.com/HumbleNet/HumbleNet/blob/master/src/humblenet/src/libwebrtc.h

    It's also a little similar to Enet with reliable/unreliable packets and peer to peer nature.

    opened by LiHe93 2
  • LIBRG_CONNECTION_ACCEPT payload

    LIBRG_CONNECTION_ACCEPT payload

    When the server accepts a client connection, it would be nice for the server to be able to send data to the client with the LIBRG_CONNECTION_ACCEPT event for initial setup (for example to set the initial position or health).

    opened by markatk 2
Releases(v7.0.1)
Owner
ZPL | Your C11 Powerkit
ZPL is a collection of single-file header-only libraries for C and C++.
ZPL | Your C11 Powerkit
FFVideo - an example FFmpeg lib, and wxWidgets Player with video filters and face detection

An example FFmpeg lib, and wxWidgets Player application with video filters and face detection, it is a no-audio video player intended for video experiments and developers learning how to code media applications.

Blake Senftner 20 Mar 26, 2022
A multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input

GLFW Introduction GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan application development. It provides a simple, platf

GLFW 9.4k Aug 6, 2022
Open 3D Engine (O3DE) is an Apache 2.0-licensed multi-platform AAA Open 3D Engine

Open 3D Engine (O3DE) is an Apache 2.0-licensed multi-platform 3D engine that enables developers and content creators to build AAA games, cinema-quality 3D worlds, and high-fidelity simulations without any fees or commercial obligations.

O3DE 5.1k Jul 30, 2022
Bullet Physics SDK: real-time collision detection and multi-physics simulation for VR, games, visual effects, robotics, machine learning etc.

Bullet Physics SDK: real-time collision detection and multi-physics simulation for VR, games, visual effects, robotics, machine learning etc.

Bullet Physics SDK 9.5k Jul 27, 2022
A multi core friendly rigid body physics and collision detection library suitable for games and VR applications.

A multi core friendly rigid body physics and collision detection library suitable for games and VR applications.

null 2k Aug 7, 2022
Multi-Joint dynamics with Contact. A general purpose physics simulator.

Multi-Joint dynamics with Contact. A general purpose physics simulator.

DeepMind 4.6k Jul 28, 2022
🚀 Making multi-player gamedev simpler since 2017

Making multi-player gamedev simpler since 2017. Single-header cross-platform world replication in pure C99. Built with love using zpl • Brought to you

ZPL | Your C11 Powerkit 972 Jul 29, 2022
GAMEDEV - Lightweight crash reporter for Unreal Engine

Mayday Mayday is a lightweight crash reporter for Unreal Engine games that uploads the crash context and minidump to an HTTP(S) server of your choosin

Gwennaël Arbona 15 Jun 24, 2022
theora-player is an embeddable theora video player C++ library based on the libtheora sample. It has no audio support at this moment.

theora-player Description theora-player is an embeddable theora video player C++ library based on the libtheora sample. It has no audio support at thi

Fire Falcom 2 Jun 18, 2022
Xan's NFS Music Player - Custom music player replacement and a BASS library interface for NFS.

Xan's NFS Music Player This is a custom music player replacement and a BASS library interface for NFS. FEATURES Custom playlist generation - put any n

Lovro Pleše 10 Mar 27, 2022
Like libevent and libuv, libhv provides event-loop with non-blocking IO and timer, but simpler api and richer protocols.

中文版 Intro Like libevent, libev, and libuv, libhv provides event-loop with non-blocking IO and timer, but simpler api and richer protocols. Features cr

ithewei 4.4k Jul 31, 2022
Slides and other materials from CppCon 2017

CppCon 2017 Presentation Materials https://github.com/CppCon/CppCon2017 is the canonical location for presentations and code from CppCon 2017. For Spe

CppCon 1.6k Aug 7, 2022
Presentation Material for C++Now 2017

C++Now 2017 Presentations Slide Deck Guidelines for Speakers Tuesday, May 16 Paepcke Morning (9:00-10:30) Rust: Hack Without Fear!, Niko Matsakis (vid

null 454 Aug 8, 2022
Like libevent and libuv, libhv provides event-loop with non-blocking IO and timer, but simpler api and richer protocols.

中文版 Intro Like libevent, libev, and libuv, libhv provides event-loop with non-blocking IO and timer, but simpler api and richer protocols. Features cr

ithewei 4.4k Aug 7, 2022
Simpler ImGui Backend Implementation for VulkanHpp.

ImGui-VulkanHpp Simpler ImGui Backend Implementation for VulkanHpp.

takiyu 25 Jul 3, 2022
2017-2019 math projects

Project Mathematics All the projects Name Language Grade Year 101 Pong Python3 16.2/20 2017 102 Architect Python3 19.8/20 2017 103 Cipher C 17.2/20 20

Luis Rosario 12 Mar 1, 2022
A refactored Proof-of-concept originally developed in 2017 to print all function calls with their arguments data types and values using Ptrace during program execution.

print-function-args-debugger A refactored Proof-of-concept originally developed in 2017 to print all function calls with their arguments data types an

*finixbit 15 Jun 17, 2022
A simpler version of the infamous zero kb virus written in C++.

A simpler version of the infamous zero kb virus written in C++. A few years back I was struck by the 'zero kb' virus, and so i decide to write my own zero kb virus as an act of vengeance (

vincent laizer 3 Sep 19, 2021
Like feh, but better, faster, more image formats, simpler, more lightweight, animation support, and better UI

Like feh, but better, faster, more image formats, simpler, more lightweight, animation support, and better UI

martin 10 Jul 27, 2022
Source code from 068A, our 64k demo presented at Syntax 2017

068A source code dump This is a dump of the source code for the engine, graphics tool and player for 068A, our 64k demo released at Syntax 2017. It's

Monad 23 May 30, 2022
Sandbox binary and source code for the Siggraph 2017 paper "Water Wave Packets" by Stefan Jeschke (NVIDIA) and Chris Wojtan (IST Austria)

----------------------------- Manual for wave packet viewer ----------------------------- System requirements: Windows8/8.1/10 with DirectX runtime e

Stefan Jeschke 35 Feb 10, 2022
Better lossless compression than PNG with a simpler algorithm

Zpng Small experimental lossless photographic image compression library with a C API and command-line interface. It's much faster than PNG and compres

Chris Taylor 201 Jun 28, 2022
CVE-2021-24084 Windows Local Privilege Escalation Left officially unpatched since 2020. Hence, its still a zero day

WindowsMDM-LPE-0Day Works best on Windows 11 CVE-2021-24084 Windows Local Privilege Escalation Left officially unpatched since 2020. Hence, its still

Exploit Blizzard 31 Jul 20, 2022
(FIXED) Since the one on github didn't work. (ALSO INCLUDES .DLL SO YOU CAN JUST INJECT INTO FORTNITE)

Marathon-Fortnite-Cheat-Fix-Leak Fortnite Marathon Cheat v18.20 FIXED [Leak] Getting started Open .sln with Visual Studio 2019 Compile batch build to

LUCIFER ® 2 Dec 13, 2021
This is my record of practicing programming skills on LeetCode since 2021.

My_LeetCode_Road This is my record of practicing programming skills on LeetCode since 2021. No. Chinese Title Englist Title Acceptance Difficulty 1 两数

Nebulae 4 Aug 5, 2022
Boost.GIL - Generic Image Library | Requires C++11 since Boost 1.68

Documentation GitHub Actions AppVeyor Azure Pipelines CircleCI Regression Codecov Boost.GIL Introduction Documentation Requirements Branches Community

Boost.org 146 Jul 11, 2022
CMake wrapper for Box2D, since it uses premake5

Box2D CMake Support This is a wrapper around the C++ library Box2D. The Source code can be found on Github Status LICENSE Linux / macOS Windows Issues

Tobias Hienzsch 10 Feb 12, 2022
It's a simple and free x86_64 architecture operating system created by one person, GoofOS started since 2022

This project is while developing... GoofOS GoofOS is a text operating system for x86 computers. About This is a 32 bit x86_64 graphical operating syst

null 3 May 1, 2022
This is a simple version of Apex-Legends-SDK since so many people having struggles with python binding

This is a simple version of Apex-Legends-SDK since so many people having struggles with python binding

skidword64 38 Jul 29, 2022