I used ready-made code to save the Bool value, modified it to fit my value, but it doesn’t work.
local dss = game:GetService("DataStoreService")
local BlockedDS = dss:GetDataStore("BLOCKED VALUE")
game.Players.PlayerAdded:Connect(function(Player)
local Values = Instance.new("Folder")
Values.Name = "Values"
Values.Parent = Player
local Bool = Instance.new("BoolValue")
Bool.Name = "Blocked"
Bool.Parent = Values
end)
function saveData(Player)
if not Player:FindFirstChild("DATA FAILED TO LOAD") then
local blockedvalue = Player.Values.Blocked.Value
local compiledData = {
BlockedValue = blockedvalue;
}
local success, err = nil, nil
while not success do
success, err = pcall(function()
BlockedDS:SetAsync(Player.UserId, compiledData)
end)
if err then
warn(err)
end
task.wait(0.1)
end
end
end
game.Players.PlayerRemoving:Connect(saveData)
game:BindToClose(function()
for _, plr in pairs(game.Players:GetPlayers()) do
saveData(plr)
end
end)
You don’t need a JSON encode to save it. And, you are not setting the bool value in the load data script!!!
Make sure to set the Bool’s value inside the ‘game.Players.PlayerAdded’ function or else it will not load the player’s data!
Judging by how you’re doing SetAsync every 0.1 seconds, you’re probably making too many requests. You can confirm this if you’re seeing warnings (yellow messages) in the output saying how further requests have been dropped, etc.
You’re only meant to run SetAsync once, regardless of whether it fails or not. If there was a problem with SetAsync and it never saved, that loop would go on forever, causing more lag as more players in the server leave.
Here’s what I think does best to save data:
function saveData(Player)
local blockedvalue = Player.Values.Blocked.Value
local userId = Player.UserId
local compiledData = {
BlockedValue = blockedvalue;
}
local success, err = pcall(function()
BlockedDS:SetAsync(userId, compiledData)
end)
if not success then
warn(err)
end
end
Also you haven’t specified the problem you’re having, so I’m not exactly sure if this is the right problem to solve, but hopefully it helps.
local attempt = 1
repeat
local success, err = pcall(function()
BlockedDS:SetAsync(userId, compiledData)
end)
if not success then
attempt += 1
end
until success or attempt == 'your maximum attempts'
For loading, it’s pretty much the same thing, except with a few new variables:
local attempt = 1
local data
repeat
local success, err = pcall(function()
data = BlockedDS:GetAsync(userId)
end)
if not success then
attempt += 1
end
until success or attempt == 'your maximum attempts'
if success then
print("Successfully loaded data!")
if not data then
print("Give default data!")
end
else
player:Kick("Failed to load your data, please rejoin!")
end
Note: I am showcasing a DataStoring way I use in my games.
Note 2: If it does not fit your needs, adjust it in anyway you’d like.
Note 3: If it every bugs, make sure to enable the Studio Access to API Services in Security in Game Settings
Note 4: If you encounter any bugs with my system, tell me what the bug is, and I will happily fix it!
When I logged in again, the value was not saved, now I noticed an error that the value was not loaded when the player joined. I fixed it, but it doesn’t work.
Slightly modified script.
local dss = game:GetService("DataStoreService")
local BlockedDS = dss:GetDataStore("BLOCKED VALUE")
game.Players.PlayerAdded:Connect(function(Player)
local Values = Instance.new("Folder")
Values.Name = "Values"
Values.Parent = Player
local Bool = Instance.new("BoolValue")
Bool.Name = "Blocked"
Bool.Parent = Values
local success, plrData = nil, nil
while not success do
success, plrData = pcall(function()
return BlockedDS:GetAsync(Player.UserId)
end)
end
if not plrData then
plrData = {Blocked = false}
end
end)
function saveData(Player)
local blockedvalue = Player.Values.Blocked.Value
local userId = Player.UserId
local compiledData = {
BlockedValue = blockedvalue;
}
local success, err = pcall(function()
BlockedDS:SetAsync(userId, compiledData)
end)
if not success then
warn(err)
end
end
game.Players.PlayerRemoving:Connect(saveData)
game:BindToClose(function()
for _, plr in pairs(game.Players:GetPlayers()) do
saveData(plr)
end
end)
I would use the data storing loading/saving methods I showed above, they are really helpful, because in your loading script, you are using a while not success loops, and if they cant load the data, it’ll loop forever causing mass lag on the server, and you wouldn’t want that.
Sorry if I sound like I’m being forceful in using my loading/saving ways.
You aren’t changing the Bool’s value. Also it would be wise to load the data first before making the Instances, so I re-ordered the function.
game.Players.PlayerAdded:Connect(function(Player)
local success, plrData = pcall(function()
return BlockedDS:GetAsync(Player.UserId)
end)
if not plrData then
plrData = {Blocked = false}
end
local Values = Instance.new("Folder")
Values.Name = "Values"
Values.Parent = Player
local Bool = Instance.new("BoolValue")
Bool.Name = "Blocked"
Bool.Value = plrData.Blocked -- added this line
Bool.Parent = Values
end)
I’m just basing it off the author’s code, and I think it’s logical. But I think you’re looking for something more like this
game.Players.PlayerAdded:Connect(function(Player)
local data
local success, err = pcall(function()
data = BlockedDS:GetAsync(Player.UserId)
end)
if success then
if not data then
data = {Blocked = false}
end
else
Player:Kick("Your data failed to load, please try again")
return
end
-- same code here
end)
I was referring to the fact you did not check if any data was stored for the player.
With the code you provided the script would error the first time a player joined, as you would attempt to set a BoolValue’s Value to nil.