Function Reference

The code runtime built into the server includes a module with functions to implement various logic and custom behavior. It is easy to define authoritative code and conditions on input received by clients.

Nakama module

This module contains all the core gameplay APIs, all registration functions used at server startup, utilities for various codecs, and cryptographic primitives.

local nk = require("nakama")
import (
  "github.com/heroiclabs/nakama/runtime"
)

Note

All Lua code examples assume the "nakama" module has been imported.

All Go functions will have nk runtime.NakamaModule avaiable as a parameter that may be used to access server runtime functions. A context will also be supplied in function input arguments.

account

Get account

Get all account information for a given user ID.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
user_id string string User ID to fetch information for. Must be valid UUID.

Returns

All account information including wallet, device IDs and more.

Example

local account = nk.account_get_id("8f4d52c7-bf28-4fcf-8af2-1d4fcf685592")
nk.logger_info(("Wallet is: %s"):format(nk.json_encode(account.wallet)))
account, err := nk.AccountGetId(ctx, "8f4d52c7-bf28-4fcf-8af2-1d4fcf685592")
if err != nil {
  // Handle error.
} else {
  logger.Info("Wallet is: %v", account.Wallet)
}

Update account

Update a user account.

Parameters

Note

The order of parameters is different in Lua and Go. Check examples below

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
user_id string string User ID for which the information is to be updated. Must be valid UUID.
metadata map[string]interface{} table Metadata to update. Use nil if it is not being updated.
username string string Username to be set. Must be unique. Use "" (Go) or nil (Lua) if it is not being updated.
display_name string string Display name to be updated. Use "" (Go) or nil (Lua) if it is not being updated.
timezone string string Timezone to be updated. Use "" (Go) or nil (Lua) if it is not being updated.
location string string Location to be updated. Use "" (Go) or nil (Lua) if it is not being updated.
language string string Lang tag to be updated. Use "" (Go) or nil (Lua) if it is not being updated.
avatar_url string string User's avatar URL. Use "" (Go) or nil (Lua) if it is not being updated.

Example

local user_id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521" -- Some user ID.
local metadata = {}
local username = ""
local display_name = nil
local timezone = nil
local location = nil
local language = nil
local avatar_url = nil
nk.account_update_id(user_id, metadata, username, display_name, timezone, location, language, avatar_url)
userID := "4ec4f126-3f9d-11e7-84ef-b7c182b36521" // Some user ID.
username := ""
metadata := make(map[string]interface{})
displayName := ""
timezone := ""
location := ""
langTag := ""
avatarUrl := ""
if err := nk.AccountUpdateId(ctx, userID, username, metadata, displayName, timezone, location, langTag, avatarUrl); err != nil {
  // Handle error.
  logger.Error("Account update error: %s", err.Error())
}

aes128

aes128_decrypt (input, key)

AES decrypt input with the key. Key must be 16 bytes long.

Parameters

Param Type Description
input string The string which has been aes128 encrypted.
key string 16 bytes decryption key.

Returns

The decrypted input.

Example

local plaintext = nk.aes128_decrypt("48656C6C6F20776F726C64", "goldenbridge_key")
// Use the standard Go crypto package.
import "crypto/aes"

aes128_encrypt (input, key)

AES encrypt input with the key. Key must be 16 bytes long.

Parameters

Param Type Description
input string The string which will be aes128 encrypted.
key string 16 bytes encryption key.

Returns

The encrypted input.

Example

local cyphertext = nk.aes128_encrypt("48656C6C6F20776F726C64", "goldenbridge_key")
// Use the standard Go crypto package.
import "crypto/aes"

authenticate

Authenticate Custom

Authenticate user and create a session token using a custom authentication managed by an external service or source not already supported by Nakama. Best suited for use with existing external identity services.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
id string string Custom ID to use to authenticate the user. Must be between 6-128 characters.
username string string Optional username. If left empty, one is generated.
create bool bool Create user if one didn't exist previously. By default this is set to true.

Returns

The user's ID, username, and a boolean flag indicating if the account was just created (true) or already existed (false).

Example

local user_id, username, created = nk.authenticate_custom("48656C6C6F20776F726C64", "username", true)
userid, username, created, err := AuthenticateCustom(ctx, "48656C6C6F20776F726C64", "username", true)
if err != nil {
  // Handle error.
}

Authenticate Device

Authenticate user and create a session token using a device identifier.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
id string string Device ID to use to authenticate the user. Must be between 1 - 128 characters.
username string string Optional username. If left empty, one is generated.
create bool bool Create user if one didn't exist previously. By default this is set to true.

Returns

The user's ID, username, and a boolean flag indicating if the account was just created (true) or already existed (false).

Example

local user_id, username, created = nk.authenticate_device("48656C6C6F20776F726C64", "username", true)
userid, username, created, err := AuthenticateDevice(ctx, "48656C6C6F20776F726C64", "username", true)
if err != nil {
  // Handle error.
}

Authenticate Email

Authenticate user and create a session token using an email address and password.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
email string string Email address to use to authenticate the user. Must be between 10-255 characters.
password string string Password to set - must be longer than 8 characters.
username string string Optional username. If left empty, one is generated.
create bool bool Create user if one didn't exist previously. By default this is set to true.

Returns

The user's ID, username, and a boolean flag indicating if the account was just created (true) or already existed (false). Go function will also return error, if any, as fourth return value.

Example

local user_id, username, created = nk.authenticate_email("email@example.com", "48656C6C6F20776F726C64", "username", true)
userid, username, created, err := AuthenticateEmail(ctx, "email@example.com", "48656C6C6F20776F726C64", "username", true)
if err != nil {
  // Handle error.
}

Authenticate Facebook

Authenticate user and create a session token using a Facebook account token.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
token string string Facebook OAuth access token.
import bool bool Whether to import facebook friends after authenticated automatically. This is true by default.
username string string Optional username. If left empty, one is generated.
create bool bool Create user if one didn't exist previously. By default this is set to true.

Returns

The user's ID, username, and a boolean flag indicating if the account was just created (true) or already existed (false).

Example

local user_id, username, created = nk.authenticate_facebook("some-oauth-access-token", true, "username", true)
userid, username, created, err := AuthenticateFacebook(ctx, "some-oauth-access-token", true, "username", true)
if err != nil {
  // Handle error.
}

Authenticate Game Center

Authenticate user and create a session token using Apple Game Center credentials.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
player_id string string PlayerId provided by GameCenter.
bundle_id string string BundleId of your app on iTunesConnect.
timestamp int64 number Timestamp at which Game Center authenticated the client and issued a signature.
salt string string A random string returned by Game Center authentication on client.
signature string string A signature returned by Game Center authentication on client.
public_key_url string string A url to the publick key returned by Game Center authentication on client.
username string string Optional username. If left empty, one is generated.
create bool bool Create user if one didn't exist previously. By default this is set to true.

Returns

The user's ID, username, and a boolean flag indicating if the account was just created (true) or already existed (false).

local user_id, username, created = nk.authenticate_gamecenter (player_id, bundle_id, timestamp, salt, signature, public_key_url, username, create)
userid, username, created, err := AuthenticateGameCenter(ctx, playerID, bundleID, timestamp, salt, signature, publicKeyUrl, username, create)
if err != nil {
  // Handle error.
}

Authenticate Google

Authenticate user and create a session token using a Google ID token.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
token string string Google OAuth access token.
username string string Optional username. If left empty, one is generated.
create bool bool Create user if one didn't exist previously. By default this is set to true.

Returns

The user's ID, username, and a boolean flag indicating if the account was just created (true) or already existed (false).

Example

local user_id, username, created = nk.authenticate_google("some-id-token", "username", true)
userid, username, created, err := AuthenticateGoogle(ctx, "some-id-token", "username", true)
if err != nil {
  // Handle error.
}

Authenticate Steam

Authenticate user and create a session token using a Steam account token.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
token string string Steam token.
username string string Optional username. If left empty, one is generated.
create bool bool Create user if one didn't exist previously. By default this is set to true.

Returns

The user's ID, username, and a boolean flag indicating if the account was just created (true) or already existed (false).

Example

local user_id, username, created = nk.authenticate_steam("steam-token", "username", true)
userid, username, created, err := AuthenticateGoogle(ctx, "steam-token", "username", true)
if err != nil {
  // Handle error.
}

