Nakama Console

Nakama Console

From the Nakama Console documentation (opens in a new tab):

The Nakama console is a powerful and flexible UI for your Nakama server instance. It enables easy access to player and server data, allowing both technical and non-technical users to quickly perform any needed service tasks.

After cloning and running the starter-game-template (opens in a new tab) with make start, the Nakama console will be hosted on your local machine at localhost:7351. The default username and password is admin:password.

The Nakama console can be used to test and verify backend game logic before any client is created. The following concepts are especially useful for Cardinal based projects:

Admin User

Nakama has User Accounts (opens in a new tab), and each User Account has a User ID. By default, a system owner User Account is created with a User ID of 00000000-0000-0000-0000-000000000000.

Additional accounts can be created using the API Explorer.

API Explorer

The API Explorer tab on the sidebar allows you to send RPC requests to Nakama. Some requests sent to Nakama will interact with Nakama directly and other requests will be passed through to your Cardinal implementation.

In general, the sequence for using the API Explorer is:

  1. Select an endpoint from the dropdown menu
  2. Paste a valid User ID into the User ID field.
  3. Populate the request body with some JSON
  4. Hit the Send Request button

The items in the endpoint dropdown are split up into two sections: The Cardinal specific endpoints are listed before the "----" break and Nakama specific endpoints are listed after the "----" break.

Additional endpoints can be added from the InitModule function like this:

package main
import (
func InitModule(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, initializer runtime.Initializer) error {
    initializer.RegisterRpc("some/endpoint/path", func(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
		// custom handler code goes here

Additional Accounts

User accounts can be created from the API Explorer. The easiest endpoint to use is AuthenticateDevice which will create a user based on a "Device ID".

Select the AuthenticateDevice endpoint from the dropdown. This endpoint does not require a User ID. Populate the request body with:

  "account": {
    "id": "some-random-device-id"
  "create": true,
  "username": "some-random-user-name"

Then hit the Send Request button. The and username fields can be modified to whatever string you want, however the field must be between 10 and 128 characters long.

To view the newly created account, click the Accounts items in the sidebar. You should find an entry with the username from the previous AuthenticateDevice request, as well as a non-zero User ID. This User ID can be copied into the User ID field of the API Explorer to simulate a request from that particular user.


Game and user data can be stored in Nakama's Storage Engine (opens in a new tab).

Items in the storage engine are grouped by a "Collection Name" and uniquely identified within a collection with a "Key Name". You can associate a storage item with a User ID. If the User ID is omitted, the system owner User ID (00000000-0000-0000-0000-000000000000) will be used. The storage item value must be properly formatted JSON.

Here is a code example that saves a made up "energy" value into a storage object associated with a specific user.

package main
func saveAnEnergyStorageItem(ctx context.Context, energy int, nk runtime.NakamaModule) error {
	userID, ok := ctx.Value(runtime.RUNTIME_CTX_USER_ID).(string)
	if !ok {
		return errors.New("unable to get user id from context")
	value := fmt.Sprintf(`{"energy": "%d"}`, energy)
	write := &runtime.StorageWrite {
		// The Collection field allows you to group similar storage objects into a single searchable field.
		Collection: "some-collection-name",
		// The Key field uniquely identifies this storage object for this user within the collection.
		Key:        "some-key-name",
		// The UserID field can be the admin user, or any other existing user's User ID.
		UserID:     userID,
		// The actual data to store in this storage object. This must be valid JSON.
		Value:      value,
	if _, err := nk.StorageWrite(ctx, []*runtime.StorageWrite{write}); err != nil {
		return err
	return nil

The starter-game-template uses Nakama's storage layer to store a global cryptographic key and Persona Tag information for each user. See the Cardinal Plugin page for more details.


Nakama allows for the creation of matches that clients can connect to be notified about game updates. Cardinal maintains its own game state separate from Nakama's match system, however the Cardinal plugin does use Nakama's matchmaking system to broadcast state changes to users.

On startup, Nakama makes a single global match that any client can discover and join. The match can be viewed in the Nakama console by selecting the "Matches" item in the sidebar.