So, I’m trying to save currencies to a datastore, and when I leave (in this case stop the game), I get an error.
I’m pretty sure it’s with the userId not existing cause the player left, though I don’t know how to fix it.
This is the current script:
local datastore = game:GetService("DataStoreService")
local playerDS = datastore:GetDataStore("CurrencyDataStore")
local player = game:WaitForChild("Players").LocalPlayer
game:WaitForChild("Players").PlayerAdded:Connect(function(player)
local ls = Instance.new("Folder")
local feathers = Instance.new("NumberValue")
local gems = Instance.new("NumberValue")
local sonicwaves = Instance.new("NumberValue")
ls.Name = "leaderstats"
feathers.Name = "Feathers"
gems.Name = "Gems"
sonicwaves.Name = "SonicWaves"
ls.Parent = player
feathers.Parent = ls
gems.Parent = ls
sonicwaves.Parent = ls
local success, errormsg = pcall(function()
local data = playerDS:GetAsync(player.UserId)
if data[1] ~= nil then
feathers.Value = data[1]
end
if data[2] ~= nil then
gems.Value = data[2]
end
if data[3] ~= nil then
sonicwaves.Value = data[3]
end
end)
end)
game.Players.PlayerRemoving:Connect(function(Lplayer)
if player.userId == Lplayer.UserId then
playerDS:SetAsync(player.UserId, {
player.leaderstats.feathers.Value,
player.leaderstats.gems.Value,
player.leaderstats.sonicwaves.Value
})
end
end)
The error is appearing in the ‘if’ function which checks if the userId is the same as the Id of the left player. I’d really appreciate any help!
Sincerely, Blackstrike.
do game:GetService(“Players”).LocalPlayer instead
1 Like
change userId to UserId
ahhhh yes cool limit
server scripts cannot use LocalPlayer, and by the look of the error, as the script is in ServerScriptService, its a server script.
in that case remove the player variable
How do I make the check work then? Is there any way to implement it?
redid this with sense, u did “userId” not UserId on that line
local playerDS = datastore:GetDataStore("CurrencyDataStore")
local player = game:WaitForChild("Players").LocalPlayer
game:WaitForChild("Players").PlayerAdded:Connect(function(player)
local ls = Instance.new("Folder")
local feathers = Instance.new("NumberValue")
local gems = Instance.new("NumberValue")
local sonicwaves = Instance.new("NumberValue")
ls.Name = "leaderstats"
feathers.Name = "Feathers"
gems.Name = "Gems"
sonicwaves.Name = "SonicWaves"
ls.Parent = player
feathers.Parent = ls
gems.Parent = ls
sonicwaves.Parent = ls
local success, errormsg = pcall(function()
local data = playerDS:GetAsync(player.UserId)
if data[1] ~= nil then
feathers.Value = data[1]
end
if data[2] ~= nil then
gems.Value = data[2]
end
if data[3] ~= nil then
sonicwaves.Value = data[3]
end
end)
end)
game.Players.PlayerRemoving:Connect(function(Lplayer)
if player.UserId == Lplayer.UserId then
playerDS:SetAsync(player.UserId, {
player.leaderstats.feathers.Value,
player.leaderstats.gems.Value,
player.leaderstats.sonicwaves.Value
})
end
end)
you get the player in the function alr
local part = script.Parent
local debounce = {}
local rS = game:GetService("ReplicatedStorage")
local rEvent = game.ReplicatedStorage.Remote.onFailTeleport
part.Touched:Connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
local checkDb = debounce[player.UserId]
if checkDb == nil or checkDb == false then
debounce[player.UserId] = true
rEvent:Fire(game.Players:GetPlayerFromCharacter(hit.Parent))
wait(0.2)
debounce[player.UserId] = false
end
end
end)
so just put the event into the event yeah?
local playerDS = datastore:GetDataStore("CurrencyDataStore")
game:WaitForChild("Players").PlayerAdded:Connect(function(player)
local ls = Instance.new("Folder")
local feathers = Instance.new("NumberValue")
local gems = Instance.new("NumberValue")
local sonicwaves = Instance.new("NumberValue")
ls.Name = "leaderstats"
feathers.Name = "Feathers"
gems.Name = "Gems"
sonicwaves.Name = "SonicWaves"
ls.Parent = player
feathers.Parent = ls
gems.Parent = ls
sonicwaves.Parent = ls
local success, errormsg = pcall(function()
local data = playerDS:GetAsync(player.UserId)
if data[1] ~= nil then
feathers.Value = data[1]
end
if data[2] ~= nil then
gems.Value = data[2]
end
if data[3] ~= nil then
sonicwaves.Value = data[3]
end
end)
end)
game.Players.PlayerRemoving:Connect(function(Lplayer)
if player.UserId == Lplayer.UserId then
playerDS:SetAsync(player.UserId, {
player.leaderstats.feathers.Value,
player.leaderstats.gems.Value,
player.leaderstats.sonicwaves.Value
})
end
end)```
formatting error, add the local datastore = game:GetService(“DataStoreService”)
aswell
player is an unknown variable cause it’s separated, as the “player” only exists in the PlayerJoined
what is the point of this line
Lplayer is the player though -------
To check if the player the datastore wants to save the data is the same at the player who just left, now that I think about it it’s useless.
game.Players.PlayerRemoving:Connect(function(player)
playerDS:SetAsync(player.UserId, {
player.leaderstats.feathers.Value,
player.leaderstats.gems.Value,
player.leaderstats.sonicwaves.Value
})
end)
I’ll try to solution as soon as I get back home. Appreciate your help!
A server script cannot grab a local player, so when you go to save the players data when they’re leaving, it errors, as you are trying to use the local player.
Also, I’d recommend having a bindToClose in the script.
I’ve cleaned up the code a bit, but I would recommend modules such as datastore2 or profileService.
Try this code out.
--Services{
local datastore = game:GetService("DataStoreService")
local playerService = game:GetService("Players")
--}
--Vars{
local playerDS = datastore:GetDataStore("CurrencyDataStore")
--}
--Tables{
local noobie = {
["Feathers"] = 0;
["Gems"] = 0;
["SonicWaves"] = 0
}
--}
local function saveData(player)
local safeSave = player:GetAttribute("SafeSave")
if safeSave then
local myStats = {
["Feathers"] = player.leaderstats.Feathers.Value;
["Gems"] = player.leaderstats.Gems.Value;
["SonicWaves"] = player.leaderstats.SonicWaves.Value;
}
local tries = 0
local maxTries = 4
while tries < maxTries do
local success, errormessage = pcall(function()
playerDS:SetAsync(player.UserId, myStats)
end)
if not success then
tries += 1
task.wait(30)
else
break
end
end
end
end
playerService.PlayerAdded:Connect(function(player)
local ls = Instance.new("Folder")
local feathers = Instance.new("NumberValue")
local gems = Instance.new("NumberValue")
local sonicwaves = Instance.new("NumberValue")
ls.Name = "leaderstats"
feathers.Name = "Feathers"
gems.Name = "Gems"
sonicwaves.Name = "SonicWaves"
ls.Parent = player
feathers.Parent = ls
gems.Parent = ls
sonicwaves.Parent = ls
local data --have the data variable outside the pcall
local success, errormsg = pcall(function()
data = playerDS:GetAsync(player.UserId)
end)
if success then
if not data then
data = table.clone(noobie)
end
feathers.Value = data["Feathers"]
gems.Value = data["Gems"]
sonicwaves.Value = data["SonicWaves"]
player:SetAttribute("SafeSave", true)
else
warn(errormsg)
player:Kick("Data could not be loaded. Please try and rejoin")
end
end)
playerService.PlayerRemoving:Connect(function(player)
saveData(player)
end)
game:BindToClose(function()
for _, v in pairs(playerService:GetPlayers()) do
saveData(v)
end
end)
also also, does datastore work in roblox studio? cause when I try to overwrite the value, then quit and load in again it’s still the original value