Dynamic leaderboard/s with fixed capacity of players

Hello,

Just wanted to use nakama leaderboard feature for our existing game. Here is my query and i wanted to know how can i achieve this task efficiently,

  • We have scheduled event running every week and every event should have separate leaderboard/s with 20player/leaderboard. When user base grows we will have different leaderboard for the same event. e.g “Event-1-Leaderboard-1” when filled with 20 players, server check and create a new leaderboard and place 21st player and onwards in “Event-1-Leaderboard-2” and so on. We need to create a pool of 20 players in a single leaderboard.

What i have in mind is something like this.

  • Player send call to server to join a leaderboard with event-id (i don’t want to couple player/user id with leaderboard).
  • Server checks if leaderboard exist with the event-id and not full than assign the leaderboard id and send call back to client.
  • In response client save that leaderboard id and initiate submit score request with score and username against that leaderboard id.
  • In response server put player score in that leaderboard with username as well and send a call back to client (may be with a list of current players with score and username in that leaderboard)

Is this possible ? how to achieve this task.

PS: I can’t find any server side function to check if leaderboard with a particular id exist or not.

Thanks.

Hi folks,

Just wanted to update this if anyone want something similar. I have done above task using nakama leaderboard and runtime code. Will post server side lua module code here after thorough testing, so that others can have idea about the approach and any improvements are always welcome. Stay tuned.

Thanks

1 Like

Alright, so here is the server side code written in lua and that’s what i have ended up with, anyone can modify and write better than this :slight_smile: and adjust according to the needs.

local nk = require("nakama");

Table used to store constants. “playerLimit” is the limit after which server will create new leaderboard for next players who will send join leaderboard request to server from client side.

local lb = {
    playerLimit = 20
}

Table used to manipulate logic and conditional statements.

lb1 = {
    lbCounter = 0,
    playerCounter = 0
}

Indexer used for events table.

events = {
  counter = 0
}

Table used to save events.

local eventIndexes = {}

Helper functions to check if given value exists in given array.

local function contains(array, val)
   for i=0,#array do
      if array[i] == val then 
         return true
      end
   end
   return false
end

The main function executing core logic and creating leaderboards when necessary, otherwise will return existing leaderboard id and title. It assume event_id to be passed from client side when calling rpc.

function lb.join_leaderboard(context, payload)
  local data = nk.json_decode(payload)
  local lbID = data.eventID .. "." .. lb1.lbCounter
  
  if contains(eventIndexes, data.eventID) then
    nk.logger_info("Event found")
  else
    rawset(lb1, "playerCounter", 0)
    nk.logger_info("Event not found - creating lb " .. lbID)
    
    if(lb1.playerCounter == 0 or lb1.playerCounter >= lb.playerLimit) then
      nk.leaderboard_create(lbID, false, "desc", "set")
      
      eventIndexes[events.counter] = data.eventID
      rawset(events, "counter", events.counter + 1)
    end
  end
  
  rawset(lb1, "playerCounter", lb1.playerCounter + 1)
  
  if(lb1.playerCounter >= lb.playerLimit) then
    rawset(lb1, "playerCounter", 0)
    rawset(lb1, "lbCounter", lb1.lbCounter + 1)
  end
  
  return nk.json_encode({ AssignedLeaderboardID = lbID, AssignedLeaderboardTitle = tostring(lb1.lbCounter) })
  
end

PS: Currently it assume one event is running at a time, if multiple events are running then some adjustments in code required. Probably remove event indexes and counter and use dictionary to store separate counter for every event that way player limit for multiple leaderboards can be handled.