yojimbo Networking Library

repository·main·Indexed 25 days ago

https://github.com/mas-bandwidth/yojimbo

A C++ networking library for competitive multiplayer client/server games (optimized for 100 players or less). It provides secure, reliable, and efficient UDP-based communication featuring cryptographically secure authentication via connect tokens, encrypted/signed packets, and support for both unreliable-unordered and reliable-ordered messages. The library includes built-in serialization, telemetry for latency and packet loss, and a companion Matcher sample for connection token distribution.

Tokens
7.7K
Snippets
30
Records
44
Agent score
83%

What's inside yojimbo

  1. Overview of yojimbo networking library

    main

    yojimbo is a C++ network library specifically designed for client/server games, such as competitive first-person shooters. It provides a complete networking stack for managing connections, security, and data transmission over UDP.

    Key features include:

    • Security: Cryptographically secure authentication via connect tokens, and encrypted/signed packets.
    • Connection Management: Handles client/server connections and timeouts.
    • Reliability: Supports both unreliable-unordered messages (for time-sensitive data) and reliable-ordered messages (with aggressive resend until acknowledged).
    • Data Handling: Includes packet fragmentation/reassembly, a bitpacker/serialization system, and the ability to attach data blocks larger than the maximum packet size to reliable-ordered messages.
    • Telemetry: Provides per-connection estimates for latency, jitter, packet loss, and bandwidth (sent, received, and acked).
  2. Understand the Yojimbo client state machine

    main

    The Yojimbo client operates as a state machine that projects the underlying netcode states. The state machine determines how a client moves between connection, disconnection, and error states.

    Key State Values:

    • CLIENT_STATE_ERROR (-1): A failure state. Negative values indicate failure.
    • CLIENT_STATE_DISCONNECTED (0): The idle state. Zero indicates idle.
    • CLIENT_STATE_CONNECTING (Positive): Progressing towards a connection.
    • CLIENT_STATE_CONNECTED (Positive): Successfully connected.

    Callers can use thin predicates like IsConnecting(), IsConnected(), IsDisconnected(), and ConnectionFailed() to check these states.

  3. Understand the Yojimbo 1.0 Connection Packet Format

    main

    The Yojimbo 1.0 connection packet is the wire format for payloads carrying messages between client and server. It is designed to be extremely compact by assuming both ends have pre-agreed on the configuration.

    Important Prerequisites:

    • This format is not self-describing. Both reader and writer must agree in advance on numChannels, channel type, maxMessagesPerPacket, maxBlockSize, blockFragmentSize, disableBlocks, and the number of registered message types.
    • This layer assumes netcode has already handled encryption, authentication, and transport.
    • All primitives (e.g., serialize_int, serialize_bool) follow the serialize library standard.
  4. Measure fuzzing coverage

    main

    To check which branches a change reaches in the deserialization sources, use the tools/fuzz_coverage.sh script. It builds a target with source-based coverage instrumentation and runs it against the committed corpus plus pseudo-random inputs, then prints an llvm-cov report.

    tools/fuzz_coverage.sh <connection>
  5. Verify connection packet format conformance

    main

    Use verify_standard.py to ensure the implementation's connection packet format matches the specification in STANDARD.md. This script decodes the existing fuzz corpus (fuzz/corpus/fuzz_connection) using only the rules defined in STANDARD.md and serialize/STANDARD.md. It checks for bit-level exhaustion, ensuring no bits are left over and no reads occur past the end of a packet, which validates that framing and message bodies are correctly implemented according to the spec.

    python3 tools/conformance/verify_standard.py
  6. Build yojimbo on macOS and Linux

    main

    To build yojimbo on macOS or Linux, ensure you have CMake (3.16 or newer) installed. By default, the build uses a bundled minimal version of libsodium.

    For a standard debug build:

    1. Configure the build directory.
    2. Compile the project.

    To create an optimized Release build, pass -DCMAKE_BUILD_TYPE=Release during the configuration step.

    # Debug build
    cmake -B build
    cmake --build build -j
    
    # Release build
    cmake -B build -DCMAKE_BUILD_TYPE=Release
    cmake --build build -j
  7. Build against system-installed dependencies

    main

    By default, yojimbo uses vendored copies of serialize, reliable, and netcode. To build against system-installed versions of these three libraries instead, use the -DYOJIMBO_SYSTEM_DEPS=ON flag.

    Requirements:

    • The dependencies must be installed where CMake can find them. Use -DCMAKE_PREFIX_PATH=/path/to/prefix if they are in a custom location.
    • In this mode, the bundled libsodium is not used (the system netcode provides its own crypto).
    • cmake --install will install the yojimbo headers and library.

    Note: The test suite skips the embedded netcode and reliable self-test sections in this configuration because system libraries do not include those test hooks.

    cmake -B build -DYOJIMBO_SYSTEM_DEPS=ON
    cmake --build build -j
    ./bin/test
    cmake --install build
  8. Manage client state transitions via Connect() and Disconnect()

    main

    You can control the client's state transitions using the following methods:

    • Connect(): Moves the client from DISCONNECTED, ERROR, or CONNECTED to CONNECTING. If a connect token cannot be generated, the client moves directly to ERROR.
    • Disconnect(): Moves the client from any state to DISCONNECTED.

    Transition Rules:

    • CONNECTINGCONNECTED: Occurs when the underlying netcode handshake completes.
    • CONNECTINGERROR: Occurs on handshake failure (e.g., token expired, invalid, connection denied, or timeouts).
    • CONNECTEDDISCONNECTED: Occurs when the server closes the connection cleanly.
    • CONNECTEDERROR: Occurs on transport failure or timeout.

    Note: ERROR is a terminal state. The client will not retry automatically; you must call Connect() to start a fresh attempt.

  9. Build real libFuzzer targets (CI mode)

    main
    To run coverage-guided fuzzing using the real libFuzzer (equivalent to the CI environment on Linux clang), replace the -DFUZZ_STANDALONE flag with -fsanitize=fuzzer (added to the sanitizer set) and provide a corpus directory and a -max_total_time=N argument.