Authentication token generator

Generate a Nakama session token from a username. This is not the same as an authentication mechanism because a user does not get created and input is not checked against the database.

This is useful if you have an external source of truth where users are registered.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
user_id string string User ID you'd like to use to generated the token.
username string string Username information to embed in the token. This is mandatory.
expires_at number string Number of seconds the token should be valid for. Optional, defaults to server configured expiry time.

Returns

The session token created for the given user details, an the expiry time of the token expressed as UTC seconds.

Example

local token, exp = nk.authenticate_token_generate("user_id", "username")
nk.logger_info(("Access token: %q, valid for %q seconds"):format(token, exp))
token, validity, err := AuthenticateTokenGenerate("user_id", "username", 0)
if err != nil {
  // Handle error.
} else {
  logger.Info("Access token: %q, valid for %v seconds", token, validity)
}

base16

Base 16 Decode

Base 16 decode the input.

Parameters

Param Type Description
input string The string which will be base16 decoded.

Returns

The base 16 decoded input.

Example

local decoded = nk.base16_decode("48656C6C6F20776F726C64")
nk.logger_info(decoded) -- Outputs "Hello world".
// Use the standard Go encoding package.
import "encoding/hex"

Base 16 encode

Base 16 encode the input.

Parameters

Param Type Description
input string The string which will be base16 encoded.

Returns

The base 16 encoded input.

Example

local encoded = nk.base16_encode("Hello world")
nk.logger_info(encoded) -- Outputs "48656C6C6F20776F726C64".
// Use the standard Go encoding package.
import "encoding/hex"

base64

Base64 Decode

Base 64 decode the input.

Parameters

Param Type Description
input string The string which will be base64 decoded.

Returns

The base 64 decoded input.

Example

local decoded = nk.base64_decode("SGVsbG8gd29ybGQ=")
nk.logger_info(decoded) -- Outputs "Hello world".
// Use the standard Go encoding package.
import "encoding/base64"

Base64 Encode

Base 64 encode the input.

Parameters

Param Type Description
input string The string which will be base64 encoded.

Returns

The base 64 encoded input.

Example

local encoded = nk.base64_encode("Hello world")
nk.logger_info(encoded) -- Outputs "SGVsbG8gd29ybGQ=".
// Use the standard Go encoding package.
import "encoding/base64"

Base64 URL Decode

Base 64 URL decode the input.

Parameters

Param Type Description
input string The string which will be base64 URL decoded.

Returns

The base 64 URL decoded input.

Example

local decoded = nk.base64url_decode("SGVsbG8gd29ybGQ=")
nk.logger_info(decoded) -- Outputs "Hello world".
// Use the standard Go encoding package.
import "encoding/base64"

Base64 URL Encode

Base 64 URL encode the input.

Parameters

Param Type Description
input string The string which will be base64 URL encoded.

Returns

The base 64 URL encoded input.

Example

local encoded = nk.base64url_encode("Hello world")
nk.logger_info(encoded) -- Outputs "SGVsbG8gd29ybGQ=".
// Use the standard Go encoding package.
import "encoding/base64"

bcrypt

BCrypt Hash

Generate one-way hashed string using bcrypt.

Parameters

Param Type Description
input string The string which will be bcrypted.

Returns

The hashed input.

Example

local hashed = nk.bcrypt_hash("Hello World")
nk.logger_info(hashed)
// Use the standard Go crypto package.
import "golang.org/x/crypto/bcrypt"

BCrypt Compare

Compare hashed input against a plaintext input.

Parameters

Param Type Description
hash string The string that is already bcrypted.
plaintext string The string that is to be compared.

Returns

True if they are the same, false otherwise.

Example

local is_same = nk.bcrypt_compare("$2a$04$bl3tac7Gwbjy04Q8H2QWLuUOEkpoNiAeTxazxi4fVQQRMGbMaUHQ2", "123456")
nk.logger_info(is_same) -- Outputs true.
// Use the standard Go crypto package.
import "golang.org/x/crypto/bcrypt"

cron

Cron Next

Parses a CRON expression and a timestamp in UTC seconds, and returns the next matching timestamp in UTC seconds.

Parameters

Param Type Description
expression string A valid CRON expression in standard format, for example " * * *".
timestamp number A time value expressed as UTC seconds.

Returns

The next UTC seconds timestamp that matches the given CRON expression, and is immediately after the given timestamp.

Example

-- Based on the current time, return the UTC seconds value representing the
-- nearest upcoming Monday at 00:00 UTC (midnight.)
local expr = "0 0 * * 1"
local ts = os.time()
local next = nk.cron_next(expr, ts)
// Use a Go CRON package, for example:
import "github.com/robfig/cron"

groups

Group Create

Setup a group with various configuration settings. The group will be created if they don't exist or fail if the group name is taken.

A user ID must be given as they'll be made group superadmin.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
user_id string string The user ID to be associcated as the group superadmin. Mandatory field.
name string string Group name, must be set and unique.
creator_id string string The user ID to be associcated as creator. If not set, system user will be set.
lang string string Group language. Will default to 'en'.
description string string Group description, can be left empty.
avatar_url string string URL to the group avatar, can be left empty.
open bool bool Whether the group is for anyone to join, or members will need to send invitations to join. Defaults to false.
metadata map[string]interface{} table Custom information to store for this group.
max_count int number Maximum number of members to have in the group. Defaults to 100.

Example

local metadata = { -- Add whatever custom fields you want.
  my_custom_field = "some value"
}

local user_id = "dcb891ea-a311-4681-9213-6741351c9994"
local creator_id = "dcb891ea-a311-4681-9213-6741351c9994"
local name = "Some unique group name"
local description = "My awesome group."
local lang = "en"
local open = true
local creator_id = "4c2ae592-b2a7-445e-98ec-697694478b1c"
local avatar_url = "url://somelink"
local maxMemberCount = 100

nk.group_create(user_id, name, creator_id, lang, description, avatar_url, open, metadata, maxMemberCount)
metadata := map[string]interface{}{ // Add whatever custom fields you want.
  "my_custom_field": "some value",
}

userID := "dcb891ea-a311-4681-9213-6741351c9994"
creatorID := "dcb891ea-a311-4681-9213-6741351c9994"
name := "Some unique group name"
description := "My awesome group."
langTag := "en"
open := true
avatarURL := "url://somelink"
maxCount := 100

if group, err := nk.GroupCreate(ctx, userID, name, creatorID, langTag, description, avatarURL, open, metadata, maxCount); err != nil {
  logger.Error("Could not create group: %s", err.Error())
}

Group Delete

Delete a group.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
group_id string string The group ID to delete.

Example

group_id = "f00fa79a-750f-11e7-8626-0fb79f45ff97"
nk.group_delete(group_id)
groupID := "f00fa79a-750f-11e7-8626-0fb79f45ff97"
if group, err := nk.GroupDelete(ctx, groupID); err != nil {
  logger.Error("Could not delete group: %s", err.Error())
}

Group Update

Update a group with various configuration settings. The group which is updated can change some or all of its fields.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
group_id string string The group ID to update.
name string string Group name, can be empty if not changed.
creator_id string string The user ID to be associcated as creator. Can be empty if not changed.
lang string string Group language. Empty if not updated.
description string string Group description, can be left empty if not updated.
avatar_url string string URL to the group avatar, can be left empty if not updated.
open bool bool Whether the group is for anyone to join or not. Use nil if field is not being updated.
metadata map[string]interface{} table Custom information to store for this group. Use nil if field is not being updated.
max_count int number Maximum number of members to have in the group. Use 0 if field is not being updated.

Example

local metadata = {
  some_field = "some value"
}
group_id = "f00fa79a-750f-11e7-8626-0fb79f45ff97"
description = "An updated description."

nk.group_update(group_id, "", "", "", description, "", nil, metadata, 0)
metadata := map[string]interface{}{ // Add whatever custom fields you want.
  "my_custom_field": "some value",
}

groupID := "dcb891ea-a311-4681-9213-6741351c9994"
description := "An updated description."

if err := nk.GroupUpdate(ctx, groupID, "", "", "", description, "", true, metadata, 0); err != nil {
  logger.Error("Could not update group: %s", err.Error())
}

Group Users List

List all members, admins and superadmins which belong to a group. This also list incoming join requests too.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
group_id string string The Id of the group who's members, admins and superadmins you want to list.

