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