-- Get username for metadatalocal users = nk.users_get_id({owner_id})local username = users and users[1] and users[1].username or "unknown"local metadata = {mode = "normal", username = username}-- Write with pcall for safetylocal ok, err = pcall(function() nk.leaderboard_record_write(leaderboard_id, owner_id, username, score, subscore, metadata)end)if ok then print("✅ Leaderboard:", leaderboard_id) else print("❌", err) end
Streak Tracking Pattern
-- Read current streak from storagelocal key = "game_streak"local streak = 1local read = nk.storage_read({{collection="game", key=key, user_id=winner_id}})if read and read[1] and read[1].value then streak = (read[1].value.streak or 0) + 1end-- Persist streaknk.storage_write({{collection="game", key=key, user_id=winner_id, value={streak=streak}, permission_read=1, permission_write=0}})-- Write to leaderboardnk.leaderboard_record_write("game_streak", winner_id, username, streak, 0, metadata)-- Reset losernk.storage_write({{collection="game", key=key, user_id=loser_id, value={streak=0}, permission_read=1, permission_write=0}})
local activity = require("activity_utils")-- On match end:activity.record_match_completion(players, "game_id", winner_id, {moves=N, durationSeconds=T})-- Activity types: match, leaderboard, achievement, friend, level, social
Match Handler Template
if state.winner and not state.resultNotified then state.resultNotified = true local winner, loser = state.winner, nil for _, p in ipairs(state.players) do if p ~= winner then loser = p break end end -- 1. Activity activity.record_match_completion(state.players, "game", winner, {moves=state.moves}) -- 2. Wins (incr) nk.leaderboard_record_write("game_wins", winner, username, 1, 0, meta) -- 3. Efficiency (best asc) nk.leaderboard_record_write("game_efficiency", winner, username, state.moves, 0, meta) -- 4. Streak (storage + best) -- [see streak pattern above] -- 5. Elo (set) -- [see elo pattern above]end
Data Seed (nakama-modules/data-seed.lua)
local boards = {"game_wins", "game_elo", "game_streak", "game_efficiency"}for _, id in ipairs(boards) do pcall(function() if id:match("_wins$") then nk.leaderboard_create(id, false, "desc", "incr", "", {}) elseif id:match("_elo$") then nk.leaderboard_create(id, false, "desc", "set", "", {}) elseif id:match("_streak$") then nk.leaderboard_create(id, false, "desc", "best", "", {}) elseif id:match("_efficiency$") then nk.leaderboard_create(id, false, "asc", "best", "", {}) end end)end