Returns

The user information for members, admins and superadmins for the group. Also users who sent a join request as well.

Example

local group_id = "a1aafe16-7540-11e7-9738-13777fcc7cd8"
local members = nk.group_users_list(group_id)
for _, m in ipairs(members)
do
  local msg = ("Member username %q has state %q"):format(m.username, m.state)
  nk.logger_info(msg)
end
groupID := "dcb891ea-a311-4681-9213-6741351c9994"

if groupUserList, err := nk.GroupUsersList(ctx, groupID); err != nil {
  logger.Error("Could not get user list for group: %s", err.Error())
} else {
  for _, member := range groupUserList {
    // States are => 0: Superadmin, 1: Admin, 2: Member, 3: Requested to join
    logger.Info("Member username %s has state %d", member.GetUser().Username, member.GetState())
  }
}

Groups Get by ID

Fetch one or more groups by their ID.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
group_ids []string table A set of strings of the ID for the groups to get.

Returns

A table (array) of groups with their fields.

Example

local group_ids = {"0BF154F1-F7D1-4AAA-A060-5FFED3CDB982", "997C0D18-0B25-4AEC-8331-9255BD36665D"}
local groups = nk.groups_get_id(group_ids)
for _, g in ipairs(groups)
do
  local msg = ("Group name %q with id %q"):format(g.name, g.id)
  nk.logger_info(msg)
end
groupID := "dcb891ea-a311-4681-9213-6741351c9994"

if groups, err := nk.GroupsGetId(ctx, []string{groupID}); err != nil {
  logger.Error("Could not get groups: %s", err.Error())
} else {
  for _, group := range groups {
    logger.Info("Group name %s with id %s.", group.Name, group.Id)
  }
}

Groups List for a user

List all groups which a user belongs to and whether they've been accepted into the group or if it's an invite.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
user_id string string The Id of the user who's groups you want to list.

Returns

A list of groups for the user.

Example

local user_id = "64ef6cb0-7512-11e7-9e52-d7789d80b70b"
local groups = nk.user_groups_list(user_id)
for _, g in ipairs(groups)
do
  local msg = ("Group name %q with id %q"):format(g.name, g.id)
  nk.logger_info(msg)
end
userID := "dcb891ea-a311-4681-9213-6741351c9994"

if groups, err := nk.UserGroupsList(ctx, userID); err != nil {
  logger.Error("Could not list groups: %s", err.Error())
} else {
  for _, group := range groups {
    logger.Printf("Group name %s with id %s.", group.GetGroup().Name, group.GetGroup().Id)
  }
}

hmac

HMAC SHA256 Hash

Create a HMAC-SHA256 hash from input and key.

Parameters

Param Type Description
input string Plaintext input to hash.
key number Hashing key.

Returns

Hashed input using the key.

Example

local hash = nk.hmac_sha256_hash("encryptthis", "somekey")
print(hash)
// Use the standard Go crypto package.
import "crypto/hmac"

http

http_request (url, method, headers, content)

Send a HTTP request and receive the result as a Lua table.

Parameters

Param Type Description
url string The URL of the web resource to request.
method string The HTTP method verb used with the request.
headers table A table of headers used with the request.
content string The bytes to send with the request.

Returns

code, headers, body - Multiple return values for the HTTP response.

Example

local url = "https://google.com/"
local method = "HEAD"
local headers = {
  ["Content-Type"] = "application/json",
  ["Accept"] = "application/json"
}
local content = nk.json_encode({}) -- encode table as JSON string
local success, code, headers, body = pcall(nk.http_request, url, method, headers, content)
if (not success) then
  nk.logger_error(("Failed %q"):format(code))
elseif (code >= 400) then
  nk.logger_error(("Failed %q %q"):format(code, body))
else
  nk.logger_info(("Success %q %q"):format(code, body))
end
// Use the standard Go HTTP package.
import "net/http"

json

json_decode (input)

Decode the JSON input as a Lua table.

Parameters

Param Type Description
input string The JSON encoded input.

Returns

A Lua table with the decoded JSON.

Example

local json = nk.json_decode('{"hello": "world"}')
nk.logger_info(json.hello)
// Use the standard Go JSON package.
import "encoding/json"

json_encode (input)

Encode the input as JSON.

Parameters

Param Type Description
input string The input to encode as JSON.

Returns

The encoded JSON string.

Example

local input = {["some"] = "json"}
local json = nk.json_encode(input)
nk.logger_info(json) -- Outputs '{"some": "json"}'.
// Use the standard Go JSON package.
import "encoding/json"

leaderboards

Leaderboard Create

Setup a new dynamic leaderboard with the specified ID and various configuration settings. The leaderboard will be created if it doesn't already exist, otherwise its configuration will not be updated.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
id string string The unique identifier for the new leaderboard. This is used by clients to submit scores.
authoritative bool bool Mark the leaderboard as authoritative which ensures updates can only be made via the Lua runtime. No client can submit a score directly. Optional in Lua. Default false.
sort string string The sort order for records in the leaderboard; possible values are "asc" or "desc". Optional in Lua. Default "desc".
operator string string The operator that determines how scores behave when submitted; possible values are "best", "set", or "incr". Optional in Lua. Default "best".
reset string string The cron format used to define the reset schedule for the leaderboard. This controls when a leaderboard is reset and can be used to power daily/weekly/monthly leaderboards. Optional in Lua.
metadata map[string]interface{} table The metadata you want associated to the leaderboard. Some good examples are weather conditions for a racing game. Optional in Lua.

Example

local id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
local authoritative = false
local sort = "desc"
local operator = "best"
local reset = "0 0 * * 1"
local metadata = {
  weather_conditions = "rain"
}
nk.leaderboard_create(id, authoritative, sort, operator, reset, metadata)
id := "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
authoritative := false
sortOrder := "desc"
operator := "best"
resetSchedule := "0 0 * * 1"
metadata := map[string]interface{}{
  "weather_conditions": "rain",
}

if err := nk.LeaderboardCreate(ctx, id, authoritative, sortOrder, operator, resetSchedule, metadata); err != nil {
  logger.Error("Error creating leaderboard: %s", err.Error())
}

Leaderboard Delete

Delete a leaderboard and all scores that belong to it.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
id string string The unique identifier for the leaderboard to delete. Mandatory field.

Example

local id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
nk.leaderboard_delete(id)
id := "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
if err := nk.LeaderboardDelete(ctx, id); err != nil {
  logger.Error("Error deleting leaderboard: %s", err.Error())
}

Leaderboard Record write

Use the preconfigured operator for the given leaderboard to submit a score for a particular user.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
id string string The unique identifier for the leaderboard to submit to. Mandatory field.
owner string string The owner of this score submission. Mandatory field.
username string string The owner username of this score submission, if it's a user. Optional in Lua.
score int64 number The score to submit. Optional in Lua. Default 0.
subscore int64 number A secondary subscore parameter for the submission. Optional in Lua. Default 0.
metadata map[string]interface{} table The metadata you want associated to this submission. Some good examples are weather conditions for a racing game. Optional in Lua.

Example

local metadata = {
  weather_conditions = "rain"
}
local id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
local owner = "4c2ae592-b2a7-445e-98ec-697694478b1c"
local username = "02ebb2c8"
local score = 10
local subscore = 0
nk.leaderboard_record_write(id, owner, username, score, subscore, metadata)
id := "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
ownerID := "4c2ae592-b2a7-445e-98ec-697694478b1c"
username := "02ebb2c8"
score := int64(10)
subscore := int64(0)
metadata := map[string]interface{}{
  "weather_conditions": "rain",
}

if record, err := nk.LeaderboardRecordWrite(ctx, id, ownerID, username, score, subscore, metadata); err != nil {
  logger.Error("Error writing leaderboard record: %s", err.Error())
}

Leaderboard Record delete

Remove an owner's record from a leaderboard, if one exists.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
id string string The unique identifier for the leaderboard to delete from. Mandatory field.
owner string string The owner of the score to delete. Mandatory field.

Example

local id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
local owner = "4c2ae592-b2a7-445e-98ec-697694478b1c"
nk.leaderboard_record_delete(id, owner)
id := "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
ownerID := "4c2ae592-b2a7-445e-98ec-697694478b1c"

