Skip to content

Usage Examples

💰 Currency Management with Validation

Example
lua
-- Award coins (validation handled internally)
local function awardCoins(player, amount, source)
    local currentCoins = PlayerState.Get(player, "Coins") or 0
    local success = PlayerState.Set(player, "Coins", currentCoins + amount)

    if success then
        print(`Awarded {amount} coins to {player.Name} from {source}`)
        return true
    else
        warn(`Failed to award coins to {player.Name}`)
        return false
    end
end

-- Spend coins with validation
local function spendCoins(player, amount, item)
    local currentCoins = PlayerState.Get(player, "Coins") or 0
    if currentCoins < amount then
        return false, "Insufficient coins"
    end

    local success = PlayerState.Set(player, "Coins", currentCoins - amount)
    if success then
        print(`{player.Name} spent {amount} coins on {item}`)
        return true, "Purchase successful"
    else
        return false, "Transaction failed"
    end
end

📈 Level System with Batch Operations

Example
lua
-- Level up player with batch operations
local function levelUp(player)
    local currentLevel = PlayerState.Get(player, "Level") or 1
    local currentCoins = PlayerState.Get(player, "Coins") or 0
    local bonusCoins = currentLevel * 100

    local success = PlayerState.BatchSetValues(player, {
        {path = "Level", value = currentLevel + 1},
        {path = "Experience", value = 0},
        {path = "Coins", value = currentCoins + bonusCoins}
    })

    if success then
        print(`{player.Name} leveled up to {currentLevel + 1}!`)
        return true
    end

    return false
end

-- Add experience with level up check
local function addExperience(player, amount)
    local currentExp = PlayerState.Get(player, "Experience") or 0
    local currentLevel = PlayerState.Get(player, "Level") or 1
    local expNeeded = currentLevel * 100

    local newExp = currentExp + amount

    if newExp >= expNeeded then
        -- Level up
        levelUp(player)
    else
        -- Just add experience
        PlayerState.Set(player, "Experience", newExp)
    end
end

🎒 Enhanced Inventory Management

Example
lua
local MAX_INVENTORY_SIZE = 50

-- Add item with validation and limits
local function addItem(player, item)
    local inventory = PlayerState.GetPath(player, "Inventory") or {}
    if #inventory >= MAX_INVENTORY_SIZE then
        return false, "Inventory full"
    end

    -- Add timestamp to item
    item.AcquiredTime = os.time()

    local success = PlayerState.AddToArray(player, "Inventory", item)
    if success then
        print(`Added {item.Name} to {player.Name}'s inventory`)
        return true, "Item added"
    end

    return false, "Failed to add item"
end

-- Remove item by ID
local function removeItemById(player, itemId)
    local inventory = PlayerState.GetPath(player, "Inventory") or {}

    for index, item in ipairs(inventory) do
        if item.Id == itemId then
            local success = PlayerState.RemoveFromArray(player, "Inventory", index)
            if success then
                print(`Removed {item.Name} from {player.Name}'s inventory`)
                return true
            end
            break
        end
    end

    return false
end

-- Upgrade item in inventory
local function upgradeItem(player, itemIndex, newStats)
    local inventory = PlayerState.GetPath(player, "Inventory") or {}
    local item = inventory[itemIndex]

    if not item then
        return false, "Item not found"
    end

    -- Merge new stats
    for key, value in pairs(newStats) do
        item[key] = value
    end

    -- Update upgraded time
    item.UpgradedTime = os.time()

    local success = PlayerState.UpdateArrayItem(player, "Inventory", itemIndex, item)
    if success then
        print(`Upgraded {item.Name} for {player.Name}`)
        return true
    end

    return false, "Upgrade failed"
end

🏆 Leaderboard Management

Example
lua
-- Server: Comprehensive leaderboard system with validation
local function setupLeaderboardSystem()
    -- Configuration reminder
    -- Make sure PlayerStateConfig.Server.Leaderboard is properly configured!

    -- ✅ Get top 10 players for coins (works if configured)
    local topCoins = PlayerState.GetLeaderboard("Coins", 10)
    if #topCoins > 0 then
        for rank, entry in ipairs(topCoins) do
            print(`#{rank}: User {entry.userId} - {entry.score} coins`)
        end
    else
        print("No coin leaderboard data available (check configuration)")
    end

    -- ✅ Get player's current rank (returns nil if not ranked)
    local playerRank = PlayerState.GetPlayerRank(player, "Coins")
    if playerRank then
        print(`You're currently ranked #{playerRank} for coins!`)
    else
        print("You're not yet ranked for coins")
    end

    -- ✅ Manual leaderboard update (for special cases)
    local success = PlayerState.UpdateLeaderboard(player, "HighScore", 2500)
    if success then
        print("High score leaderboard updated!")
    else
        print("Failed to update leaderboard (check configuration)")
    end
end

-- Safe leaderboard usage with error handling
local function safeLeaderboardUsage()
    -- Always check if leaderboard is available before heavy usage
    local testBoard = PlayerState.GetLeaderboard("Coins", 1)
    if #testBoard == 0 then
        warn("Leaderboard not configured properly - check PlayerStateConfig")
        return false
    end

    -- Proceed with leaderboard operations
    local playerRank = PlayerState.GetPlayerRank(player, "Coins")
    return PlayerState.UpdateLeaderboard(player, "Coins", 100)
end

