Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

Why doesn't this method straight from the wiki work?

Asked by 6 years ago
Edited 6 years ago

For several days I have been wondering why this method of saving player data doesn't work. Can anyone try this method out, and vouch that it doesn't work?

What would you need to do to test:

1) Create a ModuleScript

2) Place the ModuleScript inside the ServerStorage

3) Paste this code unedited, directly from the wiki inside the ModuleScript:

-- Set up table to return to any script that requires this module script
local PlayerStatManager = {}

local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("PlayerData")

-- Table to hold player information for the current session
local sessionData = {}

local AUTOSAVE_INTERVAL = 60

-- Function that other scripts can call to change a player's stats
function PlayerStatManager:ChangeStat(player, statName, value)
    assert(typeof(sessionData[playerUserId][statName]) == typeof(value), "ChangeStat error: types do not match")
    local playerUserId = "Player_" .. player.UserId
    if typeof(sessionData[playerUserId][statName]) == "number" then
        sessionData[playerUserId][statName] = sessionData[playerUserId][statName] + value
    else
        sessionData[playerUserId][statName] = value
    end
end

-- Function to add player to the 'sessionData' table
local function setupPlayerData(player)
    local playerUserId = "Player_" .. player.UserId
    local data
    local success, err = pcall(function()
        playerData:UpdateAsync(playerUserId, function(playerData)
            data = playerData
        end)
    end)

    if success then
        if data then
            -- Data exists for this player
            sessionData[playerUserId] = data
        else
            -- Data store is working, but no current data for this player
            sessionData[playerUserId] = {Money=0, Experience=0}
        end
    else
        warn("Cannot set up data for player!")
    end
end

-- Function to save player's data
local function savePlayerData(playerUserId)
    if sessionData[playerUserId] then
        local success, err = pcall(function()
            playerData:SetAsync(playerUserId, sessionData[playerUserId])
        end)
        if not success then
            warn("Cannot save data for player!")
        end
    end
end

-- Function to save player data on exit
local function saveOnExit(player)
    local playerUserId = "Player_" .. player.UserId
    savePlayerData(playerUserId)
end

-- Function to periodically save player data
local function autoSave()
    while wait(AUTOSAVE_INTERVAL) do
        for playerUserId, data in pairs(sessionData) do
            savePlayerData(playerUserId)
        end
    end
end

-- Start running 'autoSave()' function in the background
spawn(autoSave)

-- Connect 'setupPlayerData()' function to 'PlayerAdded' event
game.Players.PlayerAdded:Connect(setupPlayerData)

-- Connect 'saveOnExit()' function to 'PlayerRemoving' event
game.Players.PlayerRemoving:Connect(saveOnExit)

return PlayerStatManager

4) Create a Script and place it inside of the ServerScriptService

5) Copy this code into the script:

local serverstorage = game:GetService("ServerStorage")
local module = require(serverstorage.ModuleScript)

game:GetService("Players").PlayerAdded:Connect(function(player)
    local stats = Instance.new("Folder")
    stats.Name = 'leaderstats'
    stats.Parent = player

    local money = Instance.new("NumberValue")
    money.Name = 'Money'
    money.Parent = stats

    local experience = Instance.new("NumberValue")
    experience.Name = 'Experience'
    experience.Parent = stats

    module:ChangeStat(player, 'Money', 5)
end)

6) Check 'Enable Studio Access to API Services' located in the Configure this game settings.

7) Report back your findings.

Any help would be appreciated, thanks.

0
because you need to enable api access for data stores in the place settings User#5423 17 — 6y
0
Thanks for the feedback, but that's not the problem as I've already done that. Did you even read #7? Or even try it for yourself? KardashevScale 110 — 6y
0
You never mention what is the problem. "Why doesn't this code work?" isn't a question people can answer, as not everyone has the entire roblox lua vm in their brain. At least provide details, such as if it errors, or add prints to where it saves the data and see if it prints. Same for loading it. Btw you swapped #7 and #6 Amiaa16 3227 — 6y
0
If you don't know, then just read it and move on. There is no need to try to belittle me because you don't like the question that I asked. If you would've bothered to actually follow any of these steps, then you would understand my question. KardashevScale 110 — 6y
0
TABLES ARE BROKE PEOPLE ITS 2018 AnotherPerson_999 28 — 6y

1 answer

Log in to vote
2
Answered by 6 years ago
Edited 6 years ago

They have a mistake in their code that the Script Analysis window finds immediately -- playerUserId does not exist at the time of the assert - the assert line needs to be moved down one line.

Also, note that the script doesn't do anything obvious by default - it doesn't connect to any sort of leaderstats or print out any values. If you don't call ChangeStat or otherwise modify sessionData yourself, the Money and Experience it's saving will always stay at 0. Now, in your second script, you do call ChangeStat, but the wiki's script isn't connected to the leaderstats in any way, and you don't read from sessionData (which you can't because they didn't create a GetStat function). You'll have to make changes to the original script so that you can update the leaderboard when a player's data is returned and so that any changes you make to the leaderboard are reflected in the sessionData table. Merging your leaderboard and datastore scripts might be sensible here.

One more thing - the wiki script has a memory leak. When a player leaves the game, their session data should be removed. saveOnExit should therefore be:

local function saveOnExit(player)
    local playerUserId = "Player_" .. player.UserId
    if sessionData[playerUserId] then
        savePlayerData(playerUserId)
        sessionData[playerUserId] = nil
    end
end
0
Thank you sir, I will give all of this a try right now. KardashevScale 110 — 6y
0
Also what's weird is on the old wiki, I think I found a version of their script that does all of that, but was unsure if I should use it because it was made before retries were automated: http://wiki-origin.roblox.com/index.php?title=Saving_Player_Data KardashevScale 110 — 6y
0
Based on https://devforum.roblox.com/t/datastores-automatic-retry/42326/29 I think that automated retries are not actually implemented/enabled. chess123mate 5873 — 6y
0
Oh, you're right. I guess it's always better to go look, than believe people because somebody told me that. KardashevScale 110 — 6y
Ad

Answer this question