if err := nk.LeaderboardRecordDelete(ctx, id, ownerID); err != nil {
  logger.Error("Error deleting leaderboard record: %s", err.Error())
}

Leaderboard Record list

List records on the specified leaderboard, optionally filtering to only a subset of records by their owners. Records will be listed in the preconfigured leaderboard sort order.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
id string string The unique identifier of the leaderboard to list from. Mandatory field.
owners []string table Table array of owners to filter to. Optional in Lua.
limit int number The maximum number of records to return, from 10 to 100. Optional in Lua.
cursor string string A cursor used to fetch the next page when applicable. Optional in Lua.

Returns

A page of leaderboard records, a list of owner leaderboard records (empty if the owners input parameter is not set), an optional next page cursor that can be used to retrieve the next page of records (if any), and an optional previous page cursor that can be used to retrieve the previous page of records (if any).

Example

local id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
local owners = {}
local limit = 10
local records, owner_records, next_cursor, prev_cursor = nk.leaderboard_records_list(id, owners, limit)
id := "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
ownerIDs := []string{}
limit := 10
cursor := ""
expiry := int64(0)

if records, ownerRecords, prevCursor, nextCursor, err := nk.LeaderboardRecordsList(ctx, id, ownerIDs, limit, cursor, expiry); err != nil {
  logger.Error("Unable to fetch records: %s", err.Error())
}

logger

Logger Error

Write an ERROR level message to the server logs.

Parameters

Param Go type Lua type Description
message string string The message to write to server logs with ERROR level severity.
vars - - Variables to replace placeholders in message.

Example

local message = ("%q - %q"):format("hello", "world")
nk.logger_error(message)
logger.Error("%s - %s", "hello", "world")

Logger Info

Write an INFO level message to the server logs.

Parameters

Param Go type Lua type Description
message string string The message to write to server logs with INFO level severity.
vars - - Variables to replace placeholders in message.

Example

local message = ("%q - %q"):format("hello", "world")
nk.logger_info(message)
logger.Info("%s - %s", "hello", "world")

Logger Warning

Write an WARN level message to the server logs.

Parameters

Param Go type Lua type Description
message string string The message to write to server logs with WARN level severity.
vars - - Variables to replace placeholders in message.

Example

local message = ("%q - %q"):format("hello", "world")
nk.logger_warn(message)
logger.Warn("%s - %s", "hello", "world")

match

Match Create

Create a new authoritative realtime multiplayer match running on the given runtime module name. The given params are passed to the match's init hook.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
module string string The name of an available runtime module that will be responsible for the match. In Go, this was registered in InitModule. In Lua, this was provided as an independent match handler module.
params map[string]interface{} any Any value to pass to the match's init hook. Optional in Lua.

Returns

(string) - The match ID of the newly created match. Clients can immediately use this ID to join the match.

Example

-- Assumes you've registered a runtime module with a path of "my/match/module.lua".
local module = "my.match.module"
local params = { some = "data" }
local match_id = nk.match_create(module, params)
// Assumes you've registered a match with initializer.RegisterMatch("my.match.module", ...)
modulename := "my.match.module"
params := map[string]interface{}{
  "some": "data",
}
if matchId, err := nk.MatchCreate(ctx, modulename, params); err != nil {
  return "", err
}

Match List

List currently running realtime multiplayer matches and optionally filter them by authoritative mode, label, and current participant count.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
limit int number The maximum number of matches to list. Optional in Lua. Default 1.
authoritative bool bool Boolean true if listing should only return authoritative matches, false to only return relayed matches, nil to return both. Optional in Lua. Default false (Go) or nil (Lua).
label string string A label to filter authoritative matches by. Optional in Lua. Default "" (Go) or nil (Lua) meaning any label matches.
min_size int number Inclusive lower limit of current match participants. Optional in Lua.
max_size int number Inclusive upper limit of current match participants. Optional in Lua.
query string - Additional query parameters to shortlist matches

Example

-- List at most 10 matches, not authoritative, and that
-- have between 2 and 4 players currently participating.
local limit = 10
local authoritative = false
local label = nil
local min_size = 2
local max_size = 4
local matches = nk.match_list(limit, authoritative, label, min_size, max_size)
for _, m in ipairs(matches)
do
  local message = ("Found match with id: %q"):format(m.match_id)
  nk.logger_info(message)
end
// List at most 10 matches, not authoritative, and that
// have between 2 and 4 players currently participating.
limit := 10
isauthoritative := false
label := ""
min_size := 2
max_size := 4
if matches, err := nk.MatchList(ctx, limit, isauthoritative, label, min_size, max_size, ""); err != nil {
  // Handle error.
} else {
  for _, match := range matches {
    logger.Info("Found match with id: %s", match.GetMatchId())
  }
}

md5

md5_hash (input)

Create an md5 hash from the input.

Parameters

Param Type Description
input string The input string to hash.

Example

local input = "somestring"
local hashed = nk.md5_hash(input)
nk.logger_info(hashed)
// Use the standard Go crypto package.
import "crypto/md5"

notifications

Notification Send

Send one in-app notification to a user. Have a look at the section on in-app notifications.

Parameters

| Param | Go type | Lua type | Description | | ----- | ---- | ----------- | | ctx | context.Context | - | Context object represents information about the match and server for information | | subject | string | string | Notification subject. Must be set. | | content | map[string]interface{} | table | Notification content. Must be set but can be an empty table. | | code | int | number | Notification code to use. Must be equal or greater than 0. | | sender_id | string | string | The sender of this notification. If left empty, it will be assumed that it is a system notification. | | persistent | bool | bool | Whether to record this in the database for later listing. Defaults to false. |

Example

local subject = "You've unlocked level 100!"
local content = nk.json_encode({
  reward_coins = 1000
})
local user_id = "4c2ae592-b2a7-445e-98ec-697694478b1c" -- who to send
local sender_id = "dcb891ea-a311-4681-9213-6741351c9994" -- who the message if from
local code = 101
local persistent = true

nk.notification_send(user_id, subject, content, code, sender_id, persistent)
subject := "You've unlocked level 100!"
content := map[string]interface{}{
  "reward_coins": 1000,
}
userID := "4c2ae592-b2a7-445e-98ec-697694478b1c"   // who to send
senderID := "dcb891ea-a311-4681-9213-6741351c9994" // who the message if from
code := 101
persistent := true

nk.NotificationSend(ctx, userID, subject, content, code, senderID, persistent)

Notifications Send

Send one or more in-app notifications to a user. Have a look at the section on in-app notifications.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
notifications []*runtime.NotifictionSend table A list of notifications to be sent together.

Example

local subject = "You've unlocked level 100!"
local content = nk.json_encode({
  reward_coins = 1000
})
local user_id = "4c2ae592-b2a7-445e-98ec-697694478b1c" -- who to send
local sender_id = "dcb891ea-a311-4681-9213-6741351c9994" -- who the message if from
local code = 101

local new_notifications = {
  { subject = subject, content = content, sender_id = sender_id, user_id = user_id, code = code, persistent = true}
}
nk.notifications_send(new_notifications)
notifications := []*runtime.NotificationSend{
  &runtime.NotificationSend{
    UserID:     "4c2ae592-b2a7-445e-98ec-697694478b1c",
    Subject:    "You've unlocked level 100!",
    Content:    map[string]interface{}{"reward_coins": 1000},
    Code:       101,
    Persistent: true,
  },
  &runtime.NotificationSend{
    UserID:     "69769447-b2a7-445e-98ec-8b1c4c2ae592",
    Subject:    "You've unlocked level 100!",
    Content:    map[string]interface{}{"reward_coins": 1000},
    Code:       101,
    Persistent: true,
  },
}
if err := nk.NotificationsSend(ctx, notifications); err != nil {
  logger.Error("Could not send notifications: %s", err.Error())
}

register hooks

Register Matchmaker Matched

Registers a function that will be called when matchmaking finds opponents.

Parameters

Param Type Description
func function A function reference which will be executed on each matchmake completion.

Example

