Build scalable game backends with Nakama
In this tutorial I am going to show you the Nakama specific parts to build some social and competitive features for a fictional Unity game inspired by the hit mobile game, Crossy Road. Nakama is a customizable and scalable open source game server with all the social, competitive, and economy features you need to build and scale online games.
Install Nakama server and game engine SDK
First thing, head over to the Nakama docs and follow our Docker or binary installation guide.
Next install the Nakama Unity SDK, and in your main scene connect your game to your Nakama server by creating a Nakama Client.
var client = new Nakama.Client("http", "127.0.0.1", 7350, "defaultKey");
Authentication, Sessions and Users
Now that your game is connected to the server, it’s time to authenticate players with Facebook, import their Facebook friends, create game sessions and manage user accounts.
Facebook authentication
Authenticating with Facebook is simple with Nakama:
public void AuthenticateWithFacebook()
{
FB.LogInWithReadPermissions(new[] { "public_profile", "email" }, async result =>
{
if (FB.IsLoggedIn)
{
try
{
var importFriends = true;
Session = await client.AuthenticateFacebookAsync(AccessToken.CurrentAccessToken.TokenString, importFriends);
Debug.Log("Authenticated with Facebook");
}
catch(ApiResponseException ex)
{
Debug.LogFormat("Error authenticating with Facebook: {0}", ex.Message);
}
}
});
}
Your friends can easily be imported by passing a True
value for importFriends
. Nakama will then add them to your in-game friends list if they are also playing.
Sessions
Once authenticated, sessions can be restored or refreshed so that players don’t have to re-authenticate. The session auth and refresh tokens can be stored in Unity’s PlayerPrefs
:
PlayerPrefs.SetString("nakama.authToken", Session.AuthToken);
PlayerPrefs.SetString("nakama.refreshToken", Session.RefreshToken);
Then accessed to restore sessions:
var authToken = PlayerPrefs.GetString("nakama.authToken", null);
var refreshToken = PlayerPrefs.GetString("nakama.refreshToken", null);
session = Nakama.Session.Restore(authToken, refreshToken);
Or refresh sessions before they expire:
if (session.IsExpired || session.HasExpired(DateTime.UtcNow.AddDays(1))) {
try {
// Attempt to refresh the existing session.
session = await client.SessionRefreshAsync(session);
} catch (ApiResponseException) {
// Couldn't refresh the session so reauthenticate.
session = await client.AuthenticateDeviceAsync(deviceId);
PlayerPrefs.SetString("nakama.refreshToken", session.RefreshToken);
}
PlayerPrefs.SetString("nakama.authToken", session.AuthToken);
}
User accounts
Using the session we can get the current player’s user account, and access and update properties, visualized in your game’s profile screen:
Get the player’s account
var account = await client.GetAccountAsync(session);
var username = account.User.Username;
var avatarUrl = account.User.AvatarUrl;
Update the player’s account
var newUsername = "NotTheImp0ster";
var newDisplayName = "Innocent Dave";
var newAvatarUrl = "https://example.com/imposter.png";
var newLangTag = "en";
var newLocation = "Edinburgh";
var newTimezone = "BST";
await client.UpdateAccountAsync(session, newUsername, newDisplayName, newAvatarUrl, newLangTag, newLocation, newTimezone);
Get the player’s friends
var result = await client.ListFriendsAsync(session);
foreach (var f in result.Friends)
{
Debug.LogFormat("Friend '{0}' state '{1}'", f.User.Username, f.State);
}
Nakama has many more easy-to-use APIs for working with friends, groups (clans), real-time parties, matches, leaderboards, chat and more.
Competing with your friends
Nakama makes it easy to add social and competitive features to singleplayer games or build complete real-time multiplayer experiences. Like Crossy Road, the core gameplay of Croaky Road happens on the client and players compete against each other on global or friend leaderboards.
Once players complete a round and receive a score we’ll show them where they ranked versus their friends.
Create a leaderboard
We first need to create a Leaderboard on the game server in one of Nakama’s supported server runtimes: Go, TypeScript/JavaScript or Lua. Here’s the Go server code to create a leaderboard:
id := "weekly_leaderboard"
authoritative := false
sort := "desc"
operator := "incr"
reset := "0 0 * * 1"
metadata := map[string]interface{}{}
nk.LeaderboardCreate(ctx, id, authoritative, sort, operator, reset, metadata)
Submit a score
Player scores can be submitted to the leaderboard and Nakama will take care of ranking and ordering players.
var score = 1;
var subscore = 0;
var metadata = new Dictionary<string, string> {{ "map", "jungle" }};
await client.WriteLeaderboardRecordAsync(session, "weekly_leaderboard", score, subscore, JsonWriter.ToJson(metadata));
Display a friends leaderboard
Nakama has powerful leaderboard listing functionality. We could display the top records on the leaderboard, records around the player, the player’s group (clan) and for this example just the player’s friends:
var friendsList = await client.ListFriendsAsync(session, 0, 100, cursor: null);
var userIds = friendsList.Friends.Select(f => f.User.Id);
var recordList = await client.ListLeaderboardRecordsAsync(session, "weekly_leaderboard", userIds, expiry: null, 100, cursor: null);
foreach (var record in recordList.Records)
{
Debug.LogFormat("{0} scored {1}", record.Username, record.Score);
}
Monitoring your game’s success
Nakama comes with a developer console for monitoring your game server config, users, storage, matches, leaderboards and performance.
This is just a taste of how easy it is to add social and competitive features to your game. Nakama also has a wealth of realtime multiplayer features for matchmaking, networking game state and so much more.
Next steps
- Read our comprehensive Unity Client Guide.
- Run one of our open source sample games.