### Hello World Lua Example Source: https://heroiclabs.com/docs/nakama/server-framework/lua-runtime/index.html A basic 'Hello World' example demonstrating how to use the logger in Nakama's Lua runtime. No additional setup is required beyond creating the 'main.lua' file. ```lua local nk = require("nakama") nk.logger_info("Hello World!") ``` -------------------------------- ### Import Simple Handler Example in Unity Source: https://heroiclabs.com/docs/nakama/guides/concepts/edgegap-integration/index.html Import the Simple Handler Example from the Unity Package Manager to get started with basic integration. ```csharp // SimpleHandlerExample.cs script // Attach this script to an Empty GameObject in your scene. ``` -------------------------------- ### Install Nakama-GameLift Plugin Source: https://heroiclabs.com/docs/nakama/guides/concepts/gamelift-integration/llm.md Install the Nakama-GameLift plugin using the go get command. This command should be run in your Nakama project folder. ```bash go get github.com/heroiclabs/nakama-gamelift/fleetmanager ``` -------------------------------- ### Go Runtime Examples Source: https://heroiclabs.com/docs/nakama/server-framework/runtime-examples Examples for implementing server logic using Go. Includes match handler and match runtime APIs. ```go package main import ( "encoding/json" "log" "github.com/heroiclabs/nakama-common/runtime" ) func InitModule(s *runtime.Runtime) ende log.Println("Initializing Go module") // Register hooks ss.RegisterRpc("my_rpc_function", MyRpcFunction) ss.RegisterMatch("my_match", MyMatch{}) } func MyRpcFunction(ctx *runtime.Context, logger *log.Logger, nk runtime.Nakama, payload string) (string, error) { logger.Printf("RPC function called with payload: %s\n", payload) // Example: Echo payload back return payload, nil } type MyMatch struct {} func (m MyMatch) CreateMatch(ctx *runtime.Context, logger *log.Logger, nk runtime.Nakama, params map[string]interface{}) ende logger.Println("Creating match") // Return a new match object return &MyMatchState{}, } func (m MyMatch) MatchLoop(ctx *runtime.Context, logger *log.Logger, nk runtime.Nakama, dispatcher runtime.MatchDispatcher, tick int64, state runtime.MatchState) ende logger.Printf("Match loop tick: %d\n", tick) // Example: Send a message to all users in the match matchState := state.(*MyMatchState) dispatcher.Broadcast(runtime.OpCodeMatchState, []byte("Hello from Go server!"), nil) return nil } func (m MyMatch) JoinMatch(ctx *runtime.Context, logger *log.Logger, nk runtime.Nakama, match *runtime.Match, joiner *runtime.User, payload string)ende logger.Printf("User %s joining match\n", joiner.Id) return nil } func (m MyMatch) LeaveMatch(ctx *runtime.Context, logger *log.Logger, nk runtime.Nakama, match *runtime.Match, leaving *runtime.User, payload string)ende logger.Printf("User %s leaving match\n", leaving.Id) return nil } type MyMatchState struct {} func (s *MyMatchState) Execute(ctx *runtime.Context, logger *log.Logger, nk runtime.Nakama, dispatcher runtime.MatchDispatcher, tick int64, state runtime.MatchState)ende // This method is called by the MatchLoop, so we don't need to implement it here unless we want to override MatchLoop behavior. return nil } func (s *MyMatchState) GetState() interface{} { return s } func (s *MyMatchState) SetState(state interface{}) { // This method is called by the MatchLoop, so we don't need to implement it here unless we want to override MatchLoop behavior. } func (s *MyMatchState) BeforeCreateMatch(ctx *runtime.Context, logger *log.Logger, nk runtime.Nakama, params map[string]interface{})ende // Optional: Logic before match creation return nil } func (s *MyMatchState) AfterCreateMatch(ctx *runtime.Context, logger *log.Logger, nk runtime.Nakama, match *runtime.Match)ende // Optional: Logic after match creation return nil } func (s *MyMatchState) BeforeJoinMatch(ctx *runtime.Context, logger *log.Logger, nk runtime.Nakama, match *runtime.Match, joiner *runtime.User, payload string)ende // Optional: Logic before a user joins a match return nil } func (s *MyMatchState) AfterJoinMatch(ctx *runtime.Context, logger *log.Logger, nk runtime.Nakama, match *runtime.Match, joiner *runtime.User)ende // Optional: Logic after a user joins a match return nil } func (s *MyMatchState) BeforeLeaveMatch(ctx *runtime.Context, logger *log.Logger, nk runtime.Nakama, match *runtime.Match, leaving *runtime.User, payload string)ende // Optional: Logic before a user leaves a match return nil } func (s *MyMatchState) AfterLeaveMatch(ctx *runtime.Context, logger *log.Logger, nk runtime.Nakama, match *runtime.Match, leaving *runtime.User)ende // Optional: Logic after a user leaves a match return nil } func (s *MyMatchState) OnSignal(ctx *runtime.Context, logger *log.Logger, nk runtime.Nakama, dispatcher runtime.MatchDispatcher, tick int64, state runtime.MatchState, sender *runtime.User, opCode int, payload string)ende // Handle incoming signals from clients return nil } func (s *MyMatchState) OnError(ctx *runtime.Context, logger *log.Logger, nk runtime.Nakama, dispatcher runtime.MatchDispatcher, tick int64, state runtime.MatchState, err error)ende // Handle errors within the match return nil } ``` -------------------------------- ### Run Nakama Server Without Docker Source: https://heroiclabs.com/docs/nakama/server-framework/go-runtime/llm.md Starts the Nakama server with a specified configuration file and database address. Assumes Nakama binary is installed. ```bash nakama --config local.yml --database.address ``` -------------------------------- ### Lua Runtime Examples Source: https://heroiclabs.com/docs/nakama/server-framework/runtime-examples Examples for implementing server logic using Lua. Includes match handler and match runtime APIs. ```lua local nakama = require "nakama" local logger = nakama.logger local function create_match(ctx, logger, nk, payload) logger.info("Creating match: %s", payload) return json.encode({ match_id = payload }) end local function join_match(ctx, logger, nk, match_id, user_id, payload) logger.info("Joining match: %s, User: %s", match_id, user_id) end local function leave_match(ctx, logger, nk, match_id, user_id) logger.info("Leaving match: %s, User: %s", match_id, user_id) end local function match_loop(ctx, logger, nk, matches) logger.info("Match loop executing.") -- Example: Send a message to all users in a match for _, match_id in ipairs(matches) do nakama.match_signal(match_id, nakama.RTL_OPCODE_MATCH_STATE, json.encode({ message = "Hello from Lua server!" })) end end local function authenticate_device(ctx, logger, nk, device_id) logger.info("Authenticating device: %s", device_id) return nakama.authenticate_device(device_id) end local function rpc(ctx, logger, nk, payload) logger.info("RPC called with payload: %s", payload) -- Example: Echo payload back return payload end nakama.register_rpc(rpc) nakama.register_match_creator(create_match) nakama.register_match_joiner(join_match) nakama.register_match_leaver(leave_match) nakama.register_match_loop(match_loop) nakama.register_authenticator(authenticate_device) ``` -------------------------------- ### Initialize Go Module and Install Nakama Runtime Source: https://heroiclabs.com/docs/nakama/server-framework/go-runtime/llm.md Initialize your Go project with a module path and install the necessary Nakama runtime package. ```sh go mod init example.com/go-project go get github.com/heroiclabs/nakama-common/runtime ``` -------------------------------- ### Enable and Start Nakama systemd Service Source: https://heroiclabs.com/docs/nakama/getting-started/install/linux/llm.md Enable the Nakama service to start on boot and then start the service immediately. ```sh sudo systemctl enable nakama sudo systemctl start nakama ``` -------------------------------- ### Initialize Game Setup Source: https://heroiclabs.com/docs/nakama/tutorials/godot/fishgame/index.html This function pauses the game, initializes game state variables, instantiates player scenes, and sets up network masters for each player. It's crucial for synchronizing the game state across all clients before the match begins. Use this when starting a new game session. ```gdscript remotesync func _do_game_setup(players: Dictionary) -> void: get_tree().set_pause(true) if game_started: game_stop() game_started = true game_over = false players_alive = players reload_map() var player_number := 1 for peer_id in players: var other_player = Player.instance() other_player.name = str(peer_id) players_node.add_child(other_player) other_player.set_network_master(peer_id) other_player.set_player_skin(player_number - 1) other_player.set_player_name(players[peer_id]) other_player.position = map.get_node("PlayerStartPositions/Player" + str(player_number)).position other_player.rotation = map.get_node("PlayerStartPositions/Player" + str(player_number)).rotation other_player.connect("player_dead", self, "_on_player_dead", [peer_id]) if not GameState.online_play: other_player.player_controlled = true other_player.input_prefix = "player" + str(player_number) + "_" player_number += 1 camera.update_position_and_zoom(false) if GameState.online_play: var my_id := get_tree().get_network_unique_id() var my_player := players_node.get_node(str(my_id)) my_player.player_controlled = true # Tell the host that we've finished setup. rpc_id(1, '_finished_game_setup', my_id) else: _do_game_start() ``` -------------------------------- ### Call GameLift Initialization from Start Method Source: https://heroiclabs.com/docs/nakama/guides/concepts/gamelift-integration/llm.md Ensures that the GameLift initialization process is triggered when the game server starts. ```csharp private void Start() { InitializeGameLift(); } ``` -------------------------------- ### Install Nakama Runtime Package Source: https://heroiclabs.com/docs/nakama/server-framework/typescript-runtime/llm.md Installs a specific version of the nakama-runtime package from GitHub. Replace `` with the desired GitHub tag. ```bash npm i https://github.com/heroiclabs/nakama-common# ``` -------------------------------- ### TypeScript Runtime Examples Source: https://heroiclabs.com/docs/nakama/server-framework/runtime-examples Examples for implementing server logic using TypeScript. Includes match handler and match runtime APIs. ```typescript import { RTLOpCode } from "@heroiclabs/nakama-runtime"; export function createMatch(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, payload: string): string { const matchId = payload; logger.info("Creating match: %s", matchId); return JSON.stringify({ matchId: matchId, }); } export function joinMatch(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, matchId: string, userId: string, payload: string): void { logger.info("Joining match: %s, User: %s", matchId, userId); } export function leaveMatch(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, matchId: string, userId: string): void { logger.info("Leaving match: %s, User: %s", matchId, userId); } export function matchLoop(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, matches: string[]): void { logger.info("Match loop executing."); // Example: Send a message to all users in a match matches.forEach(matchId => { nk.matchSignal(matchId, RTLOpCode.MATCH_STATE, JSON.stringify({ message: "Hello from server!" })); }); } export function authenticateDevice(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, deviceId: string): nkruntime.Session { logger.info("Authenticating device: %s", deviceId); return nk.authenticateDevice(deviceId); } export function rpc(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, payload: string): string { logger.info("RPC called with payload: %s", payload); // Example: Echo payload back return payload; } ``` -------------------------------- ### Complete Plugin Example with Event Processing Source: https://heroiclabs.com/docs/nakama/concepts/events/llm.md A full plugin sample demonstrating how to process SessionStart, SessionEnd, and account update events. ```go package main import ( "context" "database/sql" "github.com/heroiclabs/nakama-common/api" "github.com/heroiclabs/nakama-common/runtime" ) func afterUpdateAccount(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, in *api.UpdateAccountRequest) error { evt := &api.Event{ Name: "account_updated", Properties: map[string]string{}, External: false, } return nk.Event(context.Background(), evt) } func processEvent(ctx context.Context, logger runtime.Logger, evt *api.Event) { switch evt.GetName() { case "account_updated": logger.Debug("process evt: %+v", evt) // Send event to an analytics service. default: logger.Error("unrecognised evt: %+v", evt) } } func eventSessionEnd(ctx context.Context, logger runtime.Logger, evt *api.Event) { logger.Debug("process event session end: %+v", evt) } func eventSessionStart(ctx context.Context, logger runtime.Logger, evt *api.Event) { logger.Debug("process event session start: %+v", evt) } //noinspection GoUnusedExportedFunction func InitModule(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, initializer runtime.Initializer) error { if err := initializer.RegisterAfterUpdateAccount(afterUpdateAccount); err != nil { return err } if err := initializer.RegisterEvent(processEvent); err != nil { return err } if err := initializer.RegisterEventSessionEnd(eventSessionEnd); err != nil { return err } if err := initializer.RegisterEventSessionStart(eventSessionStart); err != nil { return err } logger.Info("Server loaded.") return nil } ``` -------------------------------- ### List User Subscriptions (HTTP GET) Source: https://heroiclabs.com/docs/nakama/concepts/iap-validation/llm.md Example HTTP GET request for listing user subscriptions. ```http GET /v2/iap/subscription/limit=&cursor= Host: 127.0.0.1:7350 Accept: application/json Content-Type: application/json Authorization: Bearer ``` -------------------------------- ### Go Runtime Examples Source: https://heroiclabs.com/docs/nakama/server-framework/runtime-examples/index.html Examples for implementing server logic using Go. These snippets demonstrate how to use Nakama's Go SDK for server-side operations. ```go package main import ( "context" "log" "github.com/heroiclabs/nakama-common/runtime" ) // Example of a server-side Go function func MyServerFunction(ctx context.Context, logger runtime.Logger, nk runtime.Nakama) ( map[string]interface{}, error) { logger.Info("Hello from Go runtime!") // Example: Fetch user data user, err := nk.GetUser(ctx, ctx.Value(runtime.RUNTIME_CTX_USER_ID).(string)) if err != nil { logger.Error("Error getting user: %v", err) return nil, err } logger.Info("User ID: %s, Display Name: %s", user.Id, user.DisplayName) // Example: Store custom data customData := map[string]interface{}{"score": 100, "level": 5} if _, err := nk.StorageWrite(ctx, "user_progress", "", customData, ctx.Value(runtime.RUNTIME_CTX_USER_ID).(string), ctx.Value(runtime.RUNTIME_CTX_USER_ID).(string)); err != nil { logger.Error("Error writing storage: %v", err) return nil, err } return map[string]interface{}{"message": "Go function executed successfully!"}, nil } ``` -------------------------------- ### Initialize User on Registration (Go) Source: https://heroiclabs.com/docs/nakama/server-framework/runtime-examples/llm.md This Go example demonstrates initializing a new user by adding currency to their wallet after authentication, using the 'AfterAuthenticateDevice' hook. ```go func InitializeUser(ctx context.Context, logger Logger, db *sql.DB, nk NakamaModule, out *api.Session, in *api.AuthenticateDeviceRequest) error { if out.Created { // Only run this logic if the account that has authenticated is new. userID, ok := ctx.Value(runtime.RUNTIME_CTX_USER_ID).(string) if !ok { return "", errors.New("Invalid context") } changeset := map[string]interface{}{ "coins": 10, // Add 10 coins to the user's wallet. "gems": 5, // Add 5 gems to the user's wallet. "artifacts": 0, // No artifacts to start with. } var metadata map[string]interface{} if err := nk.WalletUpdate(ctx, userID, changeset, metadata, true); err != nil { // Handle error. } } } // Register as after hook, this call should be in InitModule. if err := initializer.RegisterAfterAuthenticateDevice(InitializeUser); err != nil { logger.Error("Unable to register: %v", err) return err } ``` -------------------------------- ### HTTP GET Request for Channel Messages Source: https://heroiclabs.com/docs/nakama/concepts/chat/index.html Example of an HTTP GET request to retrieve channel messages, including necessary headers. ```http GET /v2/channel/?forward=true&limit=10&cursor= HTTP/1.1 Host: 127.0.0.1:7350 Accept: application/json Content-Type: application/json Authorization: Bearer ``` -------------------------------- ### HTTP GET Request for Listing Groups Source: https://heroiclabs.com/docs/nakama/concepts/groups/index.html Example of an HTTP GET request to list groups with a name filter and cursor. Includes necessary headers. ```http GET /v2/group?limit=20&name=heroes%&cursor=somecursor Host: 127.0.0.1:7350 Accept: application/json Content-Type: application/json Authorization: Bearer ``` -------------------------------- ### Setup Realtime Client and Connect Source: https://heroiclabs.com/docs/nakama/client-libraries/unreal/llm.md Set up a Nakama Realtime Client from the main client and establish a connection using success and error delegates. This is used for real-time gameplay features. ```cpp RealtimeClient = Client->SetupRealtimeClient(Session); FOnRealtimeClientConnected ConnectionSuccessDelegate; ConnectionSuccessDelegate.AddDynamic(this, &ASagiShiActor::OnRealtimeClientConnectionSuccess); FOnRealtimeClientError ConnectionErrorDelegate; ConnectionErrorDelegate.AddDynamic(this, &ASagiShiActor::OnRealtimeClientConnectionError); RealtimeClient->Connect(ConnectionSuccessDelegate, ConnectionErrorDelegate); ``` -------------------------------- ### HTTP GET Request for Channel Messages Source: https://heroiclabs.com/docs/nakama/concepts/chat/index.html Example of an HTTP GET request to retrieve channel messages. This is a low-level representation and client SDKs are recommended. ```http GET /v2/channel/ Host: 127.0.0.1:7350 Accept: application/json Content-Type: application/json Authorization: Bearer ``` -------------------------------- ### List Expired Leaderboard Records (HTTP Request Example) Source: https://heroiclabs.com/docs/nakama/concepts/leaderboards/index.html Example of an HTTP GET request to list expired leaderboard records. Includes host, accept, content-type, and authorization headers. ```http GET /v2/leaderboard/?overrideexpiry=604800 Host: 127.0.0.1:7350 Accept: application/json Content-Type: application/json Authorization: Bearer ``` -------------------------------- ### Nakama Server Startup Log Source: https://heroiclabs.com/docs/nakama/server-framework/go-runtime/llm.md Example log output indicating that custom Go code has been successfully loaded and executed at server startup. ```json { "level": "info", "ts": "....", "caller": "go-project/main.go:10", "msg": "Hello World!", "runtime": "go" } ``` -------------------------------- ### Nakama Server Startup Log Source: https://heroiclabs.com/docs/nakama/server-framework/go-runtime/index.html Example log output indicating that the Go runtime code has been loaded and executed successfully at server startup. ```json { "level": "info", "ts": "....", "caller": "go-project/main.go:10", "msg": "Hello World!", "runtime": "go" } ``` -------------------------------- ### Restore Session on App Start (.NET/Unity) Source: https://heroiclabs.com/docs/nakama/concepts/session/index.html Example of restoring a session from persistent storage on app start. It checks if the auth token is expired and attempts to refresh it using the stored refresh token. ```csharp var authToken = PlayerPrefs.GetString("nakama.authToken"); var refreshToken = PlayerPrefs.GetString("nakama.refreshToken"); if (!string.IsNullOrEmpty(refreshToken)) { var session = Session.Restore(authToken, refreshToken); if (session.IsExpired) { session = await client.SessionRefreshAsync(session); PlayerPrefs.SetString("nakama.authToken", session.AuthToken); PlayerPrefs.SetString("nakama.refreshToken", session.RefreshToken); } } else { // No stored session — authenticate from scratch. } ``` -------------------------------- ### Initialize Go Module Source: https://heroiclabs.com/docs/nakama/server-framework/go-runtime/llm.md The entry point for your Go runtime code. Register RPCs, hooks, and other event functions here. This example logs a 'Hello World!' message. ```go package main import ( "context" "database/sql" "github.com/heroiclabs/nakama-common/runtime" ) func InitModule(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, initializer runtime.Initializer) error { logger.Info("Hello World!") return nil } ``` -------------------------------- ### Get Subscription Request Headers (HTTP) Source: https://heroiclabs.com/docs/nakama/concepts/iap-validation/llm.md Example HTTP request headers for retrieving subscription status. ```http GET /v2/iap/subscription/{productId} Host: 127.0.0.1:7350 Accept: application/json Content-Type: application/json Authorization: Bearer ``` -------------------------------- ### List Notifications REST API Source: https://heroiclabs.com/docs/nakama/concepts/notifications/llm.md Example of an HTTP GET request to list notifications, including limit and cursor parameters. ```shell GET /v2/notification?limit=100&cursor= Host: 127.0.0.1:7350 Accept: application/json Content-Type: application/json Authorization: Bearer ``` -------------------------------- ### Create a Nakama Client Instance Source: https://heroiclabs.com/docs/nakama/client-libraries/unity/llm.md Initializes a Nakama client to connect to your server. Ensure you provide the correct server address, port, and key. ```csharp var client = new Nakama.Client("http", "127.0.0.1", 7350, "defaultkey"); ``` -------------------------------- ### Install i3D Fleet Manager Plugin Source: https://heroiclabs.com/docs/nakama/guides/concepts/i3d-integration/llm.md Add the i3D fleet manager to your Nakama Go module using go get. ```bash go get github.com/i3d/nakama-fleetmanager ``` -------------------------------- ### Initialize Nakama Client (Defold) Source: https://heroiclabs.com/docs/nakama/concepts/authentication/llm.md Initialize the Nakama client in Defold using a configuration table. ```lua local defold = require "nakama.engine.defold" local config = {} config.host = 127.0.0.1 config.port = 7350 config.use_ssl = false config.username = "defaultkey" config.engine = defold local client = nakama.create_client(config) ``` -------------------------------- ### List Notifications API Request Source: https://heroiclabs.com/docs/nakama/concepts/notifications/index.html Example HTTP GET request to list notifications, including query parameters for limit and cursor, and authorization header. ```http GET /v2/notification?limit=100&cursor= Host: 127.0.0.1:7350 Accept: application/json Content-Type: application/json Authorization: Bearer ``` -------------------------------- ### Example Matchmaking Call Source: https://heroiclabs.com/docs/nakama/tutorials/godot/fishgame/index.html Demonstrates how to call the start_matchmaking function with specific parameters for minimum count, string properties (region), numeric properties (rank), and a custom query. ```gdscript OnlineMatch.start_matchmaking(Online.nakama_socket, { # The default minimum is 2, we can increase that to 3 to find a 3-player match. min_count = 3, # We can tell the matchmaker about string or numeric properties of this player. string_properties = { region = 'europe', }, numeric_properties = { rank = 8, }, # The query requires a player in the same region and similar rank. query = '+region:europe +rank:>=7 +rank:<=9' }) ``` -------------------------------- ### Create and Navigate Project Directory Source: https://heroiclabs.com/docs/nakama/server-framework/go-runtime/llm.md Use these commands to create a new directory for your Go project and change into it. ```sh mkdir go-project cd go-project ``` -------------------------------- ### Access Session Variables in Lua Source: https://heroiclabs.com/docs/nakama/concepts/session/index.html Access session variables in the 'before get account' hook using Lua. This example logs the session variables available in the context. ```lua local nk = require("nakama") local function access_session_vars(context, payload) nk.logger_info("User session contains key-value pairs set by both the client and the before authentication hook: " .. nk.json_encode(context.vars)) return payload end nk.register_req_before(access_session_vars, "GetAccount") ``` -------------------------------- ### List Groups API Request Example Source: https://heroiclabs.com/docs/nakama/concepts/groups/index.html Illustrates an HTTP GET request to list groups, including query parameters for limit, name filter, and cursor for pagination. ```http GET /v2/group?limit=20&name=heroes%&cursor= Host: 127.0.0.1:7350 Accept: application/json Content-Type: application/json Authorization: Bearer ``` -------------------------------- ### Start Nakama Server Source: https://heroiclabs.com/docs/nakama/getting-started/commands/index.html Run the `nakama` command to start the server with default configuration. Command-line flags can override default settings and configuration file parameters. ```bash nakama ``` -------------------------------- ### Receive Match State Updates Source: https://heroiclabs.com/docs/nakama/client-libraries/cpp/index.html Subscribe to match state received events to get data from other connected clients. This example processes position updates for players in a match. ```cpp listener.setMatchDataCallback([&players](const NMatchData& matchData) { switch (matchData.opCode) { case OpCodes::POSITION: { // Get the updated position data json j = json::parse(matchData.data); positionState position { j["x"].get(), j["y"].get(), j["z"].get() }; // Update the GameObject associated with that player. if (players.count(matchData.presence.sessionId) > 0) { // Here we would normally do something like smoothly interpolate to the new position, but for this example let's just set the position directly. players[matchData.presence.sessionId].position = new Vector3(position.x, position.y, position.z); } } default: cout << "Unsupported opcode"; break; } }); ``` -------------------------------- ### Initialize Nakama Client Source: https://heroiclabs.com/docs/nakama/client-libraries/java/index.html Demonstrates how to create a Nakama Client instance with different levels of configuration, from minimum to explicit parameters. This client is used to connect to a Nakama Server. ```java final String serverKey = "defaultkey"; // The key used to authenticate with the server without a session. final string host = "127.0.0.1"; // The host address of the server. final int port = 7349; // The port number of the server. final boolean ssl = false; // Set connection strings to use the secure mode with the server. final int deadlineAfterMs = 0; // Timeout for the gRPC messages. final long keepAliveTimeMs = Long.MAX_VALUE; // The time without read activity before sending a keepalive ping. final long keepAliveTimeoutMs = 0L; // The time waiting for read activity after sending a keepalive ping. final boolean trace = false; // Trace all actions performed by the client. // explicity passing all parameters Client client = new DefaultClient(serverKey, host, port, ssl, deadlineAfterMs, keepAliveTimeMs, keepAliveTimeoutMs, trace); // basic parameters Client client = new DefaultClient(serverKey, host, port, ssl); // minimum parameters Client client = new DefaultClient(serverKey); ``` -------------------------------- ### List Notifications HTTP Request Source: https://heroiclabs.com/docs/nakama/concepts/notifications/index.html Example HTTP GET request to list notifications with a limit and cursor. Includes necessary headers like Host, Accept, Content-Type, and Authorization. ```http GET /v2/notification?limit=10&cursor= Host: 127.0.0.1:7350 Accept: application/json Content-Type: application/json Authorization: Bearer ``` -------------------------------- ### Create Nakama Client Configuration Source: https://heroiclabs.com/docs/nakama/client-libraries/defold/index.html Sets up the configuration object required to create a Nakama client instance. Includes host, port, SSL usage, and server key. ```lua local defold = require "nakama.engine.defold" local config = { host = 127.0.0.1, port = 7350, use_ssl = false, username = "defaultkey", engine = defold } local client = nakama.create_client(config) ``` -------------------------------- ### Retrieve Newer Notifications (cURL) Source: https://heroiclabs.com/docs/nakama/concepts/notifications Example using cURL to fetch notifications, specifically using a cacheable cursor to get only newer items. Requires session token for authorization. ```bash curl -X GET "http://127.0.0.1:7350/v2/notification?limit=10&cacheable_cursor=" \ -H 'Authorization: Bearer ' ``` -------------------------------- ### Start Nakama Server with PostgreSQL Source: https://heroiclabs.com/docs/nakama/getting-started/install/linux/llm.md Start the Nakama server with PostgreSQL, providing the same database connection string used for migrations. The database must be running prior to this. ```sh ./nakama --database.address postgres:password@127.0.0.1:5432 ``` -------------------------------- ### List Leaderboard Records by Owner IDs (HTTP Request) Source: https://heroiclabs.com/docs/nakama/concepts/leaderboards/llm.md Example of an HTTP GET request to list leaderboard records filtered by owner IDs. Ensure the Authorization header is correctly set. ```shell GET /v2/leaderboard/?owner_ids=some&owner_ids=friends Host: 127.0.0.1:7350 Accept: application/json Content-Type: application/json Authorization: Bearer ``` -------------------------------- ### Register Device Authentication Hook in Nakama Server Source: https://heroiclabs.com/docs/nakama/tutorials/unity/pirate-panic/authentication/index.html Registers a server-side hook that executes after a device authentication. This function is used for initial player setup, such as granting starting items or setting initial stats. ```typescript initializer.registerAfterAuthenticateDevice(afterAuthenticateDeviceFn); const afterAuthenticateDeviceFn: nkruntime.AfterHookFunction = function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, data: nkruntime.Session, req: nkruntime.AuthenticateDeviceRequest) { afterAuthenticate(ctx, logger, nk, data); if (!data.created) { return; // Account already exists. } ... // Player initialization goes here. Write initial stats, add items to inventory, etc. } ``` -------------------------------- ### Initialize User with Go Source: https://heroiclabs.com/docs/nakama/server-framework/runtime-examples/index.html Registers a Go function to run after user authentication to initialize user wallets. This example demonstrates updating coins, gems, and artifacts for newly created accounts. ```go func InitializeUser(ctx context.Context, logger Logger, db *sql.DB, nk NakamaModule, out *api.Session, in *api.AuthenticateDeviceRequest) error { if out.Created { // Only run this logic if the account that has authenticated is new. userID, ok := ctx.Value(runtime.RUNTIME_CTX_USER_ID).(string) if !ok { return "", errors.New("Invalid context") } changeset := map[string]interface{}{ "coins": 10, // Add 10 coins to the user's wallet. "gems": 5, // Add 5 gems to the user's wallet. "artifacts": 0, // No artifacts to start with. } var metadata map[string]interface{} if err := nk.WalletUpdate(ctx, userID, changeset, metadata, true); err != nil { // Handle error. } } } // Register as after hook, this call should be in InitModule. if err := initializer.RegisterAfterAuthenticateDevice(InitializeUser); err != nil { logger.Error("Unable to register: %v", err) return err } ``` -------------------------------- ### Authenticate with Device ID (C#) Source: https://heroiclabs.com/docs/nakama/concepts/authentication/llm.md Authenticate a user with a device ID in C#. This example generates a new GUID as the device ID and calls the `AuthenticateDeviceAsync` method. It also logs whether the user was created. ```csharp // Should use a platform API to obtain a device identifier. var deviceId = System.Guid.NewGuid().ToString(); var session = await client.AuthenticateDeviceAsync(deviceId); System.Console.WriteLine("New user: {0}, {1}", session.Created, session); ``` -------------------------------- ### Nakama Client Initialization and Account Retrieval Source: https://heroiclabs.com/docs/nakama/client-libraries/defold/index.html Demonstrates how to initialize the Nakama client and retrieve account information either in a blocking or non-blocking manner using callbacks. ```lua -- blocking local nakama.get_account(client) -- non-blocking nakama.get_account(client, function(account) print(account.user.id) end) ``` -------------------------------- ### Create Nakama Client Source: https://heroiclabs.com/docs/nakama/client-libraries/cpp/index.html Initialize the Nakama Client with server connection details. This is the entry point for interacting with the Nakama server. ```cpp NClientParameters params; params.serverKey = "defaultkey"; params.host = "127.0.0.1"; params.port = DEFAULT_PORT; auto client = createDefaultClient(params); ``` -------------------------------- ### Call Get Pokemon RPC via Defold Client Source: https://heroiclabs.com/docs/nakama/server-framework/lua-runtime/code-samples/llm.md This Defold Lua example demonstrates calling the 'get_pokemon' RPC. It shows how to encode the payload to JSON and use the client.rpc_func method to retrieve Pokémon information. ```lua local payload = { PokemonName = "dragonite"} local rpcid = "get_pokemon" local pokemon_info = client.rpc_func(rpcid, json.encode(payload)) pprint("Retrieved pokemon info:", pokemon_info) ``` -------------------------------- ### Get Session Details (Swift) Source: https://heroiclabs.com/docs/nakama/concepts/session/index.html Authenticate a device using its ID and retrieve session details like user ID, username, and expiration status. This Swift example uses async/await for handling the authentication response. ```swift let id = "3e70fd52-7192-11e7-9766-cb3ce5609916" var session = await client.authenticateDevice(id: id) debugPrint("Id: \(session.userId)", "Username: \(session.username)") debugPrint("Session expired? \(session.isExpired)") ``` -------------------------------- ### Authenticate Device with Nakama Unreal SDK Source: https://heroiclabs.com/docs/nakama/client-libraries/unreal/llm.md Demonstrates how to authenticate a device with the Nakama server using the Unreal SDK. It shows how to define and bind delegates for success and error callbacks. ```cpp FOnAuthUpdate AuthenticationSuccessDelegate; AuthenticationSuccessDelegate.AddDynamic(this, &ASagiShiActor::OnAuthenticationSuccess); FOnError AuthenticationErrorDelegate; AuthenticationErrorDelegate.AddDynamic(this, &ASagiShiActor::OnAuthenticationError); FString DeviceId = TEXT(""); FString Username = TEXT("NewUser"); bool bCreate = true; TMap Vars; Client->AuthenticateDevice(DeviceId, Username, Create, Vars, AuthenticationSuccessDelegate, AuthenticationErrorDelegate); /* Define callbacks */ void ASagiShiActor::OnAuthenticationSuccess(UNakamaSession* LoginData) { UE_Log(LogTemp, Log, TEXT("Login successful: %s"), *LoginData->SessionData.Username); } void ASagiShiActor::OnAuthenticationError(const FNakamaError& Error) { UE_LOG(LogTemp, Error, TEXT("Failed to login: %s"), *Error.Message); } ``` -------------------------------- ### Call Get Pokemon RPC via cURL Source: https://heroiclabs.com/docs/nakama/server-framework/lua-runtime/code-samples/llm.md This example shows how to call the 'get_pokemon' RPC endpoint using cURL. It demonstrates the correct URL, HTTP method, headers, and JSON payload required to retrieve Pokémon information. ```bash curl "http://127.0.0.1:7350/v2/rpc/get_pokemon" \ -H 'authorization: Bearer ' -d '"{\"PokemonName\": \"dragonite\"}"' ``` -------------------------------- ### Create Realtime Client and Connect Source: https://heroiclabs.com/docs/nakama/client-libraries/cpp/index.html Create a real-time client from the main client and establish a connection with the server using a session. This is necessary for gameplay and real-time features. ```cpp NRtClientPtr rtClient; rtClient = client->createRtClient(); bool createStatus = true; rtClient->connect(session, createStatus); ``` -------------------------------- ### Loaded Libraries Output Source: https://heroiclabs.com/docs/nakama/guides/server-framework/debugging-with-delve/index.html Example output showing loaded libraries, including the custom backend.so module. ```text 0. 0x7f8099127000 /lib/x86_64-linux-gnu/libdl.so.2 1. 0x7f8099106000 /lib/x86_64-linux-gnu/libpthread.so.0 2. 0x7f8098f45000 /lib/x86_64-linux-gnu/libc.so.6 3. 0x7f8099131000 /lib64/ld-linux-x86-64.so.2 4. 0x7f8062758000 /lib/x86_64-linux-gnu/libnss_files.so.2 5. 0x7f806177c000 /nakama/data/modules/backend.so ``` -------------------------------- ### C#: Create Party and Add to Matchmaker Source: https://heroiclabs.com/docs/nakama/concepts/multiplayer/matchmaker/llm.md Example of creating a party, accepting join requests, and adding the party to the matchmaker using the client SDK. ```csharp // Register the matchmaker matched handler (the party leader and party members should all do this) socket.ReceivedMatchmakerMatched += async matched => await socket.JoinMatchAsync(matched); // Create a party as the party leader var party = await socket.CreatePartyAsync(true, false, 2); // Accept any incoming party requests socket.ReceivedPartyJoinRequest += async request => { foreach (var presence in request.Presences) { await socket.AcceptPartyMemberAsync(request.PartyId, presence); } }; // As the leader of the party, add the entire party to the matchmaker var ticket = await socket.AddMatchmakerPartyAsync(party.Id, "*", 3, 4); ``` -------------------------------- ### Write Storage Objects (Defold Client) Source: https://heroiclabs.com/docs/nakama/concepts/storage/collections/llm.md Shows how to write storage objects using the Nakama Defold client. This example includes setting read/write permissions and versioning for the objects. ```lua local save_game = json.encode({ progress = 50 }) local my_stats = json.encode({ skill = 24 }) local can_read = 1 local can_write = 1 local version = "" local objects = { { collection = "saves", key = "savegame", permissionRead = can_read, permissionWrite = can_write, value = save_game, version = version, }, { collection = "stats", key = "skills", permissionRead = can_read, permissionWrite = can_write, value = my_stats, version = version, } } local result = client.write_storage_objects(objects) if result.error then print(result.message) return end for _,ack in ipairs(result.acks) do pprint(ack) end ``` -------------------------------- ### Install Docker on Droplet Source: https://heroiclabs.com/docs/nakama/guides/deployment/digital-ocean/llm.md Download and execute the Docker installation script to install Docker on your Digital Ocean droplet. This prepares the environment for running Nakama. ```sh curl -fsSL https://get.docker.com -o get-docker.sh sh get-docker.sh ``` -------------------------------- ### Install Dlvx Plugin in GoLand Source: https://heroiclabs.com/docs/nakama/guides/server-framework/debugging-with-delve/goland-debugger/index.html To enable debugging with Delve in GoLand, you must install the Dlvx plugin. Navigate to GoLand settings, then Plugins, search for 'Dlvx', and install it. ```GoLand GoLand > Settings > Plugins > Search for "Dlvx" > Install ``` -------------------------------- ### Run Local Development Server Source: https://heroiclabs.com/docs/nakama/tutorials/javascript/xoxo/index.html Start your local application server. Your application will be accessible at localhost:5000. ```bash npm run dev ``` -------------------------------- ### Install NPM Dependencies Source: https://heroiclabs.com/docs/nakama/tutorials/javascript/xoxo/index.html Install project dependencies using NPM. Run this command in your terminal. ```bash npm install ``` -------------------------------- ### Basic Hello World Module Initialization Source: https://heroiclabs.com/docs/nakama/server-framework/typescript-runtime/llm.md A simple 'Hello World' example for Nakama server runtime. This code must be placed in 'src/main.ts' and registered via the 'InitModule' function. ```typescript let InitModule: nkruntime.InitModule = function(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, initializer: nkruntime.Initializer) { logger.info("Hello World!"); } ``` -------------------------------- ### Get Subscription (cURL) Source: https://heroiclabs.com/docs/nakama/concepts/iap-validation/llm.md Make a GET request to retrieve subscription status using cURL. ```bash curl "http://127.0.0.1:7350/v2/iap/subscription/{productId} \ -H 'Authorization: Bearer ' ``` -------------------------------- ### Execute Lua Function (GET) Source: https://heroiclabs.com/docs/nakama/api Executes a Lua function on the server using a GET request. ```APIDOC ## GET /v2/rpc/{id} ### Description Execute a Lua function on the server. ### Method GET ### Endpoint /v2/rpc/{id} ``` -------------------------------- ### Swift: Create Party and Add to Matchmaker Source: https://heroiclabs.com/docs/nakama/concepts/multiplayer/matchmaker/llm.md Example of creating a party, accepting join requests, and adding the party to the matchmaker using the client SDK. ```swift // Register the matchmaker matched handler (the party leader and party members should all do this) socket.onMatchmakerMatched = { matched in print("Received MatchmakerMatched message: \(matched)") print("Matched opponents: \(matched.users)") } // Create a party as the party leader let party = try await socket.createParty(open: true, maxSize: 2) // Accept any incoming party requests socket.onPartyJoinRequest = { request in for presence in request.presences { Task { try await self.socket.acceptPartyMember(partyId: request.partyID, presence: presence.toUserPresence()) } } } // As the leader of the party, add the entire party to the matchmaker let ticket = try await socket.addMatchmakerParty(partyId: party.partyID, query: "*", minCount: 3, maxCount: 4) ``` -------------------------------- ### Install Project Dependencies Locally Source: https://heroiclabs.com/docs/nakama/server-framework/typescript-runtime/llm.md Installs all project dependencies, including development dependencies, using npm. ```bash npm i ``` -------------------------------- ### Nakama Configuration Example Source: https://heroiclabs.com/docs/nakama/getting-started/configuration/llm.md A comprehensive example of a Nakama server configuration file in YAML format. This covers all major sections like logger, database, runtime, socket, session, social, console, cluster, tracker, matchmaker, and IAP. ```yaml name: nakama-node-1 data_dir: "./data/" logger: stdout: false level: "warn" file: "/tmp/path/to/logfile.log" rotation: false max_size: 100 max_age: 0 max_backups: 0 local_time: false compress: false metrics: reporting_freq_sec: 60 namespace: "" prometheus_port: 7354 database: address: - "root@localhost:26257" conn_max_lifetime_ms: 0 max_open_conns: 0 max_idle_conns: 100 runtime: env: - "example_apikey=example_apivalue" - "encryptionkey=afefa==e332*u13=971mldq" path: "/tmp/modules/folders" http_key: "defaulthttpkey" socket: server_key: "defaultkey" port: 7350 max_message_size_bytes: 4096 # bytes read_timeout_ms: 10000 write_timeout_ms: 10000 idle_timeout_ms: 60000 write_wait_ms: 5000 pong_wait_ms: 10000 ping_period_ms: 8000 # Must be less than pong_wait_ms outgoing_queue_size: 16 session: encryption_key: "defaultencryptionkey" token_expiry_sec: 60 refresh_encryption_key: "defaultrefreshencryptionkey" refresh_token_expiry_sec: 3600 social: steam: publisher_key: "" app_id: 0 console: port: 7351 username: "admin" password: "password" cluster: join: - "10.0.0.2:7352" - "10.0.0.3:7352" gossip_bindaddr: "0.0.0.0" gossip_bindport: 7352 rpc_port: 7353 local_priority: true work_factor_interval_ms: 1000 tracker: max_delta_sizes: - 100 - 1000 - 10000 matchmaker: max_tickets: 2 interval_sec: 15 max_intervals: 3 iap: apple: shared_password: "password" google: client_email: "email@google.com" private_key: "pk" huawei: public_key: "pk" client_id: "id" client_secret: "secret" ``` -------------------------------- ### Install Rollup and Babel Dependencies Source: https://heroiclabs.com/docs/nakama/server-framework/typescript-runtime/llm.md Installs the necessary development dependencies for Rollup, Babel, and TypeScript compilation. ```bash npm i -D @babel/core @babel/plugin-external-helpers @babel/preset-env @rollup/plugin-babel @rollup/plugin-commonjs @rollup/plugin-json @rollup/plugin-node-resolve @rollup/plugin-typescript rollup tslib ``` -------------------------------- ### Install Nakama Runtime Types Source: https://heroiclabs.com/docs/nakama/server-framework/typescript-runtime/llm.md Installs the Nakama runtime types as a project dependency using NPM. ```shell npm i 'https://github.com/heroiclabs/nakama-common' ```