I'm trying to create a small game and try to learn Lua by creating a problem I want in my game and trying to code them. I wanted to create Data storage. I used the Roblox tutorial https://developer.roblox.com/en-us/articles/Saving-Player-Data.

I understand all the lines except for this.

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

To my understanding that a function that given the player, stat name, and value will save the value if it's a number and if a string will save value as the name of the string. If this is correct how would I go about calling this code from a different script attached to a part?

For Instance, I created a small sphere and added particle effects to represent experience orbs, Once the player comes in contact I was going to create a hit function that destroys the orb and updates the player's experience using and UpdateAsync.

How would I go calling the function or am I just supposed to return values and it saves it. I really want to understand more than anything. I tried to look at Roblox Studio Base games and other videos online. The Roblox Studio Line runner game almost had what I was looking for , but I believe it's different because it just creates a clone of the script.

Additionally, am I going about data stores the correct way I saw some other videos online of people creating folders and saving values into those folders would that be more efficient then how I'm going about this currently? Any help is greatly appreciated

One last thing I noticed most people put files into ServerScriptService or ServerStorage. At the start of the tutorial, it instructs you to make a ModuleScript and put it in the ServerStorage. Everyone seems to put it in the ServerScriptService which I believe ran as soon as the game is launched. I was reading up on ModuleScript and has stated on the Roblox Wiki

A ModuleScript is a type of Lua source container that runs once and must return exactly one value. This value is then returned by a call to require given the ModuleScript as the only argument. ModuleScripts run once and only once per Lua environment and return the exact same value for subsequent calls to require.

Is this only supposed to actually return a single value? I know this is meant to used functions over and over, but any help on that would be awesome as well.

If you made it this far Thank you just for reading this! Once again all help welcomed and will be greatly appreciated!!

Full Code :

-- Set up table to return to any script that requires this module script
    local PlayerInfo = {}
    
	--new variable for the data store in the same ModuleScript and call GetDataStore() to open a new PlayerData data store
    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 PlayerInfo:ChangeStat(player, statName, value)
    	local playerUserId = "Player_" .. player.UserId
    	assert(typeof(sessionData[playerUserId][statName]) == typeof(value), "ChangeStat error: types do not match")
    	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 success, data = pcall(function()
			return playerData:GetAsync(playerUserId) --GetASync() checks if holding any data
		end)

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

	-- Function to Save player Data
	local function savePlayerData(playerUserId)
		if sessionData[playerUserId] then
			local tries = 0
			local success
			repeat
				tries = tries + 1
				success = pcall(function()
					playerData:SetAsync(playerUserId, sessionData[playerUserId])
				end)
			until tries == 3 or success
			if not success then 
				warn("Cannot save data for the 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 save player's data
    local function savePlayerData(playerUserId)
    	if sessionData[playerUserId] then
    		playerData:SetAsync(playerUserId, sessionData[playerUserId])
    	end
    end
     
    -- Function to save player data on exit
    local function saveOnExit(player)
    	local playerUserId = "Player_" .. player.UserId
    	savePlayerData(playerUserId)
    end
    
	-- Function to Autosave every X(AUTOSAVE_INTERVAL variable defined above) mins
	local function autoSave()
		while wait(AUTOSAVE_INTERVAL) do 
			for playerUserId, data in pairs (sessionData) do
				savePlayerData(playerUserId)
			end
		end
	end
	
	-- Once player is spawned starts running "autoSave()" function
	spawn(autoSave)
	
    -- Connect "setupPlayerData()" function to "PlayerAdded" event (PlayerAdded when Human Joins Server)
    game.Players.PlayerAdded:Connect(setupPlayerData)
     
    -- Connect "saveOnExit()" function to "PlayerRemoving" event (PLayerRemoving is when a Human is leaving the Server)
    game.Players.PlayerRemoving:Connect(saveOnExit)

    return PlayerInfo

3 comments

0

Yeah this is too much information. Attention spans only get shorter and shorter, there is no way anyone will read that wall of text.

1

Basically I just want to know how to call first function to read/update the value there in a different script outside the current service