Social Infrastructure at Scale

If you haven’t set up a Nakama server and started it, please visit Start a server first.

The Unity client handles all realtime client/server communication with our protocol. It supports all Nakama server features which include users, data storage, groups, realtime multiplayer, realtime chat, and more. Have a look at our Development docs for a full list.

To work with our Unity client you’ll need to install and setup Unity.

Looking for another engine? Defold, Unreal, another? Join our community and help us shape the development of realtime and social games with your favorite game engine.


To include the Unity client in your project, download it from our GitHub releases page. The download is named "Nakama.unitypackage" and contains a copy of all source code as well as the DLL dependencies required by the client.

Drag or import the ".unitypackage" into your Unity editor project to install it.

How to connect to server

In the Unity editor create a new C# script. This can be done via the Assets menu with "Assets > Create > C# Script". Modify the initial code in the script to connect with the server:

Run with a local server These instructions assume you’ve got a Nakama server setup and started with default connection details "" and port "7350". For more help see Start a server.
using UnityEngine;
using System.Collections;
using Nakama;

public class NewBehaviourScript : MonoBehaviour {
  void Start() {
    INClient client = NClient.Default("defaultkey");

  void Update() {

An INClient object is created which represents a connection to the server. Have a read of Controlling GameObjects Using Components for examples on how to share a C# object across your game objects.

You can change all the default connection settings with an NClient.Builder:

INClient client = new NClient.Builder("defaultkey")
In production You must not use the default server key "defaultkey" in a production environment. Be sure to change it within the configuration settings.


The INClient manages a socket connection with the server but before you can connect to the socket you must authenticate. There’s various different ways you can authenticate a user with the server.

The device ID option is the most simple register/login option for users. It is done entirely without user interaction, so the user experience is completely frictionless. You can use SystemInfo.deviceUniqueIdentifier which is guaranteed to be unique on every device.

client.Register(request, (INSession session) => {
  // cache session on device
}, (INError error) => {
  Debug.LogErrorFormat("ID register '{0}' failed: {1}", uid, error);

If the user has already registered with the device ID you should use:

var uid = SystemInfo.deviceUniqueIdentifier;
var request = NAuthenticateMessage.Device(uid);
client.Login(request, (INSession session) => {
  // cache session on device
}, (INError error) => {
  Debug.LogErrorFormat("ID login '{0}' failed: {1}", uid, error);
Session cache It’s a good idea to cache a session on a device and restore it at game startup to avoid asking the user to login or register again. See the User docs for examples.

Both "login" and "register" give us an INSession object. This session is used to establish a connection with the server.

client.Connect(session, (bool connected) => {
  Debug.Log("Socket connected.");
Session lifecycle Use client.Disconnect() when the game client loses focus or is closed and reconnect when it’s active. See the Awake and Start tutorial on the Unity website.

Write/Fetch records

Nakama provides a general purpose data storage service for save games and other records owned by users. We’ll use storage to introduce how messages are sent between client and server. This covers the general pattern for all of the protocol available in the Unity client.

We’ll create a record for the current user, create a message to store it, and send the message that will store it with the server.

byte[] storageValue = Encoding.UTF8.GetBytes("{\"jsonkey\":\"jsonvalue\"}");

var message = new NStorageWriteMessage.Builder().Write("testBucket", "testCollection", "testRecord", storageValue).Build();
client.Send(message, (bool completed) => {
  Debug.Log ("Successfully storage data.");
}, (INError error) => {
  Debug.LogErrorFormat ("Could not store data into storage: '{0}'.", error.Message);

And you can fetch it back from the server:

byte[] userId; // this value can be retrieve by sending a Self message.

var message = new NStorageFetchMessage.Builder().Fetch("testBucket", "testCollection", "testRecord", userId).Build();
client.Send(message, (INResultSet<INStorageData> results) =>
  foreach (INStorageData data in results) {
    Debug.LogFormat ("Storage Bucket: '{0}', Collection: '{1}', Record: '{2}'", data.Bucket, data.Collection, data.Record);
}, (INError error) => {
  Debug.LogErrorFormat ("Could not fetch data from storage: '{0}'.", error.Message);

Logs and errors

Both the server and client generate logs which can help to identify issues in development. To log all messages between client and server you can enable Trace when you create an INClient:

var client = new NClient.Builder("defaultkey").Trace(true).Build();
var client = NClient.Default("defaultkey");

#if preprocessor directives are used so Trace is only enabled in Unity editor development. For more complex directives with "debug" vs "release" builds have a look at Platform dependent compilation.

All errors in the Unity client implement INError. It contains details on the source of an error:

Debug.LogErrorFormat("Error occurred: {0}", error.Message);
Open-source The Unity client is open-source on GitHub. Please report issues and contribute code to help us make it better.

Next Steps

This covers the basics of the Unity client. Some next steps are -