You are viewing a potentially older version of this package. View all versions.
DAa-PEAKNetworkingLibrary-1.0.0 icon

PEAKNetworkingLibrary

Network library for PEAK using Steam instead of PUN with offline compatiblity.

By DAa
Date uploaded 8 months ago
Version 1.0.0
Download link DAa-PEAKNetworkingLibrary-1.0.0.zip
Downloads 98
Dependency string DAa-PEAKNetworkingLibrary-1.0.0

This mod requires the following mods to function

BepInEx-BepInExPack_PEAK-5.4.75301 icon
BepInEx-BepInExPack_PEAK

BepInEx pack for PEAK. Preconfigured and ready to use.

Preferred version: 5.4.75301

README


Discord

PEAKNetworkingLibrary v1.0.0: Release!

Latest Version Total Downloads

Minimal, backend-agnostic networking for PEAK modders.
Works with the Steam adapter or the built-in Offline shim for testing.


Update Details & Plans & Features:

Update Details
  • Released...
Plans
  • Add chunked RPC transfer for very large payloads.
  • Improve documentation.
Features [Not All]
  • Backend
    INetworkingService provides one surface mods use. Swap Steam vs Offline without code changes.

  • Lobby key sync (host -> clients)
    Host sets small authoritative strings via SetLobbyData. Clients read with GetLobbyData and LobbyDataChanged event.

  • RPC discovery & invocation
    Discover methods marked [CustomRPC] with RegisterNetworkObject and call RPC, RPCTarget, or RPCToHost.

  • Message serialization
    Message class supports: byte, int, uint, long, ulong, float, bool, string, byte[], Vector3, Quaternion, CSteamID.

  • Reliable vs Unreliable
    ReliableType enum supports Reliable, Unreliable, UnreliableNoDelay semantics.

  • Security (optional)
    Optional HMAC signing, per-mod signer hooks, sequence numbers, replay protection.

  • Framing & priority
    Per-message flags, msg-id, sequence, fragment metadata, priority queues.

  • Offline shim for CI
    Full in-process simulator to run tests without Steam.

  • Incoming validation hook
    IncomingValidator lets consumers drop or accept messages before handler invocation.

  • Poll-based receive loop
    PollReceive() is required for Steam adapter; Offline shim is immediate.

API Refrences [Not All]
INetworkingService
  - Initialize()
  - Shutdown()
  - CreateLobby(maxPlayers)
  - JoinLobby(lobbySteamId64)
  - LeaveLobby()
  - RegisterLobbyDataKey(string key)
  - SetLobbyData(string key, object value)
  - T GetLobbyData<T>(string key)
  - RegisterPlayerDataKey(string key)
  - SetPlayerData(string key, object value)
  - T GetPlayerData<T>(ulong steam64, string key)
  - IDisposable RegisterNetworkObject(object instance, uint modId, int mask = 0)
  - void DeregisterNetworkObject(object instance, uint modId, int mask = 0)
  - void RPC(uint modId, string methodName, ReliableType reliable, params object[] parameters)
  - void RPCTarget(uint modId, string methodName, ulong targetSteamId64, ReliableType reliable, params object[] parameters)
  - void RPCToHost(uint modId, string methodName, ReliableType reliable, params object[] parameters)
  - void PollReceive()
  - Events: LobbyCreated, LobbyEntered, LobbyLeft, PlayerEntered(ulong), PlayerLeft(ulong),
            LobbyDataChanged(string[] keys), PlayerDataChanged(ulong steam64, string[] keys)
  - Func<Message, ulong, bool>? IncomingValidator { get; set; }
Examples [Not All]

All examples assume the networking service is already present (Steam or Offline). They show the smallest usable code for each feature.

1) Minimal host -> clients: Lobby key (recommended for package lists)

Host sets one string key. Clients read it on change.

Host: broadcast package list

