• Studio

  • Bots

  • Web API

  • Designer Resources

  • Host Resources







    Leaderboards are a common feature in games that display the top scores of players, allowing them to compete with each other and track their progress. In Highrise, you can create leaderboards to showcase the achievements of players in your worlds.

    Create a Leaderboard in Your World

    1. Right-click in the Hierarchy window and select Empty Object
    2. Give the object a name (e.g., Leaderboard)
    3. Right-click in the Project window and select Create > Lua > UI
    4. Name the UI script (e.g., ranking`)
    5. Drag and drop the UI script onto the Leaderboard object in the Hierarchy window
    6. Set the Output to World in the Inspector
    7. Change the scale and position of the object to fit your world

    When you create a new UI script, it will automatically generate a UXML, USS, and Lua file. The UXML file defines the layout of the UI elements, the USS file styles the UI elements, and the Lua file contains the logic for the UI.

    Write Lua Script for Leaderboard

    To make life easier, you can create 2 separate modules for the leaderboard: one for tracking player scores and another for communicating with the UI.

    1. Create Player Tracker Module

    The player tracker module will keep track of player scores and update the leaderboard accordingly.

    1. Right-click in the Project window and select Create > Lua > Module
    2. Name the module (e.g., PlayerTracker)
    3. Create an empty object in the Hierarchy window and attach the PlayerTracker module to it
    4. Write the following code inside the PlayerTracker module:
    -- Event for requesting top players list from server
    local GetTopPlayersRequest = Event.new("GetTopPlayersRequest") 
    -- Event for receiving top players list from server
    local GetTopPlayersResponse = Event.new("GetTopPlayersResponse") 
    local players = {} -- Table to store player scores
    local topPlayers = {} -- Table to store top players
    -- Function to track players when they connect to the game
    function TrackPlayers(game)
        -- Initialize player info with score set to 0
        players[player.name] = {
          player = player,
          score = 0
    -- Function to get and sort top players list
    GetTopPlayers = function()
      -- Sort top players list
      if topPlayers ~= nil and #topPlayers > 0 then
        table.sort(topPlayers, function(a, b)
          return a.score > b.score
      return topPlayers
    -- Function to handle client initialization
    function self:ClientAwake()
      -- Track players when client initializes
      -- Request the top players from the server when the client initializes
      -- Handle response from server containing top players list
        -- Override the local top players list with the updated list from the server
        topPlayers = newTopPlayers
    -- Function to handle server initialization
    function self:ServerAwake()
      -- Track players when server initializes
      -- Retrieve the top players list from storage
      Storage.GetValue("TopPlayers", function(oldList)
        if oldList == nil then oldList = {} end
        topPlayers = oldList
      -- Handle request for top players list from client
        -- Retrieve the top players list from storage
        Storage.GetValue("TopPlayers", function(oldList)
          if oldList == nil then oldList = {} end
          topPlayers = oldList
          -- Send the top players list to the client

    The example above doesn't have a complete implementation of the individual player score tracking. You will need to implement the logic to update player scores based on player actions in your world. See the example below for a simple implementation.

    Assuming you have a function to update player scores based on player actions, you can update the top players list as follows:

    -- Update top players list
    local playerEntry = { name = player.name, score = newScore }
    -- Check if the player is already in the top players list
    local found = false
    for i = 1, #topPlayers do 
      if topPlayers[i].name == player.name then
        topPlayers[i] = playerEntry
        found = true
    -- If the player is not in the top players list, add them
    if not found then
      table.insert(topPlayers, playerEntry)
    -- Update the top players list on all clients
    -- Save the updated top players list to storage
    Storage.SetValue("TopPlayers", topPlayers)

    2. Write UXML Script for Leaderboard

    <?xml version="1.0" encoding="utf-8"?>
      <hr:UILuaView class="ranking">
        <VisualElement class="header">
            <Label class="title" text="Global Leaderboard" />
            <Label class="update" text="Updates every 5 seconds" />
        <VisualElement class="content" name="_content">
          <VisualElement class="rank-list" name="_ranklist">
            <!-- Rank Items will be added here -->

    3. Write USS Script for Leaderboard

    * {
      padding: 0;
      margin: 0;
      flex-shrink: 0;
      overflow: hidden;
    .ranking {
      flex-grow: 1;
      display: flex;
      flex-direction: column;
      padding: 20px;
      background-color: rgba(0, 0, 0, 0.5);
      -unity-font-definition: var(--font-regular);
      height: 100%;
      width: 100%;
      border-radius: 12px;
    .ranking .header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      align-self: center;
      color: #ac9d5b;
      text-shadow: 2px 2px 0px rgba(0, 0, 0, 0.5);
      margin-bottom: 20px;
    .header .title {
      font-size: 75px;
    .header .update {
      font-size: 40px;
    .ranking .content {
      display: flex;
      align-items: center;
      width: 100%;
      height: 100%;
      padding: 20px;
      text-shadow: 2px 2px 0px rgba(255, 255, 255, 0.5);
    .content .rank-list {
      width: 100%;
      font-size: 35px;
    .content .rank-item {
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      align-items: center;
      width: 100%;
      padding: 10px;
      margin-bottom: 15px;
      border-radius: 10px;
      color: #ac9d5b;
      background-color: rgba(0, 0, 0, 0.1);
    .rank-item .name-label {
      flex-grow: 1;
      margin-left: 20px;
    .first {
      font-size: 60px;
    .second {
      font-size: 50px;
    .third {
      font-size: 40px;

    4. Update Lua Script for Leaderboard

    In our Lua script, we will create a function to update the leaderboard UI with the top players list. The leaderboard will display top 8 players based on their scores and it will update every 5 seconds.

    In the example below, the players table and score are hardcoded for demonstration purposes. You should replace this with the actual player data and scores from the player tracker module.

    local _content : VisualElement = nil
    local _ranklist : VisualElement = nil
    -- Require the PlayerTracker module
    local playerTracker = require("PlayerTracker")
    -- Function to update the leaderboard UI with the top players list
    function UpdateLeaderboard(players)
      _ranklist:Clear() -- Clear the current leaderboard
       if not players or #players == 0 then return end -- Return if there are no players
       local count = #players -- Get the number of players
       if count > 8 then count = 8 end -- Display only the top 8 players
       for i = 1, count do
        -- Create a rank item for each player
        local _rankItem = VisualElement.new()
        local entry = players[i] -- Get the player entry
        local name = entry.name -- Get the player name
        local score = entry.score -- Get the player score
        -- Create a label for the player rank
        local _rankLabel = UILabel.new()
        _rankLabel:SetPrelocalizedText("#" .. i)
        -- Create a label for the player name
        local _nameLabel = UILabel.new()
        -- Create a label for the player score
        local _scoreLabel = UILabel.new()
        -- Add the labels to the rank item
        -- Add the placement class based on the rank
         if i == 1 then
        elseif i == 2 then
        elseif i == 3 then
        -- Add the rank item to the rank list
    local cooldown = 5 -- Update every 5 seconds
    local timer = 0 -- Timer to keep track of the time
    local players = {
      { name = "Player1", score = 100 },
      { name = "Player2", score = 90 },
      { name = "Player3", score = 80 },
      { name = "Player4", score = 70 },
      { name = "Player5", score = 60 },
      { name = "Player6", score = 50 },
      { name = "Player7", score = 40 },
      { name = "Player8", score = 30 }
    -- Function to update the leaderboard
    function self:ClientUpdate()
      timer = timer + Time.deltaTime -- Increment the timer
      if timer >= cooldown then
        -- Generate random scores for demonstration purposes
        for i = 1, #players do
          players[i].score = math.random(1, 100)
        -- Sort the players table based on scores
        table.sort(players, function(a, b)
          return a.score > b.score
        -- Update the leaderboard UI with the top players list
        timer = 0 -- Reset the timer

    Test Your Leaderboard

    Now that you have created the player tracker module and the leaderboard UI, you can test your leaderboard by running your world in Unity. The leaderboard will be updated every 5 seconds with the top 8 players based on their scores.


    Leaderboards are a great way to engage players and encourage competition in your worlds. By implementing a leaderboard system, you can showcase the achievements of players and create a sense of accomplishment for those who reach the top. Experiment with different leaderboard designs and features to enhance the player experience and keep them coming back for more!

    Updated 16 days ago

    PocketWorlds Icon

    © 2024 Pocket Worlds. All rights reserved.