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.
Secondly, the 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.
Thirdly, the 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 GetAsync
.
Reccomendations
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 PlayerAdded
chunk.
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.