Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

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

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
  1. Create a Script and place it inside of the ServerScriptService

  2. 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)
  1. Check 'Enable Studio Access to API Services' located in the Configure this game settings.

  2. Report back your findings.

Any help would be appreciated, thanks.

5 comments

0

because you need to enable api access for data stores in the place settings

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?

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

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.

0

TABLES ARE BROKE PEOPLE ITS 2018

1 answer

✓ Accepted answer

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

4 comments

0

Thank you sir, I will give all of this a try right now.

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

0

Based on https://devforum.roblox.com/t/datastores-automatic-retry/42326/29 I think that automated retries are not actually implemented/enabled.

0

Oh, you're right. I guess it's always better to go look, than believe people because somebody told me that.

This discussion is preserved as it was. New answers, comments, and votes are closed.