Development
#game
unity
Integrate SpacetimeDB with Unity game projects. Use when building Unity clients with MonoBehaviour lifecycle, FrameTick, and PlayerPrefs token persistence.
DeepseekModel
Curated skill
Quality Excellent · 90
v1.0.0
Get
https://deepseekmodel.com/api/download.php?id=clockworklabs-spacetimedb-codex-plugin-plugins-spacetimedb-skills-unity-skill-md&format=skill
Download .skill
Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name unity description Integrate SpacetimeDB with Unity game projects. Use when building Unity clients with MonoBehaviour lifecycle, FrameTick, and PlayerPrefs token persistence. license Apache-2.0 metadata {"author":"clockworklabs","version":"2.0","role":"client","language":"csharp","cursor_globs":"**/*.cs","cursor_always_apply":false,"tested_with":"SpacetimeDB 2.0, Unity 2022.3+"} SpacetimeDB Unity Integration This skill covers Unity-specific patterns for connecting to SpacetimeDB. For server-side module development, see the csharp-server skill. Installation Add via Unity Package Manager using the git URL: https://github.com/clockworklabs/com.clockworklabs.spacetimedbsdk.git Window > Package Manager > + > Add package from git URL Generate Module Bindings spacetime generate --lang csharp --out-dir Assets/SpacetimeDB/module_bindings --module-path PATH_TO_MODULE Place generated files in your Assets folder so Unity compiles them. SpacetimeManager Singleton The core pattern for Unity integration. This MonoBehaviour manages the connection lifecycle. using UnityEngine; using SpacetimeDB; using SpacetimeDB.Types; public class SpacetimeManager : MonoBehaviour { private const string TOKEN_KEY = "SpacetimeAuthToken" ; private const string SERVER_URI = "http://localhost:3000" ; private const string DATABASE_NAME = "my-game" ; public static SpacetimeManager Instance { get ; private set ; } public DbConnection Connection { get ; private set ; } public Identity LocalIdentity { get ; private set ; } void Awake () { if (Instance != null && Instance != this ) { Destroy(gameObject); return ; } Instance = this ; DontDestroyOnLoad(gameObject); } void Start () { string savedToken = PlayerPrefs.GetString(TOKEN_KEY, null ); Connection = DbConnection.Builder() .WithUri(SERVER_URI) .WithDatabaseName(DATABASE_NAME) .WithToken(savedToken) .OnConnect(OnConnected) .OnConnectError(err => Debug.LogError( $"Connection failed: {err} " )) .OnDisconnect((conn, err) => { if (err != null ) Debug.LogError( $"Disconnected: {err} " ); }) .Build(); } void Update () { Connection?.FrameTick(); } void OnDestroy () { Connection?.Disconnect(); } private void OnConnected ( DbConnection conn, Identity identity, string authToken ) { LocalIdentity = identity; PlayerPrefs.SetString(TOKEN_KEY, authToken); PlayerPrefs.Save(); Debug.Log( $"Connected as: {identity} " ); conn.SubscriptionBuilder() .OnApplied(OnSubscriptionApplied) .SubscribeToAllTables(); } private void OnSubscriptionApplied ( SubscriptionEventContext ctx ) { Debug.Log( "Subscription applied: game state loaded" ); } } FrameTick (Critical) FrameTick() must be called every frame in Update() . The SDK queues all network messages and only processes them when you call FrameTick() . Without it, no callbacks fire and the client appears frozen. See the Update() method in the SpacetimeManager above. Thread safety : FrameTick() processes messages on the calling thread (the main thread in Unity). Do NOT call it from a background thread. Do NOT access conn.Db from background threads. Row Callbacks for Game State Register callbacks to update Unity GameObjects when table data changes. void RegisterCallbacks () { Connection.Db.Player.OnInsert += (EventContext ctx, Player player) => { SpawnPlayerObject(player); }; Connection.Db.Player.OnDelete += (EventContext ctx, Player player) => { DestroyPlayerObject(player.Id); }; Connection.Db.Player.OnUpdate += (EventContext ctx, Player oldPlayer, Player newPlayer) => { UpdatePlayerObject(newPlayer); }; } Register these in OnSubscriptionApplied (after initial data is loaded) or in Start() before connecting. Calling Reducers from UI public class GameUI : MonoBehaviour { public void OnMoveButtonClicked ( Vector2 direction ) { SpacetimeManager.Instance.Connection.Reducers.MovePlayer(direction.x, direction.y); } public void OnSendChat ( string message ) { SpacetimeManager.Instance.Connection.Reducers.SendMessage(message); } } Reducer Callbacks SpacetimeManager.Instance.Connection.Reducers.OnSendMessage += (ReducerEventContext ctx, string text) => { if (ctx.Event.Status is Status.Committed) Debug.Log( $"Message sent: {text} " ); else if (ctx.Event.Status is Status.Failed( var reason)) Debug.LogError( $"Send failed: {reason} " ); }; Reading the Client Cache // Find by primary key if (Connection.Db.Player.Id.Find(playerId) is Player player) { Debug.Log( $"Player: {player.Name} " ); } // Iterate all foreach ( var p in Connection.Db.Player.Iter()) { Debug.Log(p.Name); } // Filter by index foreach ( var p in Connection.Db.Player.Level.Filter( 5 )) { Debug.Log( $"Level 5: {p.Name} " ); } // Count int total = Connection.Db.Player.Count; Unity-Specific Considerations Main Thread Only All SpacetimeDB SDK calls ( FrameTick , conn.Db access, reducer calls) must happen on the main thread. If you need to pass data to a background thread, copy it first in the callback. Scene Loading Use DontDestroyOnLoad(gameObject) on the SpacetimeManager to prevent the connection from being destroyed during scene transitions. Without it, the connection drops every time you load a new scene. IL2CPP / AOT The SpacetimeDB SDK uses code generation. If you encounter issues with IL2CPP builds: Ensure generated bindings are up to date Check that link.xml preserves SpacetimeDB types if you use assembly stripping Token Persistence Token save/load via PlayerPrefs is demonstrated in the SpacetimeManager singleton above. Persisting the server-issued token and passing it back on reconnect keeps the same identity; without a saved token the server issues a new identity in the OnConnect callback. This token does not expire and a lost one can't be recovered, so self-issued identities are for development. For production, authenticate with an OIDC provider such as SpacetimeAuth, which handles token lifecycle.
Keywords that activate this skill. Click one to copy it.
This skill does not provide trigger words.
The downloaded .skill package contains the following fields.
| Field | Description |
|---|---|
| format | Format tag (skill/v1) |
| skill_id | Unique skill ID |
| name | Skill name |
| version | Version |
| description | Description |
| category | Categories (array) |
| trigger_words | Trigger words |
| tags | Tags |
| source | Source |
| source_url | Source URL (this page) |
| exported_at | Exported at (set per download) |
| system_prompt | System prompt body |
| model_config | Model config: provider / model / temperature / max_tokens / top_p |
| examples | Examples |
| install_guide | Import guide for Coze / Dify / Claude / custom frameworks |
The same skill can be exported in different platform formats.