-- For example let's create a two player authoritative match.
local function matchmaker_matched(context, matchmaker_users)
  for _, m in ipairs(matched_users)
  do
    nk.logger_info(m.presence["user_id"])
    nk.logger_info(m.presence["session_id"])
    nk.logger_info(m.presence["username"])
    nk.logger_info(m.presence["node"])

    for _, p in ipairs(m.properties)
    do
      nk.logger_info(p)
    end
  end

  if #matchmaker_users ~= 2 then
    return nil
  end

  if matchmaker_users[1].properties["mode"] ~= "authoritative" then
    return nil
  end
  if matchmaker_users[2].properties["mode"] ~= "authoritative" then
    return nil
  end

  return nk.match_create("match", {debug = true, expected_users = matchmaker_users})
end
nk.register_matchmaker_matched(matchmaker_matched)
func MakeMatch(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, entries []runtime.MatchmakerEntry) (string, error) {
  for _, e := range entries {
    logger.Info(e.GetPresence().GetUserId())
    logger.Info(e.GetPresence().GetSessionId())
    logger.Info(e.GetPresence().GetUsername())
    logger.Info(e.GetPresence().GetNode())

    for k, v := range e.GetProperties() {
      logger.Info("%v: %v", k, v)
    }
  }

  params := map[string]interface{}{
    "debug":          true,
    "expected_users": entries,
  }

  matchId, err := nk.MatchCreate(ctx, "pingpong", params)
  if err != nil {
    return "", err
  }

  return matchId, nil
}

// Register as matchmaker matched hook, this call should be in InitModule.
if err := initializer.RegisterMatchmakerMatched(MakeMatch); err != nil {
  logger.Error("Unable to register: %v", err)
  return err
}

Expected to return an authoritative match ID for a match ready to receive these users, or nil if the match should proceed through the peer-to-peer relayed mode.


Register Request After

Register a function with the server which will be executed after every non-realtime message as specified while registering the function.

This can be used to apply custom logic to standard features in the server. It will not block the execution pipeline. The logic will be executed in parallel to any response message sent back to a client. Have a look at the section on runtime code basics.

Parameters

Param Go type Lua type Description
func function function A function reference which will be executed on each msgname message (in Lua). In Go, there are separate functions for each of those actions.
msgname - string The specific message name to execute the func function after.

For a complete list of RegisterBefore functions, refer this page. For message names (in Lua), have a look at this section.

Example

local function my_func(context, payload)
  -- Run some code.
end
nk.register_req_after(my_func, "FriendsAdd")
func AfterAddFriends(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, in *api.AddFriendsRequest) error {
  // Run some code.
}

// Register as an appropriate after hook, this call should be in InitModule.
if err := initializer.RegisterAfterAddFriends(AfterAddFriends); err != nil {
  logger.Error("Unable to register: %v", err)
  return err
}

Register Request Before

Register a function with the server which will be executed before any non-realtime message with the specified message name. This can be used to apply custom conditions to standard features in the server. Have a look at the section on runtime code basics.

Parameters

Param Go type Lua type Description
func function function A function reference which will be executed on each msgname message (in Lua). In Go, there are separate functions for each of those actions.
msgname - string The specific message name to execute the func function after.

For a complete list of RegisterBefore functions, refer this page. For message names in lua, have a look at this section.

Note

The function should pass the payload input back as a return argument so the pipeline can continue to execute the standard logic. If you return nil, the server will stop processing that message. Any other return argument will result in an error.

Example

local function my_func(context, payload)
  -- Run some code.
  return payload -- Important!
end
nk.register_req_before(my_func, "FriendsAdd")
func BeforeAddFriends(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, in *api.AddFriendsRequest) (*api.AddFriendsRequest, error) {
  // Run some code.
  return in, nil // Important!
}

// Register as an appropriate before hook, this call should be in InitModule.
if err := initializer.RegisterBeforeAddFriends(BeforeAddFriends); err != nil {
  logger.Error("Unable to register: %v", err)
  return err
}

Register Realtime After

Register a function with the server which will be executed after every realtime message with the specified message name.

This can be used to apply custom logic to standard features in the server. It will not block the execution pipeline. The logic will be executed in parallel to any response message sent back to a client. Have a look at the section on runtime code basics.

Parameters

Param Type Description
func function A function reference which will be executed on each msgname message.
msgname string The specific message name to execute the func function after.

For message names, have a look at this section.

Example

local function my_func(context, payload)
  -- Run some code.
end
nk.register_rt_after(my_func, "ChannelJoin")
func MyFunc(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime NakamaModule, envelope *rtapi.Envelope) error {
  // Run some code.
}

// Register as an appropriate after hook, this call should be in InitModule.
if err := initializer.RegisterAfterRt("ChannelJoin", MyFunc); err != nil {
  logger.Error("Unable to register: %v", err)
  return err
}

Register Realtime Before

Register a function with the server which will be executed before any realtime message with the specified message name. This can be used to apply custom conditions to standard features in the server. Have a look at the section on runtime code basics.

Parameters

Param Type Description
func function A function reference which will be executed on each msgname message.
msgname string The specific message name to execute the func function before.

For message names, have a look at this section.

Note

The function should pass the payload input back as a return argument so the pipeline can continue to execute the standard logic. If you return nil, the server will stop processing that message. Any other return argument will result in an error.

Example

local function my_func(context, payload)
  -- Run some code.
  return payload -- Important!
end
nk.register_rt_before(my_func, "ChannelJoin")
func MyFunc(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, envelope *rtapi.Envelope) (*rtapi.Envelope, error) {}
  // run some code
  return envelope, nil // For code to keep processing the request.
}

// Register as an appropriate before hook, this call should be in InitModule.
if err := initializer.RegisterBeforeRt("ChannelJoin", MyFunc); err != nil {
  logger.Error("Unable to register: %v", err)
  return err
}

Register RPC

Registers a function for use with client RPC to the server.

The ID can be any string identifier and is sent by the client. The ID is used to map the client RPC message to the specific function to execute. Have a look at the section on runtime code basics.

This function can also be used to register a HTTP endpoint within the server. Have a look at the Server to server docs for more info.

Parameters

Param Type Description
func function A function reference which will be executed on each RPC message.
id string The unique identifier used to register the func function for RPC.

Note

The func can pass nil/"" or a string back as a return argument which will returned as bytes in the RPC response.

Example

local function my_func(context, payload)
  -- Run some code.
  return payload
end
nk.register_rpc(my_func, "my_func_id")
func MyFunc(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
  logger.Info("Payload: %s", payload)
  return payload, nil
}

// Register as an RPC function, this call should be in InitModule.
if err := initializer.RegisterRpc("my_func_id", MyFunc); err != nil {
  logger.Error("Unable to register: %v", err)
  return err
}

run once

Run Once

The runtime environment allows you to run code that must only be executed only once. This is useful if you have custom SQL queries that you need to perform (like creating a new table) or to register with third party services.

Go runtime modules do not need a dedicated 'run once' function, use the InitModule function to achieve the same effect.

Parameters

Param Type Description
func function A function reference which will be executed only once.

Example

nk.run_once(function(context)
  -- This is to create a system ID that cannot be used via a client.
  local system_id = context.env["SYSTEM_ID"]

  nk.sql_exec([[
INSERT INTO users (id, username)
VALUES ($1, $2)
ON CONFLICT (id) DO NOTHING
  ]], { system_id, "system_id" })
end)
func InitModule(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, initializer runtime.Initializer) error {
  // This is to create a system ID that cannot be used via a client.
  var systemId string
  if env, ok := ctx.Value(runtime.RUNTIME_CTX_ENV).(map[string]string); ok {
    systemId = env["SYSTEM_ID"]
  }

  _, err := db.ExecContext(ctx, `
INSERT INTO users (id, username)
VALUES ($1, $2)
ON CONFLICT (id) DO NOTHING`, systemId, "system_id")
  if err != nil {
    logger.Error("Error: %s", err.Error())
  }

  return nil
}

storage

Storage Read

Fetch one or more records by their bucket/collection/keyname and optional user.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
object_ids []*runtime.StorageRead table A table / array of object identifiers to be fetched.

Returns

A table array of object result set.

Example

local user_id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521" -- some user ID.
local object_ids = {
  {collection = "save", key = "save1", user_id = user_id},
  {collection = "save", key = "save2", user_id = user_id},
  {collection = "save", key = "save3", user_id = user_id}
}
local objects = nk.storage_read(object_ids)
for _, r in ipairs(objects)
do
  local message = ("read: %q, write: %q, value: %q"):format(r.permission_read, r.permission_write, r.value)
  nk.logger_info(message)
