game.Players.PlayerRemoving:Connect(function(plr)
print(spbh.Value, plr)
if plr == player -- only saves one specific player in the server. ignores others
and spbh.Value ~= "" then
local data = mok_rok[spbh.Value].bonche.playerhasit.savecode.Value
print(data)
if data ~= 0 then
print("past the conditionals")
local s,_ = pcall(function()
print("inside the pcall") -- the script stops here
itemsave:SetAsync("spbh", data)
print("datasave done")
end)
end
print("outside the pcall")
end
end)
print("plrremoving reached")
I made a script that saves data when a specific player leaves the game. I tried both kind of studio tests and also tried it In-game after publishing it. All the other lines of the script functioned properly except the part I wrote above(failed in all 3 tests). So, I added print all over it to find out what went wrong, and tested again.
the output was like this:
plrremoving reached
1 nofair2002
1
past the conditionals
inside the pcall
and nothing appeared after that. It was obvious that the script stopped there. But I couldnât figure out why.
I tried removing the pcall, nothing changed. No errors.
I erased the part that called game:BindToClose()(not written here), nothing changed.
PlayerRemoving is only called here once. No other scripts call it.
PlayerRemoving is not inside a function
studio API and Http requests are both on.
I tried placing the itemsave:SetAsync part outside the PlayerRemoving function. It worked. But when I place it back in, it doesnât work again.
This is why you actually need to use pcall for what itâs for, which is an error handler. Calling things in protected mode isnât enough when it comes to DataStore code; if youâre experiencing unexpected behaviour, then you need to use the return values to debug.
local success, result = pcall(function ()
return itemsave:SetAsync("spbh", data)
end)
if not success then
warn(result)
end
Prints along the way arenât enough to debug, printing actual values (which you do already do except for the returns of the pcall) will further help you debug as will pcall itself since it returns both a success value and error information or the values you explicitly return if the function successfully runs.
Itâs clear that the pcall is still running but stopping at SetAsync, so there must be some kind of exception being thrown. You arenât receiving an error because pcall is catching it.
Thanks for your help!
But even if I remove pcall to check what itâs catching, no errors are thrown at all.
The script wonât print anything after that line, even itâs outside pcall.
print(âouside the pcallâ)
didnât print anything. The script just stops there and does nothing afterwards.
I tried it, it didnât work.
The problem appears when I try to save at PlayerRemoving. the datastore itself causes no problem. I think the player is being disconnected before the script finishes its job.
This might help you. Its what I use to save data, may need tweaking a bit to work with your game. This will save values inside of a leaderstats folder within the player.
game.Players.PlayerRemoving:connect(function(player)
local datastore = game:GetService("DataStoreService"):GetDataStore(player.Name.."Stats")
local statstorage = player:FindFirstChild("leaderstats"):GetChildren()
for i = 1, #statstorage do
datastore:SetAsync(statstorage[i].Name, statstorage[i].Value)
print("saved data number "..i)
end
print("Stats successfully saved")
end)
And that would matter because? Youâre running in Studio and the game is shutting down?
You may want to use game:BindToClose() with player kicks to ensure DataStore writes on shutdown.
I know in your original post you said you tried in studio and in published,
but have you tried all changes/tests in all as well?
I assume you have âEnable Studio Access to API Servicesâ checked in your Game Configuration, as @Snoopy1333 suggests (I mention it for completeness and for others.)
To add to what @446576656C6F706572 suggests, are you checking for errors on the other earlier
DataStore accesses in your code? There may be some hints there.
Have you tried writing âblahâ for instance instead of data as a test?
Finally, as a test, have you tried changing the store you are using? (Maybe there is corruption.)
Little note about your suggestion here: if you are trying to coerce UserId into a string by concatenating it to a blank string (you can just use tostring here), that wouldnât be necessary. Anything related to a DataStore - name, scope, key and value - are coerced into string formats internally before being passed to DynamoDB. In the case of value, if a non-string format is passed, then the value will be coerced into a string format - for example, for tables, through JSON encoding.
Hi, I think the OP know this, and yes to coerce, but I mainly did the concat that way to intentionally not
use tostring() as it will turn nil into ânilâ, to demonstrate for testing purposes, it fails immediately
on concat with a nil
You donât even need any demonstration nor testing purposes here. UserId is guaranteed to be non-nil and the default value is 0. If itâs anything other than an integer, youâve ran into an edge case and should file a bug report with appropriate information.
This was mainly directed to you, but it can also be used for information should anyone else want to adopt this. Iâm also confused on why you used string coercion on scope when that neither has any bearing on the problem listed in the thread nor differentiates what happens with GetDataStore, it just looks messier from a readability standpoint.
Sorry Im late.
Yes. I tried everything that I could think of.
I invited my friends to the game and checked the console when they left.
I removed the other earlier datastore accesses to check if it works without them.
Changing the name of the variable didnât make any change.
I even put 1 instead of data:
itemsave:SetAsync("spbh", 1)
to check if there was any problem in calling the value of the variable
And finally, I have been changing the store like tem2, tem3 etc every time I wanted to reset data. I tried it once again, but it still doesnât work.
Try autosaving maybe? By this point clearly many experienced people have weighed in and no one really knows whatâs going on. This could qualify for a bug report.
I would encourage you to keep tryingâHave you tried making a new minimal rbxl?
Thereâs a funny old thing about âreal programmersâ and part of it goes:
'âReal Programmersâ programs never work right the first time. But if you throw them on the machine they can be patched into working in âonly a fewâ 30-hour debugging sessions. ââ
Often when this type of thing happens, youâre âbarking up the wrong tree.â
To be clear, I meant keep your use of BindToClose() and within the listener, loop through the players
and kick them.
Iâm still unclear as to how youâre testing; if itâs a leave, shutdown, etc. But I will suggest that first be sure
your game can handle negative UserIds and non-player-real-name-matching character names, then
in Studio, use Test->Start, but prior to Start, select at least 2 Players. (As opposed to using Home->Play)
Then in the game in Studio, have just one of the players leave. And see what happens then.