-- Get multiple leaderboard stats at once
local function getPlayerStatsSummary(player)
    local stats = {
        coinRank = PlayerState.GetPlayerRank(player, "Coins"),
        levelRank = PlayerState.GetPlayerRank(player, "Level"),
        scoreRank = PlayerState.GetPlayerRank(player, "HighScore"),
    }

    -- Display player's rankings
    for statName, rank in pairs(stats) do
        if rank then
            print(`{statName}: Rank #{rank}`)
        else
            print(`{statName}: Not ranked yet`)
        end
    end

    return stats
end

-- Leaderboard UI data
local function getLeaderboardUIData(statName, maxEntries)
    local leaderboard = PlayerState.GetLeaderboard(statName, maxEntries or 50)
    local uiData = {}

    for i, entry in ipairs(leaderboard) do
        table.insert(uiData, {
            rank = entry.rank,
            userId = entry.userId,
            score = entry.score,
            displayName = "Loading...", -- You'll need to get this from Player service
        })
    end

    return uiData
end

-- Periodic leaderboard announcements
local function announceTopPlayers()
    local topPlayers = PlayerState.GetLeaderboard("Coins", 3)

    if #topPlayers >= 3 then
        print("🏆 TOP 3 RICHEST PLAYERS 🏆")
        for i, entry in ipairs(topPlayers) do
            local medal = i == 1 and "🥇" or i == 2 and "🥈" or "🥉"
            print(`{medal} #{i}: User {entry.userId} - {entry.score} coins`)
        end
    end
end

🏠 Plot Building System

Example
lua
-- Build structure on plot (efficient nested updates)
local function buildStructure(player, buildingType, position)
    local buildingData = {
        Type = buildingType,
        Level = 1,
        Position = position,
        BuiltTime = os.time(),
        Health = 100
    }

    local buildingId = `{buildingType}_{os.time()}`
    local success = PlayerState.SetInDict(player, "Plot.Buildings", buildingId, buildingData)

    if success then
        print(`{player.Name} built {buildingType} at {position}`)
        return true, buildingId
    end

    return false, "Build failed"
end

-- Upgrade building (efficient single-key update)
local function upgradeBuilding(player, buildingId)
    local building = PlayerState.GetPath(player, `Plot.Buildings.{buildingId}`)
    if not building then
        return false, "Building not found"
    end

    building.Level = building.Level + 1
    building.UpgradedTime = os.time()

    local success = PlayerState.SetInDict(player, "Plot.Buildings", buildingId, building)
    if success then
        print(`{player.Name} upgraded {building.Type} to level {building.Level}`)
        return true
    end

    return false, "Upgrade failed"
end

-- Remove building (efficient key removal)
local function removeBuilding(player, buildingId)
    local success = PlayerState.RemoveFromDict(player, "Plot.Buildings", buildingId)
    if success then
        print(`{player.Name} removed building {buildingId}`)
        return true
    end

    return false, "Removal failed"
end

🔄 Event-Driven Data Management

Example
lua
-- Setup event handlers for comprehensive data management
local function setupPlayerStateEvents()
    -- When player data loads
    PlayerState.ProfileLoaded:Connect(function(player, data)
        -- Welcome back message
        local loginCount = (data.Stats.Logins or 0) + 1
        PlayerState.SetPath(player, "Stats.Logins", loginCount)
        PlayerState.Set(player, "LastJoinTime", os.time())

        -- Check for daily rewards
        local lastReward = data.Stats.LastDailyReward or 0
        local currentDay = math.floor(os.time() / 86400) -- Days since epoch

        if currentDay > lastReward then
            PlayerState.SetPath(player, "Stats.LastDailyReward", currentDay)
            PlayerState.Increment(player, "Coins", 100)
            print(`{player.Name} received daily reward!`)
        end

        -- Initialize player systems
        setupPlayerUI(player)
        setupPlayerEffects(player)
    end)

    -- Before data saves
    PlayerState.BeforeSave:Connect(function(player, data)
        -- Final cleanup and validation
        data.LastSaveTime = os.time()

        -- Calculate session playtime
        local joinTime = data.LastJoinTime or os.time()
        local sessionTime = os.time() - joinTime
        local totalPlayTime = (data.Stats.TotalPlayTime or 0) + sessionTime

        PlayerState.SetPath(player, "Stats.TotalPlayTime", totalPlayTime)
        PlayerState.SetPath(player, "Stats.LastSessionTime", sessionTime)

        -- Validate data integrity
        if data.Coins and data.Coins < 0 then
            warn(`{player.Name} had negative coins, resetting to 0`)
            PlayerState.Set(player, "Coins", 0)
        end

        print(`Saving {player.Name}'s data - Session: {sessionTime}s, Total: {totalPlayTime}s`)
    end)

    -- When profile unloads
    PlayerState.ProfileUnloaded:Connect(function(player, data)
        -- Analytics and external system updates
        local finalStats = {
            userId = player.UserId,
            coins = data.Coins or 0,
            level = data.Level or 1,
            totalPlayTime = data.Stats.TotalPlayTime or 0,
            logins = data.Stats.Logins or 0
        }

        -- Send to analytics (direct data access only)
        sendToAnalytics(finalStats)

        -- Cleanup player-specific systems
        cleanupPlayerUI(player)
        cleanupPlayerEffects(player)

        print(`{player.Name} profile unloaded - Final coins: {finalStats.coins}`)
    end)
end

-- Call this during server startup
setupPlayerStateEvents()

PlayerState - High-Performance Roblox Data Management