Hello, I’m having trouble using DataStores to create a system where it uses a command of “!Point [Input]” to give a point to someone and then save them point(s) and when leaving adds that to a DataStore so it loads back up when joined again, I’ve tried a bit but haven’t really got far. I’d be great if someone could help explain how to do or something. This would be amazing, thank you!
If possible, please show any code that you already have. It’s easier for me to correct things for you than it is for me to try and explain everything in text.
You will need these things to have that system work:
- Use the Player.Chatted event to detect when someone chats.
- Change the point values inside leaderstats
- Use the Players.PlayerRemoving event to save to DataStores using the GlobalDataStore:SetAsync()
This is what I currently have, most likely has a lot of errors and all so excuse me for all of them ahah. Pretty sure there’s an easier way to do it but I’m too dumb for that.
local DataStoreService = game:GetService("DataStoreService") local players = game.Players game.Players.PlayerAdded:Connect(function(Player) Player.CharacterAdded:Connect(function(Character) function GetPlayerData(player) local playerData = DataStoreService:GetDataStore("PlayerData") local success, data = pcall(function() playerData:GetAsync(player.UserId) end) if not success then wait(0.5) GetPlayerData(player) else if data then workspace.PointValues[player.Name .. "Points"].Value = data else workspace.PointValues[player.Name .. "Points"].Value = 0 end print(player.Name .. " has " .. workspace.PointValues[player.Name .. "Points"].Value) end end players.PlayerAdded:Connect(function(player) local Points = Instance.new("IntValue") Points.Name = player.Name .. "Points" Points.Parent = workspace.PointValues GetPlayerData(player) end) function SavePlayerData(player) local playerData = DataStoreService:GetDataStore("PlayerData") local success = pcall(function() playerData:SetAsync(player.UserId, workspace.PointValues[player.Name] .. "Points") end) if success then workspace.PointValues[player.Name .. "Points"]:Destroy() print("Successfully saved " .. player.Name .. "'s data.") else wait(0.5) SavePlayerData(player) end end Player.Chatted:connect(function(chat) if string.sub(chat,0,string.len("!points")) == "!points" then local point = string.sub(chat,8) if tostring(point) then print(player.Name .. " has gained point(s), saving data") workspace.PointValues[player.Name .. "Points"].Value = (point) SavePlayerData(player) end players.PlayerRemoving:Connect(function(player) print(player.Name .. " has left the server, saving data") workspace.PointValues[player.Name .. "Points"].Value = (point) SavePlayerData(player) end) end
Please indent properly and use whitespace in your code. I indented it myself, and it was clear that there are a lot of problems.
For one, the amount of ends.
point variable contains the sub string from the start of
chat to its eighth character. If
chat was equal to “!points 28”, then
point would be equal to "!points ". So, you’d be setting the player’s PointValue to a string. Since those are of the class
IntValue, this is not possible. You’re also performing
tostring on something you know is a string. This is redundant. You were probably looking for
tonumber to make sure that the point value inputted was a valid number. Also, I would not reccomend using this for a game as this is a very insecure system as anyone can change their data.
SavePlayerData function. When it sets async, it tries to index
workspace.PointValues with the player’s name and then concatenate that (which will be an object) with a string. What you were probably trying to do is to try to index
workspace.PointValues with the string resulting from concatenating the player’s name from a string. Although, even if you got this object correctly, you can’t save objects to DataStores. So, you’d have to grab the value from that object. The correct code would be:
playerData:SetAsync(player.UserId, workspace.PointValues[player.Name.. "Points"].Value)
Fourthly, in the callback for the
PlayerRemoving event, you’re attempting to set the value of one of those PointValues to
point. The variable
point will be out of scope in this chunk. The line is redundant in any case.
Fifthly (if that’s the proper word), in the
GetPlayerData function you’re trying to get data from the
pcall function. The second return value of the
pcall will be an error if there is one occuring in the code encased within the
pcall, not the data returned from
GetAsync. To do this, you’d have to declare a variable outside of the
pcall and assign to it in the
pcall the data returned from
Inside the callback of the
CharacterAdded event of each player passed by
PlayerAdded you’re adding connections for events from the service
Players when you could add those connections outside of that chunk. You do not even have to use the
CharacterAdded event in this code. I would also declare the functions (“GetPlayerData”,“SavePlayerData”) outside of the
Wrong one. That one only fires if ChatService’s Chat method is called. The proper function to use would be Player.Chatted or an LCS command module.