end
userid := "4ec4f126-3f9d-11e7-84ef-b7c182b36521" // some user ID.
objectIds := []*runtime.StorageRead{
  &runtime.StorageRead{
    Collection: "save",
    Key: "save1",
    UserID: userid,
  },
  &runtime.StorageRead{
    Collection: "save",
    Key: "save2",
    UserID: userid,
  },
  &runtime.StorageRead{
    Collection: "save",
    Key: "save3",
    UserID: userid,
  },
}

records, err := nk.StorageRead(ctx, objectIds)
if err != nil {
  // Handle error.
} else {
  for _, record := range records {
    logger.Info("read: %d, write: %d, value: %s", record.PermissionRead, record.PermissionWrite, record.Value)
  }
}

Storage List

You can list records in a collection and page through results. The records returned can be filtered to those owned by the user or "" for public records which aren't owned by a user.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
user_id string string User ID or "" (empty string) for public records.
collection string string Collection to list data from.
limit int number Limit number of records retrieved. Min 10, Max 100.
cursor string string Pagination cursor from previous result. If none available set to nil or "" (empty string).

Returns

A table array of the records result set.

Example

local user_id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521" -- Some user ID.
local records = nk.storage_list(user_id "collection", 10, "")
for _, r in ipairs(records)
do
  local message = ("read: %q, write: %q, value: %q"):format(r.permission_read, r.permission_write, r.value)
  nk.logger_info(message)
end
userID := "4ec4f126-3f9d-11e7-84ef-b7c182b36521" // Some user ID.
if listRecords, nextCursor, err := nk.StorageList(ctx, userID, "collection", 10, ""); err != nil {
  // Handle error.
} else {
  for _, r := range listRecords {
    logger.Info("read: %d, write: %d, value: %s", r.PermissionRead, r.PermissionWrite, r.Value)
  }
}

Storage Delete

Remove one or more objects by their collection/keyname and optional user.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
object_ids []*runtime.StorageDelete table A table / array of object identifiers to be fetched.

Example

local user_id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521" -- Some user ID.
local friend_user_id = "8d98ee3f-8c9f-42c5-b6c9-c8f79ad1b820" -- Friend ID.
local object_ids = {
  {collection = "save", key = "save1", user_id = user_id},
  {collection = "save", key = "save2", user_id = user_id},
  {collection = "public", key = "progress", user_id = friend_user_id}
}
nk.storage_delete(object_ids)
userID := "4ec4f126-3f9d-11e7-84ef-b7c182b36521"       // Some user ID.
friendUserID := "8d98ee3f-8c9f-42c5-b6c9-c8f79ad1b820" // Friend ID.
objectIds := []*runtime.StorageDelete{
  &runtime.StorageDelete{
    Collection: "save",
    Key:        "save1",
    UserID:     userID,
  },
  &runtime.StorageDelete{
    Collection: "save",
    Key:        "save2",
    UserID:     userID,
  },
  &runtime.StorageDelete{
    Collection: "public",
    Key:        "progress",
    UserID:     friendUserID,
  },
}

if err := nk.StorageDelete(ctx, objectIds); err != nil {
  // Handle error.
}

Storage Write

Write one or more objects by their collection/keyname and optional user.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
object_ids []*runtime.StorageWrite table A table / array of object identifiers to be fetched.

Example

local user_id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521" -- Some user ID.
local new_objects = {
  {collection = "save", key = "save1", user_id = user_id, value = {}},
  {collection = "save", key = "save2", user_id = user_id, value = {}},
  {collection = "save", key = "save3", user_id = user_id, value = {}, permission_read = 2, permission_write = 1},
  {collection = "save", key = "save3", user_id = user_id, value = {}, version="*", permission_read = 1, permission_write = 1}
}
nk.storage_write(new_objects)
userID := "4ec4f126-3f9d-11e7-84ef-b7c182b36521" // Some user ID.
objectIds := []*runtime.StorageWrite{
  &runtime.StorageWrite{
    Collection: "save",
    Key:        "save1",
    UserID:     userID,
    Value:      "{}", // Value must be a valid encoded JSON object.
  },
  &runtime.StorageWrite{
    Collection: "save",
    Key:        "save2",
    UserID:     userID,
    Value:      "{}", // Value must be a valid encoded JSON object.
  },
  &runtime.StorageWrite{
    Collection:      "public",
    Key:             "save3",
    UserID:          userID,
    Value:           "{}", // Value must be a valid encoded JSON object.
    PermissionRead:  2,
    PermissionWrite: 1,
  },
  &runtime.StorageWrite{
    Collection:      "public",
    Key:             "save4",
    UserID:          userID,
    Value:           "{}", // Value must be a valid encoded JSON object.
    Version:         "*",
    PermissionRead:  2,
    PermissionWrite: 1,
  },
}

if _, err := nk.StorageWrite(ctx, objectIds); err != nil {
  // Handle error.
}

sql

Note

These functions allow your Lua scripts to run arbitrary SQL staments beyond the ones built into Nakama itself. It is your responsibility to manage the performance of these queries.

sql_exec (query, parameters)

Execute an arbitrary SQL query and return the number of rows affected. Typically an INSERT, DELETE, or UPDATE statement with no return columns.

Param Type Description
query string A SQL query to execute.
parameters table Arbitrary parameters to pass to placeholders in the query.

Returns

A single number indicating the number of rows affected by the query.

Example

-- This example query deletes all expired leaderboard records.
local query = [[DELETE FROM leaderboard_record
                WHERE expires_at > 0 AND expires_at <= $1]]
local parameters = {os.time() * 1000}
local affected_rows_count = nk.sql_exec(query, parameters)
// Use the standard Go sql package.
import "database/sql"

sql_query (query, parameters)

Execute an arbitrary SQL query that is expected to return row data. Typically a SELECT statement.

Param Type Description
query string A SQL query to execute.
parameters table Arbitrary parameters to pass to placeholders in the query.

Returns

A Lua table containing the result rows in the format:

{
  {column1 = "value1", column2 = "value2", ...}, -- Row 1.
  {column1 = "value1", column2 = "value2", ...}, -- Row 2.
  ...
}
// Use the standard Go sql package.
import "database/sql"

Example

-- Example fetching a list of usernames for the 100 most recetly signed up users.
local query = [[SELECT username, create_time
                FROM users
                ORDER BY create_time DESC
                LIMIT 100]]
local parameters = {}
local rows = nk.sql_query(query, parameters)

