Leaderstats
Leaderstats and Leaderboards are easily confused by name alone, but they solve different problems. Leaderstats is the simple, per-player leaderstats folder that Roblox’s own client UI reads — the stats shown above a player’s head and in the player list, always live, never persisted by this module itself. Leaderboards is a persisted, queryable, cross-server ranking system — a global top-N over OrderedDataStores or a custom backend. If you want a global ranked list instead of a per-server display, that’s Leaderboards, not this module.
Mental model
Section titled “Mental model”Roblox’s player-list leaderboard is convention, not API: a Folder named leaderstats under the player, with Value instances inside. Leaderstats owns that wiring against the kernel’s session lifecycle:
kernel:onSession— on every session start, aleaderstatsfolder is created (or yourGetContainersupplies one), and one Value instance is created per declared stat, seeded from data.- A slow sweep (every
UpdateSeconds, default 1s, Background priority) copies current data values into the Value instances. You never push updates — write your data, the leaderboard follows within a second. session:bind— cleanup runs when the session ends. If the module created the folder it destroys it; if you suppliedGetContainerit destroys only the Value instances it made.
Each stat reads from the session’s profile data (session.Profile.Data, the persisted record from DataDriver) or the session’s transient data (session.Data). The default is profile if one exists, else session — persisted stats show persisted values without configuration.
local Root = game:GetService("ServerScriptService").ChloeKernelServerlocal Leaderstats = require(Root.Leaderstats)
return function(kernel) Leaderstats.attach(kernel, { Coins = { Field = "Coins" }, -- from session.Profile.Data Stage = { Field = "BestStage" }, Title = { Field = "Title", Kind = "StringValue", From = "Session" }, })endThat is the whole integration. session.Profile.Data.Coins += 100 shows on the leaderboard within the next sweep.
Configuration
Section titled “Configuration”Leaderstats.attach(kernel, stats, options?) — stats maps display names (what the player list shows) to:
| Field | Default | Description |
|---|---|---|
Field |
required | The data field to read |
From |
Profile if present, else Session | "Profile" (persisted, session.Profile.Data) or "Session" (transient, session.Data) |
Kind |
"IntValue" |
"IntValue", "NumberValue", or "StringValue" |
Options:
| Option | Default | Description |
|---|---|---|
UpdateSeconds |
1 |
Sweep cadence |
GetContainer |
creates leaderstats |
(player) → Instance — supply your own container (e.g. a folder another system also writes to). The module then only owns its Value instances |
SkipLoop |
false |
Don’t schedule the sweep (specs call sweep() by hand) |
API reference
Section titled “API reference”| Member | Description |
|---|---|
Leaderstats.attach(kernel, stats, options?) → handle |
Wire the mapping; hooks session start/end immediately |
handle.sweep() |
Run one update pass by hand |
handle.detach() |
Cancel the sweep, disconnect the session hook, clean up every tracked container/value |