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; theImcore.Unityadapter is validated inside the editor. Validate against your own deployment before production use.