Astro Leaderboard Free

Official Astro Leaderboard Free documentation for installing global Roblox rankings, connecting leaderstats or Player attributes, configuring boards and testing OrderedDataStore behavior.

On this page

Before you install

Install either Astro Leaderboard Free or Astro Leaderboard in one experience. Do not install both editions. They contain separate runtimes, stat observers, refresh loops and test commands that would compete with each other.

The package maintains an OrderedDataStore snapshot for global ranking. It does not replace your game’s main player data system. Continue saving and loading coins, wins or other values through your existing data service.

Astro Leaderboard Free displays placement, Roblox username and the configured amount. It is suitable for coins, wins, points, levels, donations, fastest times and other numeric values.

Installation

Place the supplied objects at these exact locations:

ServerScriptService
└── FreeLeaderboard
    ├── Config
    ├── LeaderboardService
    ├── Main
    └── NumberFormatter

Workspace
└── Leaderboard
    └── FreeLeaderboard

The required row path inside the board model is:

Cube.Part.SurfaceGui.Placements.ScrollingFrame.Row_1.Frame

Every row Frame must contain Placement, Name and Amount TextLabels. Keep Row_1, Row_2, Row_3 and Row_4. The first three rows preserve their individual Studio designs. Row_4 is cloned for every later placement.

You may change sizes, colours, fonts, padding and layout order in Studio. Do not rename the required objects unless you also update the service code.

First configuration

  1. Open ServerScriptService.FreeLeaderboard.Config.
  2. Give DataStore.Name a stable, unique name for this stat.
  3. Set Stat.Name to the exact numeric stat name used by your game.
  4. Confirm the configured BoardPath matches the model in Workspace.
  5. Replace the supplied TestCommand.AllowedUserIds entry with your own trusted tester IDs.
  6. Publish the experience before testing live OrderedDataStore data.

Keep DataStore.ReadInStudio and DataStore.WriteInStudio set to false unless Studio access to production data is deliberate.

Connect a stat

The service checks a matching ValueBase inside player.leaderstats first. If it is not present and Stat.ReadPlayerAttribute is enabled, the matching Player attribute is used as the fallback. Names are case-sensitive.

For a board whose ID and stat name are both Coins, either source works:

player.leaderstats.Coins.Value = 500
player:SetAttribute("Coins", 500)

IntValue and NumberValue are supported. Set Stat.PrintUpdates = true on a board while integrating if you want accepted changes printed to Output.

The first value discovered for a player is not immediately written. This avoids replacing a saved score with a temporary zero while another system is still loading player data. Later changes are buffered using DataStore.WriteFlushDelay.

Server API

Server scripts may update a configured board through the included service. Pass the board Id, not its visible title.

local Leaderboard = require(
    game.ServerScriptService.FreeLeaderboard.LeaderboardService
)

Leaderboard:SetPlayerStat(player, "Coins", 500)
Leaderboard:AddPlayerStat(player, "Coins", 25)

local coins = Leaderboard:GetPlayerStat(player, "Coins")
print("Current coins:", coins)

SetPlayerStat changes the matching leaderstat when it exists. Otherwise, it changes or creates the Player attribute when attribute reading is enabled. GetPlayerStat returns nil when no numeric source exists. These methods are server-only and must not be called from a LocalScript.

Useful refresh helpers are also available:

local ids = Leaderboard:GetBoardIds()
Leaderboard:RefreshNow("Coins")
Leaderboard:RefreshNow()

RefreshNow reads the current OrderedDataStore. It does not bypass a pending buffered write, and it does not reset the normal refresh timer.

Add more boards

Copy the short Board({...}) entry inside Config.Boards, duplicate the board model in Studio and change these values:

Setting Purpose
Id Unique internal identifier used by the server API
BoardPath Path below Workspace to this board model
Title Text displayed on the board
Stat.Name Exact leaderstat or Player attribute name
DataStore.Name Stable OrderedDataStore name for this ranking

Each board inherits BOARD_DEFAULTS. Add only the settings that differ from those defaults.

Board({
    Id = "Wins",
    BoardPath = { "Leaderboard", "TopWins" },
    Title = "Top Wins",
    Stat = { Name = "Wins" },
    DataStore = { Name = "Leaderboard_Wins_v1" },
    Rows = { MaximumEntries = 50 },
})

Use a different score DataStore name for each different stat. Two visual boards may share a DataStore only when they intentionally display the same stat and ranking.

Practical three-board pattern

A live game integration can define separate boards for best win streak, total wins and coins. Use one Board entry and one OrderedDataStore name for each stat. Highest streak and total wins should normally use descending order. Coins can use the same order with compact formatting enabled. Monotonic values such as lifetime wins and best streak should also be protected by your main data system so an older value cannot overwrite a newer maximum.

Configuration reference

Setting Recommended use
DataStore.Ascending false for highest first, true for lowest first such as fastest times
DataStore.WriteFlushDelay Combines rapid stat changes before writing. Default is 15 seconds
Rows.MaximumEntries Number of placements from 1 to 100
Rows.TemplateRank Keep at 4 for the supplied row design
Rows.ShowEmptyRows Show or hide placeholder rows without entries
Rows.BatchSize and BatchDelay Spread row rendering over small batches
Refresh.InitialDelay Delay before the first server refresh. Default is 5 seconds
Refresh.Interval Time between ranking reads. Default is 300 seconds
Refresh.RetryCount and RetryDelay Recovery from temporary Roblox service failures

Number formatting

Set Formatting.Abbreviate = false to show complete values with a thousands separator. When abbreviation is enabled, Formatting.Suffixes may use any sequence:

Suffixes = { "K", "M", "B", "T" }
Suffixes = { "A", "B", "C", "D" }
Suffixes = { "AA", "AB", "AC", "AD" }

Formatting.Base = 1000 makes each suffix the next power of 1,000. DecimalPlaces and TrimTrailingZeros control compact decimals.

Studio testing

Start a Studio playtest and run:

/lb load 100

This fills the display with temporary values and real public Roblox usernames. It does not write fake scores to OrderedDataStore. Run /lb clear to return to real data.

The command only accepts users listed in TestCommand.AllowedUserIds. Replace the included ID with your own trusted user ID before release. Disable the command entirely when it is not needed.

Troubleshooting

The board is empty in Studio

ReadInStudio is disabled by default to protect live data. Use /lb load 100 for safe temporary entries. Only enable Studio API access and real reads when you understand the production data impact.

A stat does not update

Check the exact capitalisation of Stat.Name, confirm the leaderstat is numeric, and temporarily enable Stat.PrintUpdates. Remember that writes wait for WriteFlushDelay and the board reads again on Refresh.Interval.

A row or title is missing

Read the first setup warning in Output. The service validates board paths, templates, labels and configuration once at startup without flooding Output. Restore the required object name or hierarchy, then restart the playtest.

Upgrading to Astro Leaderboard

Remove the complete FreeLeaderboard script folder and all Free board models first. Then install the paid package and its paid board models. Never leave both runtimes in the experience.