-- Example of processing the rows.
nk.logger_info("Selected " .. #rows .. " rows.")
for i, row in ipairs(rows) do
  nk.logger_info("Username " .. row.username .. " created at " .. row.create_time)
end
// Use the standard Go sql package.
import "database/sql"

Note

The fields available in each row depend on the columns selected in the query such as row.username and row.create_time above.

time

time ()

Get the current UTC time in milliseconds using the system wall clock.

Returns

A number representing the current UTC time in milliseconds.

Example

local utc_msec = nk.time()
// Use the standard Go time package.
import "time"

tournaments

Tournament Create

Setup a new dynamic tournament with the specified ID and various configuration settings. The underlying leaderboard will be created if it doesn't already exist, otherwise its configuration will not be updated.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
id string string The unique identifier for the new tournament. This is used by clients to submit scores.
sort string string The sort order for records in the tournament; possible values are "asc" or "desc". Optional in Lua. Default "desc".
operator string string The operator that determines how scores behave when submitted; possible values are "best", "set", or "incr". Optional in Lua. Default "best".
duration int number The active duration for a tournament. This is the duration when clients are able to submit new records. The duration starts from either the reset period or tournament start time whichever sooner. Clients can query the tournament for results between end of duration and next reset period. Required.
reset string string The cron format used to define the reset schedule for the tournament. This controls when the underlying leaderboard resets and the tournament is considered active again. Optional in Lua.
metadata map[string]interface{} table The metadata you want associated to the tournament. Some good examples are weather conditions for a racing game. Optional in Lua.
title string string The title of the tournament. Optional in Lua.
description string string The description of the tournament. Optional in Lua.
category int number A category associated with the tournament. This can be used to filter different types of tournaments. Between 0 and 127. Optional in Lua.
start_time int number The start time of the tournament. Leave empty for immediately, or a future time.
end_time int number The end time of the tournament. When the end time is elapsed, the tournament will not reset and will cease to exist. Must be greater than start_time if set. Optional in Lua. Default value is never.
max_size int number Maximum size of participants in a tournament. Optional in Lua.
max_num_score int number Maximum submission attempts for a tournament record.
join_required bool bool Whether the tournament needs to be joint before a record write is allowed.

Example

local id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
local authoritative = false
local sort = "desc"     -- One of: "desc", "asc".
local operator = "best" -- One of: "best", "set", "incr".
local reset = "0 12 * * *" -- Noon UTC each day.
local metadata = {
  weather_conditions = "rain"
}
title = "Daily Dash"
description = "Dash past your opponents for high scores and big rewards!"
category = 1
start_time = 0       -- Start now.
end_time = 0         -- Never end, repeat the tournament each day forever.
duration = 3600      -- In seconds.
max_size = 10000     -- First 10,000 players who join.
max_num_score = 3    -- Each player can have 3 attempts to score.
join_required = true -- Must join to compete.
nk.tournament_create(id, sort, operator, duration, reset, metadata, title, description,
    category, start_time, endTime, max_size, max_num_score, join_required)
id := "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
sortOrder := "desc"           // One of: "desc", "asc".
operator := "best"            // One of: "best", "set", "incr".
resetSchedule := "0 12 * * *" // Noon UTC each day.
metadata := map[string]interface{}{
  "weather_conditions": "rain",
}
title := "Daily Dash"
description := "Dash past your opponents for high scores and big rewards!"
category := 1
startTime := 0       // Start now.
endTime := 0         // Never end, repeat the tournament each day forever.
duration := 3600     // In seconds.
maxSize := 10000     // First 10,000 players who join.
maxNumScore := 3     // Each player can have 3 attempts to score.
joinRequired := true // Must join to compete.
if err := nk.TournamentCreate(ctx, id, sortOrder, operator, resetSchedule, metadata, title, description, category, startTime, endTime, duration, maxSize, maxNumScore, joinRequired); err != nil {
  // Handle error.
}

Tournament Delete

Delete a tournament and all records that belong to it.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
id string string The unique identifier for the tournament to delete. Mandatory field.

Example

local id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
nk.tournament_delete(id)
id := "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
if err := nk.TournamentDelete(ctx, id); err != nil {
  // Handle error.
}

Tournament Add Attempt

Add additional score attempts to the owner's tournament record. This overrides the max number of score attempts allowed in the tournament for this specific owner.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
id string string The unique identifier for the tournament to update. Mandatory field.
owner string string The owner of the record to increment the count for. Mandatory field.
count int number The number of attempt counts to increment. Can be negative to decrease count. Mandatory field.

Example

local id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
local owner = "leaderboard-record-owner"
local count = -10
nk.tournament_add_attempt(id, owner, count)
id := "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
ownerID := "leaderboard-record-owner"
count := -10
if err := nk.TournamentAddAttempt(ctx, id, ownerID, count); err != nil {
  // Handle error.
}

Tournament Join

A tournament may need to be joined before the owner can submit scores. This operation is idempotent and will always succeed for the owner even if they have already joined the tournament.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
id string string The unique identifier for the tournament to update. Mandatory field.
user_id string string The owner of the record. Mandatory field.
username string string The username of the record owner. Mandatory field.

Example

local id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
local owner = "leaderboard-record-owner"
local username = "myusername"
nk.tournament_join(id, owner, username)
id := "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
ownerID := "leaderboard-record-owner"
userName := "myusername"
if err := nk.TournamentJoin(ctx, id, ownerID, userName)
  // Handle error.
}

Tournament List

Find tournaments which have been created on the server. Tournaments can be filtered with categories and via start and end times. This function can also be used to see the tournaments that an owner (usually a user) has joined.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
category_start int number Filter tournament with categories greater or equal than this value.
category_end int number Filter tournament with categories equal or less than this value.
start_time int number Filter tournament with that start after this time.
end_time int number Filter tournament with that end before this time.
limit int number Return only the required number of tournament denoted by this limit value.
cursor string string Cursor to paginate to the next result set. If this is empty/null there is no further results.

Returns

A table of tournament objects.

Example

local category_start = 1
local category_end = 2
local start_time = 1538147711
local end_time = 0 -- All tournaments from the start time.
local limit = 100  -- Number to list per page.
local tournaments = nk.tournament_list(category_start, category_end, start_time, end_time, limit)
for i, row in ipairs(tournaments) do
  nk.logger_info("ID " .. tournament.id .. " - can enter? " .. row.can_enter)
end
categoryStart := 1
categoryEnd := 2
startTime := int(time.Now().Unix())
endTime := 0 // All tournaments from the start time.
limit := 100 // Number to list per page.
cursor := ""
if tournaments, err := nk.TournamentList(ctx, categoryStart, categoryEnd, startTime, endTime, limit, cursor); err != nil {
  // Handle error.
} else {
  for _, t := range tournaments.Tournaments {
    logger.Info("ID %s - can enter? %b", t.Id, t.CanEnter)
  }
}

Tournament Record Write

Submit a score and optional subscore to a tournament leaderboard. If the tournament has been configured with join required this will fail unless the owner has already joined the tournament.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
id string string The unique identifier for the leaderboard to submit to. Mandatory field.
owner string string The owner of this score submission. Mandatory field.
username string string The owner username of this score submission, if it's a user. Optional in Lua.
score int64 number The score to submit. Optional in Lua. Default 0.
subscore int64 number A secondary subscore parameter for the submission. Optional in Lua. Default 0.
metadata map[string]interface{} table The metadata you want associated to this submission. Some good examples are weather conditions for a racing game. Optional in Lua.

Returns

A table of tournament record objects.

Example

local metadata = {
  weather_conditions = "rain"
}
local id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
local owner = "4c2ae592-b2a7-445e-98ec-697694478b1c"
local username = "02ebb2c8"
local score = 10
local subscore = 0
nk.tournament_record_write(id, owner, username, score, subscore, metadata)
id := "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
ownerID := "4c2ae592-b2a7-445e-98ec-697694478b1c"
username := "02ebb2c8"
score := int64(10)
subscore := int64(0)
metadata := map[string]interface{}{
  "weather_conditions": "rain",
}
if _, err := nk.TournamentRecordWrite(ctx, id, ownerID, username, score, subscore, metadata); err != nil {
  // Handle error.
}

Tournament Records Haystack

Fetch the list of tournament records around the owner.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
id string string The unique identifier for the leaderboard to submit to. Mandatory field.
owner string string The owner of this score submission. Mandatory field.
limit int number Number of records to return. Default 1, optional field.

Returns

A table of tournament record objects.

Example

local metadata = {
  weather_conditions = "rain"
}
local id = "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
local owner = "4c2ae592-b2a7-445e-98ec-697694478b1c"
nk.tournament_records_haystack(id, owner, 10)
id := "4ec4f126-3f9d-11e7-84ef-b7c182b36521"
ownerID := "4c2ae592-b2a7-445e-98ec-697694478b1c"
limit := 10

if records, err := nk.TournamentRecordsHaystack(ctx, id, ownerID, limit); err != nil {
  // Handle error.
} else {
  for _, r := range records {
    logger.Info("Leaderboard: %s, score: %d, subscore: %d", r.GetLeaderboardId(), r.Score, r.Subscore)
  }
}

users

Users Get by ID

Fetch one or more users by ID.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
user_ids []string table A table / array of user IDs to fetch.

Returns

A table array of the user result set.

Example

local user_ids = {
  "3ea5608a-43c3-11e7-90f9-7b9397165f34",
  "447524be-43c3-11e7-af09-3f7172f05936"
}
local users = nk.users_get_id(user_ids)
for _, u in ipairs(users)
do
  local message = ("username: %q, displayname: %q"):format(u.username, u.display_name)
  nk.logger_info(message)
end
if users, err := nk.UsersGetId(ctx, []string{
  "3ea5608a-43c3-11e7-90f9-7b9397165f34",
  "447524be-43c3-11e7-af09-3f7172f05936",
}); err != nil {
  // Handle error.
} else {
  for _, u := range users {
    logger.Info("username: %s, displayname: %s", u.Username, u.DisplayName)
  }
}

Users Get by Username

Fetch a set of users by their usernames.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
usernames []string table A table array of usernames to fetch.

