Alright, so I have a module script which contains a bunch of methods for storing, changing, and getting player data. There is a table called sessionData which stores players. Attached to each player is a set of identical data(values may be different, but there is the same number of keys and all key names are the same). The problem arises when I try call setAsync in the module script.
sessionData var
local sessionData = {}
This data table is copied to each player if getAsync returns nil(meaning this player doesn't have an existing data set
data = {Coins = 0, Gold = 0, Level = 1, cpCurrent = 0, cpMax = 0, cpPerLvl = 0, cpRecovery = 0, expCurrent = 0, expNeeded = 0, hpMax = 75, hpPerLvl = 0.15}
After creating a data set for new players, it sets the data to an index in sessionData which can be referenced by the player
sessionData[player] = data
Tries to call this method but returns an error, both after setting a new data set and for saving data which are the two times in the module script that setAsync() is called
playerData:SetAsync(player.UserId, sessionData[player])
Note: These methods are called in another script using PlayerAdded and PlayerRemoving and the player object passed from both these events is passed on to the function via parameter.
This is the error
13:00:10.748 - Argument 2 missing or nil 13:00:10.751 - Script 'ServerStorage.PlayerStatManager', Line 27 - method savePlayerData 13:00:10.753 - Script 'Workspace.setup', Line 8 13:00:10.755 - Stack End
PlayerAdded and PlayerRemoving regular script located in workspace
local module = require(game.ServerStorage.PlayerStatManager) game.Players.PlayerAdded:connect(function(player) module:setupPlayerData(player) --SetAsync() in this method returns error end) game.Players.PlayerRemoving:connect(function(player) module:savePlayerData(player) --SetAsync() in this method returns an error end)
I have completely redone this question. If you have any problems or errors, contact me ASAP. I hope you thumbs up this post as I have put a lot of work on it.
I am using JSON as a string / table saver. In my head JSON is a much better way of data saving. http://wiki.roblox.com/index.php?title=JSON http://wiki.roblox.com/index.php?title=API:Class/HttpService/JSONEncode http://wiki.roblox.com/index.php?title=API:Class/HttpService/JSONDecode http://wiki.roblox.com/index.php?title=API:Class/HttpService
Your server script..
local mod = require(game.ServerStorage.PlayerStatManager) local players = game:GetService("Players") players.PlayerAdded:connect(function(Player) local _DS_Result = mod:getPlayerData(Player, "Datastore") if _DS_Result ~= nil then mod:UpdateSessionData(Player, "Data", _DS_Result) else local Result = mod:setupPlayerData(Player) if type(Result) ~= "table" then error("Result ~= table") end end end) players.PlayerRemoving:connect(function(Player) mod:savePlayerData(Player) end)
And now, for the longggggg module for any type of data :)
local sessionData ={} local playerData =game:GetService("DataStoreService"):GetDataStore("playerData") local Http =game:GetService("HttpService") local JSONEncode =function(...) return(Http:JSONEncode(...)) end local JSONDecode =function(...) return(Http:JSONDecode(...)) end local GetInfo =function(plr, data) for _,v in next,sessionData do if v.User:lower() == plr.Name:lower() then return(v[data]) end end return(nil) end local SetInfo =function(plr, data_name, set_data) for _,v in next,sessionData do if v.User:lower() == plr.Name:lower() then if GetInfo(plr, data_name) then v[data_name] = set_data return v[data_name] else return"Unable to get data" end end end return(nil) end local NewUserData ={ Coins = 0, Gold = 0, Level = 1, cpCurrent = 0, cpMax = 0, cpPerLvl = 0, cpRecovery = 0, expCurrent = 0, expNeeded = 0, hpMax = 75, hpPerLvl = 0.15 } function sessionData:UpdateSessionData(Player, Data_Name, Data) -- Update the sessionData table, mid-game if you need local Result = SetInfo(Player, Data_Name, Data) if Result == nil then warn("Somethings not right here!") else print("Updated sessionData for "..Player.Name) end end function sessionData:setupPlayerData(Player) -- For a player that has just joined, never before table.insert(sessionData, {User=Player.Name; Data=nil;}) -- Insert new data SetInfo(Player, "Data", NewUserData) local JSON =JSONEncode( GetInfo(Player, "Data") ) -- Convert a table to a string playerData:SetAsync(Player.UserId, JSON) -- Set the table as a string return JSONDecode( playerData:GetAsync(Player.UserId) ) -- When we return it to check, its now a table! end function sessionData:savePlayerData(Player) -- For a player thats leaving the server local JSON =JSONEncode( GetInfo(Player, "Data") ) -- Convert to a string, gets the sessionData's table playerData:SetAsync(Player, JSON) return JSONDecode( playerData:GetAsync(Player.UserId) ) end function sessionData:getPlayerData(Player, String) if String == "Datastore" then return JSONDecode( playerData:GetAsync(Player.UserId) ) -- Returns a table elseif String:lower() == "SessionData" then return GetInfo(Player, "Data") -- Also returns a table ;) else warn("To call getPlayerData you need for #arg2 either, \"Datastore\" or \"SessionData\"!") return(nil) end end return sessionData