// host only
void BroadcastLoadedPackages(INetworkingService svc, IEnumerable<string> packages)
{
    const string KEY = "PEAK_PACKAGES_V1";
    svc.RegisterLobbyDataKey(KEY); // safe to call on all peers

    // serialize: escape '|' then join and compress+base64 option
    string joined = string.Join("|", packages.Select(p => p.Replace("|","||")));
    string payload = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(joined));
    svc.SetLobbyData(KEY, payload); // host-only action
}

Client: receive update

void SubscribeToPackageUpdates(INetworkingService svc)
{
    const string KEY = "PEAK_PACKAGES_V1";
    svc.RegisterLobbyDataKey(KEY); // register the key used by host
    svc.LobbyDataChanged += keys =>
    {
        if (!keys.Contains(KEY)) return;
        var payload = svc.GetLobbyData<string>(KEY);
        if (string.IsNullOrEmpty(payload)) return;
        var joined = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(payload));
        var packages = joined.Length == 0 ? Array.Empty<string>() :
                       joined.Split('|').Select(s => s.Replace("||","|")).ToArray();
        // now packages[] contains the host list
    };
}

Notes:

  • Lobby metadata is small and best for modest lists (tens of items).
  • If payload grows large, compress it (gzip) before base64.
2) Minimal RPC broadcast (general notifications)

Use RPC when you need immediate notification or structured params.

Register and broadcast

const uint MOD = 0xDEADBEEF;

// on plugin init
IDisposable token = svc.RegisterNetworkObject(this, MOD);

// broadcast
svc.RPC(MOD, "NotifyPackages", ReliableType.Reliable,  "GAME_PACKAGES_READY");

In same class: RPC handler

[CustomRPC]
void NotifyPackages(string tag)
{
    // runs on all peers (including host by loopback)
    Logger.LogInfo($"NotifyPackages received: {tag}");
}

Notes:

  • Must call PollReceive() each frame for Steam adapter.
  • RegisterNetworkObject discovers methods tagged [CustomRPC].
3) Targeted RPC to specific player
svc.RPCTarget(MOD, "PrivateMessage", targetSteamId64, ReliableType.Reliable, "hello");

Handler:

[CustomRPC]
void PrivateMessage(string text) { Debug.Log(text); }
4) IncomingValidator usage (drop unwanted messages)
svc.IncomingValidator = (msg, fromSteam64) =>
{
    // drop messages with a specific method name
    if (msg.MethodName == "DropMe") return false;
    return true;
};
5) Offline shim for local tests
// Use this for unit tests or local dev when Steam not available.
INetworkingService svc = new OfflineNetworkingService();
svc.Initialize();
// Offline shim delivers messages immediately. PollReceive() is a no-op.


Efficiency guidance

  • Lobby data: cheap for small text. Keep per-key payload < ~2–4 KB.
  • RPC: use for immediate messages and structured params. Use Unreliable for high-rate telemetry.
  • Compress large payloads (gzip) before base64. Or use chunked RPC transfer.
  • HMAC/signing is optional. Enable when you need tamper detection.

Troubleshooting & tips

  • Always call PollReceive() in Update() when using Steam adapter.
  • Register lobby/player keys before calling Get/Set to avoid warnings.
  • Use RegisterNetworkObject and keep the returned IDisposable for safe deregistration.
  • For very large lists prefer chunked RPC or a request-on-join RPC rather than putting everything in lobby metadata.


More details & Help

⠀ (!) If you encounter any issues with the mod, join the discord and message here.


Discord

CHANGELOG

Changelog

The format is based on Keep a Changelog.

 

1.0.7 23/11/2025

Added

  • Table value support for messages.

Changed

  • null

Fixed

  • Patched issues with RPC events.

1.0.6 23/11/2025

Added

  • null.

Changed

  • null

Fixed

  • I forgot to change reference link to the actual one.

1.0.5 22/11/2025

Added

  • null.

Changed

  • Simplified RPC structure for sending back messages to the caller / fetching the caller.

Fixed

  • Made photon user to steam user mapping usable.

v1.0.4

- Patched something.
- Implemented IsHost bool.

v1.0.3

- Implemented helper functions to simplify usage of Library.

v1.0.2

- Fixed the README

v1.0.1

- Made it mote consumer friendly.

v1.0.0

- Release