Returns

A table array of the user result set.

Example

local usernames = {"b7865e7e", "c048ba7a"}
local users = nk.users_get_username(usernames)
for _, u in ipairs(users)
do
  local message = ("id: %q, displayname: %q"):format(u.id, u.display_name)
  nk.logger_info(message)
end
if users, err := nk.UsersGetUsername(ctx, []string{"b7865e7e", "c048ba7a"}); err != nil {
  // Handle error
} else {
  for _, u := range users {
    logger.Printf("id: %s, displayname: %s", u.Id, u.DisplayName)
  }
}

Users Ban by ID

Ban one or more users by ID. These users will no longer be allowed to authenticate with the server until unbanned.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
user_ids []string table A table / array of user IDs to ban.

Example

local user_ids = {
  "3ea5608a-43c3-11e7-90f9-7b9397165f34",
  "447524be-43c3-11e7-af09-3f7172f05936"
}
nk.users_ban_id(user_ids)
if err := nk.UsersBanId(ctx, []string{
  "3ea5608a-43c3-11e7-90f9-7b9397165f34",
  "447524be-43c3-11e7-af09-3f7172f05936",
}); err != nil {
  // Handle error.
}

Users Unban by ID

Unban one or more users by ID. These users will again be allowed to authenticate with the server.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
user_ids []string table A table / array of user IDs to unban.

Example

local user_ids = {
  "3ea5608a-43c3-11e7-90f9-7b9397165f34",
  "447524be-43c3-11e7-af09-3f7172f05936"
}
nk.users_unban_id(user_ids)
if err := nk.UsersUnbanId(ctx, []string{
  "3ea5608a-43c3-11e7-90f9-7b9397165f34",
  "447524be-43c3-11e7-af09-3f7172f05936",
}); err != nil {
  // Handle error.
}

uuid

uuid_v4 ()

Generate a version 4 UUID in the standard 36-character string representation.

Returns

The generated version 4 UUID identifier.

Example

local uuid = nk.uuid_v4()
nk.logger_info(uuid)
// Use a Go CRON package, for example:
import "github.com/gofrs/uuid"

uuid_bytes_to_string (uuid_bytes)

Convert the 16-byte raw representation of a UUID into the equivalent 36-character standard UUID string representation. Will raise an error if the input is not valid and cannot be converted.

Parameters

Param Type Description
uuid_bytes string The UUID bytes to convert.

Returns

A string containing the equivalent 36-character standard representation of the UUID.

Example

local uuid_bytes = "\78\196\241\38\63\157\17\231\132\239\183\193\130\179\101\33" -- some uuid bytes.
local uuid_string = nk.uuid_bytes_to_string(uuid_bytes)
nk.logger_info(uuid_string)
// Use a Go CRON package, for example:
import "github.com/gofrs/uuid"

uuid_string_to_bytes (uuid_string)

Convert the 36-character string representation of a UUID into the equivalent 16-byte raw UUID representation. Will raise an error if the input is not valid and cannot be converted.

Parameters

Param Type Description
uuid_string string The UUID string to convert.

Returns

A string containing the equivalent 16-byte representation of the UUID. This function will also insert a new wallet ledger item into the user's wallet history that trackes this update.

Example

local uuid_string = "4ec4f126-3f9d-11e7-84ef-b7c182b36521" -- some uuid string.
local uuid_bytes = nk.uuid_string_to_bytes(uuid_string)
nk.logger_info(uuid_bytes)
// Use a Go CRON package, for example:
import "github.com/gofrs/uuid"

wallet

Wallet Update

Update a user's wallet with the given changeset.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
user_id string string The ID of the user to update the wallet for.
changeset map[string]interface{} table The set of wallet operations to apply.
metadata map[string]interface{} table Additional metadata to tag the wallet update with. Optional in Lua.
update_ledger bool bool Whether to record this update in the ledger. Default true. Optional in Lua.

Example

local user_id = "8f4d52c7-bf28-4fcf-8af2-1d4fcf685592"
local changeset = {
  coins = 10, -- Add 10 coins to the user's wallet.
  gems = -5   -- Remove 5 gems from the user's wallet.
}
local metadata = {
  game_result = "won"
}
nk.wallet_update(user_id, changeset, metadata, true)
userID := "8f4d52c7-bf28-4fcf-8af2-1d4fcf685592"
changeset := map[string]interface{}{
  "coins": 10, // Add 10 coins to the user's wallet.
  "gems":  -5, // Remove 5 gems from the user's wallet.
}
metadata := map[string]interface{}{
  "game_result": "won",
}
if err := nk.WalletUpdate(ctx, userID, changeset, metadata, true); err != nil {
  // Handle error.
}

Wallets Update

Update one or more user wallets with individual changesets. This function will also insert a new wallet ledger item into each user's wallet history that tracks their update.

All updates will be performed atomically.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
updates []*runtime.WalletUpdate table The set of user wallet update operations to apply.
update_ledger bool bool Whether to record this update in the ledger. Default true. Optional in Lua.

Example

local updates = {
  {
    user_id = "8f4d52c7-bf28-4fcf-8af2-1d4fcf685592",
    changeset = {
      coins = 10, -- Add 10 coins to the user's wallet.
      gems = -5   -- Remove 5 gems from the user's wallet.
    },
    metadata = {
      game_result = "won"
    }
  }
}
nk.wallets_update(updates, true)
updates := []*runtime.WalletUpdate{
  &runtime.WalletUpdate{
    UserID: "8f4d52c7-bf28-4fcf-8af2-1d4fcf685592",
    Changeset: map[string]interface{}{
      "coins": 10, // Add 10 coins to the user's wallet.
      "gems":  -5, // Remove 5 gems from the user's wallet.
    },
    Metadata: map[string]interface{}{
      "game_result": "won",
    },
  },
}

if err := nk.WalletsUpdate(ctx, updates, true); err != nil {
  // Handle error.
}

Wallet Ledger List

List all wallet updates for a particular user, from oldest to newest.

Parameters

Param Go type Lua type Description
ctx context.Context - Context object represents information about the match and server for information purposes.
user_id string string The ID of the user to update the wallet for.

Returns

A Lua table / Go slice containing wallet entries, with the following parameters:

{
  {
    id = "...",
    user_id = "...",
    create_time = 123,
    update_time = 123,
    changeset = {},
    metadata = {}
  }
}
{
  {
    Id: "...",
    UserID: "...",
    CreateTime: 123,
    UpdateTime: 123,
    ChangeSet: {}, // map[string]interface{}
    Metadata: {},  // map[string]interface{}
  },
}

Example

local user_id = "8f4d52c7-bf28-4fcf-8af2-1d4fcf685592"
local updates = nk.wallet_ledger_list(user_id)
for _, u in ipairs(updates)
do
  local message = ("found wallet update with id: %q"):format(u.id)
  nk.logger_info(message)
end
userID := "8f4d52c7-bf28-4fcf-8af2-1d4fcf685592"

if items, err := nk.WalletLedgerList(ctx, userID); err != nil {
  // Handle error.
} else {
  for _, item := range items {
    logger.Info("found wallet update with id: %v", item.GetID())
  }
}

Wallet Ledger Update

Update the metadata for a particular wallet update in a users wallet ledger history. Useful when adding a note to a transaction for example.

Parameters

Param Type Description
id string The ID of the wallet ledger item to update.
metadata table The new metadata to set on the wallet ledger item.

Returns

The updated wallet ledger item as a Lua table with the following format:

{
  {
    id = "...",
    user_id = "...",
    create_time = 123,
    update_time = 123,
    changeset = {},
    metadata = {}
  }
}
{
  {
    Id: "...",
    UserID: "...",
    CreateTime: 123,
    UpdateTime: 123,
    ChangeSet: {}, // map[string]interface{}
    Metadata: {},  // map[string]interface{}
  },
}

Example

local id = "2745ba53-4b43-4f83-ab8f-93e9b677f33a"
local metadata = {
  game_result = "loss"
}
local u = nk.wallet_ledger_update(id, metadata
itemID := "8f4d52c7-bf28-4fcf-8af2-1d4fcf685592"
metadata := map[string]interface{}{
  "game_result": "loss",
}
if _, err := nk.WalletLedgerUpdate(ctx, itemID, metadata); err != nil {
  // Handle error.
}