SDK · Unity/.NET

im.balala.unity-sdk is the Unity / .NET client SDK for the imcore IM server (Unity 2021.3+, .NET Standard 2.1, C# 9). WebSocket + JSON over async/await; commands and DTOs are generated from clients/protocol.yaml, sharing the wire contract of the JS, Kotlin, Swift and Dart SDKs. The core assembly has zero UnityEngine references and is reusable from any .NET project.

Add it (UPM)

Unity Package Manager → Install package from tarball → the imcore-sdk-unity-<version>.tar.gz from the download page; or from source via Packages/manifest.json with "im.balala.unity-sdk": "file:../clients/unity".

Two assemblies ship in the package: Imcore.SDK (protocol core) and Imcore.Unity (main-thread callbacks, PlayerPrefs storage, pause/resume lifecycle wiring).

Usage

using Imcore.Sdk;
using Imcore.Unity;

// Call from the Unity main thread: every callback is marshalled back to it.
var im = ImcoreUnity.CreateClient(o =>
{
    o.Url = "wss://your-host/acc";
    o.Auth = new AuthConfig { Token = "<jwt>", Login = new LoginPayload("1001", "alice") };
});
ImcoreUnity.AttachLifecycle(im); // disconnect on pause, reconnect on resume

im.StatusChanged += s => Debug.Log($"imcore: {s}"); // Idle/Connecting/Open/Authenticated/Closed/ReauthRequired
using var sub = im.On(Cmd.ChatMessage, payload =>
    Debug.Log($"msg {payload["text"]?.AsString()}"));

// ConnectAsync only returns after the server acknowledges login; a rejected
// login (bad token) throws RequestError — always wrap it.
try
{
    await im.ConnectAsync();
    await im.Dm.SendAsync(targetUserId: "1002", text: "hi");
    var history = await im.Dm.HistoryAsync(targetUserId: "1002", limit: 20);

    // Escape hatch for commands not yet wrapped:
    await im.RequestAsync("chat_group_create",
        JsonValue.Object().Set("name", JsonValue.Of("team")));
    await im.SendAsync("chat_dm_typing",
        JsonValue.Object().Set("targetUserID", JsonValue.Of("1002")));
}
catch (RequestError e)
{
    Debug.LogError($"imcore error: {e.Message}");
}

Offline queue

Use SendQueuedAsync while disconnected or not yet logged in: messages persist to PlayerPrefs (swap in any IKeyValueStorage) and flush automatically after the next successful login; im.Offline exposes manual flush/retry/clear.

Scope (first drop)

Transport core + seq-correlated request/response + login-ack-gated connect + typed DM/group/room APIs + the offline send queue + Unity lifecycle wiring. Not included: Unity UIKit, HTTP media upload, local chat cache, a built-in WebGL channel (inject your own IWebSocketChannel) and E2EE.

The protocol core is fully covered by dotnet test; the Imcore.Unity adapter is validated inside the editor. Validate against your own deployment before production use.