Skip to main content
The C# SDK uses the same routes and wire format as the TypeScript and Swift clients. It has two parts:
  • Runtime/: plain .NET Standard 2.1 with no Unity references and no reflection. It runs under IL2CPP and in any .NET app.
  • Unity/: token storage in PlayerPrefs and a converter that uses JsonUtility.
The SDK has live queries but no offline write queue: writes go through server functions.

Types

Platforms

Install

In Unity, open Window > Package Manager. Click +, then Install package from git URL, and enter:
Any release tag from v0.22.12 on works.

Sign in and call a function

A sign-in method stores the token. Later requests send it as Authorization: Bearer. Every method throws PylonException. For an HTTP error, the exception has the status, the server’s error code, and the message. The client also has these methods:
  • SignInWithAppleAsync, SignInWithGoogleAsync, and SignInWithSteamAsync (see Native sign-in)
  • StartMagicCodeAsync and VerifyMagicCodeAsync
  • SignInWithPasswordAsync and RegisterWithPasswordAsync
  • RefreshSessionAsync and StartSessionAutoRefresh
  • ListAsync, ListCursorAsync, GetAsync, CreateAsync, UpdateAsync, and DeleteAsync
  • AggregateAsync and SearchAsync
  • RequestAsync, for any other route

Live queries

  • The server sends each insert, update, and delete the caller may read. Read policies and field redaction apply on the server.
  • Rows and Changed change on the client’s dispatcher.
  • After a reconnect, the query pulls from its cursor, so it loses no change.
  • Rows come from entities with sync on (the default).

Your own types

Function arguments, results, and snapshots are PylonValue. A missing key reads as PylonValue.Null, so snapshot["players"][0]["x"] does not throw. To use your own types, give an IPylonConverter<T>. The SDK calls the converter and does not use reflection. For a [Serializable] class, use JsonUtilityConverter<T>.Instance.

Join a shard

  • Send returns the input’s sequence number. A frame’s Ack is the highest sequence number the shard processed.
  • For a MessagePack shard, inputs go as MessagePack. For all other shards, inputs go as JSON.
  • A replicating shard fills shard.Entities. The Replication event gives the spawned, updated, and despawned ids.
  • When the server moves the player to another shard, Transferred runs. The connection then goes to the new shard.
  • The server can refuse a ticket, or the ticket can expire. The connection then stops, unless TicketProvider gives a new ticket.
  • IdleTimeout reconnects when no frame arrives. Use it only for tick-driven shards.

A render loop

ShardGame<TInput> puts the connection, the clock, interpolation, and prediction together.
  • A predictor from Predict records each sent input, drops refused inputs, and resets when the connection reopens.
  • Send returns 0 when it did not send. Do not predict that input.
  • Send stamps each input with the tick the last Frame drew, for a shard with lag compensation.

WebTransport

Over WebTransport (QUIC), entity updates travel as datagrams. A lost packet delays only its own update. Over a WebSocket, it holds back every frame behind it.
  • WebSocket is the default for ShardConnection.
  • WebTransport uses WebTransport only.
  • Auto is the default for ShardGame. It uses WebTransport when the session opens, and a WebSocket otherwise.
  • Auto uses a WebSocket when the plugin is missing, the app does not serve WebTransport, UDP is blocked, the session does not open in 3 s, or datagrams stop.
  • The server serves WebTransport when PYLON_WEBTRANSPORT_PORT is set.
  • shard.Transport gives the transport of the open connection.
The package includes a native WebTransport plugin for each platform in Plugins/:
  • macOS (arm64 and x86_64)
  • Windows x86_64
  • Linux x86_64
  • iOS (device and simulator)
  • Android arm64-v8a and armeabi-v7a

Threads

The SDK runs callbacks on the SynchronizationContext of the thread that made the client or connection. In Unity, make them on the main thread. Events then run on the main thread, and you can change GameObjects in them. Dispose the connection and the client in OnDestroy.

Sample

The package has an Arena sample. It signs in as a guest, calls joinArena, joins the arena shard, and moves your player. To run it:
  1. Run pylon dev in examples/shard-arena. To use WebTransport, set PYLON_WEBTRANSPORT_PORT=4324.
  2. Import the sample from Package Manager > Pylon > Samples.
  3. Open the scene and press Play.

Tests

The tests run with the .NET SDK. Unity includes one at Unity.app/Contents/Resources/Scripting/DotNetSdk.
The TypeScript, Swift, and C# clients check the same fixture files: packages/realtime/src/replication.fixtures.json and packages/realtime/src/wire.fixtures.json. The Rust encoders write these files, so a change to the wire format fails all three clients until each one matches.