Saving datastore within PlayerRemoving (while in studio, not ingame)

so i’m wondering if there is a way to successfully save within studio. (when the PlayerRemoving event is fired) .


Issues

1). Saving in PlayerRemoving works perfectly ingame, but fails 75% of the time when im within studio.

2). Saving in BindToClose works perfectly ingame, but doesn’t seem to work every time on studio and it’ll make studio hang for a long time if I yield


EDIT: I’ve found a simple fix, but I really want a better solution…


My Fix

Basically, if studio is detected (using RunService:IsStudio()) then my script will PURPOSELY throttle the request, so it’ll be in queue, this GARUNTEES it to save 100% of the time for some reason, but at what cost?

I understand that the queue size is 30, so i figured saving a couple of times wouldn’t harm it. (I only purposely throttle when studio is detected, not in game)


any suggestions?

1 Like

put the saving method in a pcall. If the save fails, re run the save attempt until it saves (make sure to space out the re attempts so you dont blow your datastore budget, i believe the max saves per minute is 60 + 10 times the number of players, correct me if i am wrong)

My saving function is already wrapped ina pcall, that isn’t the issue.

The current issue is the fact that BindToClose and PlayerRemoving events don’t always work within studio. (atleast not the way I want them too). Everything works perfectly ingame, just not within studio

and my saving function also includes a retry state, so it’ll attempt to save a few times, if it failed initially.

thank you though.

1 Like

Just test in an actual game. Data stores and studio haven’t always been the best mix.

1 Like

i’d rather not, and its saving 100% of the time in studio when I purposely throttle the request.

I was just wondering if there was a better way… but if no one has a solution soon then i’ll probably just stick with purposely throttling (if studio is detected), it seems to work pretty effectively.

1 Like

What does your saving script look like and where are your values? I don’t want to start throwing out solutions without knowing what exactly you’re doing right now because then you may have already tried that or are doing it. For example, I would suggest using UpdateAsync to queue the save request. The function there is repeatedly called until the data successfully saves.

if studio is detected then my PlayerRemoving save function basically just saves multiple times quickly, to force the save into queue.(BindToClose is completely disabled if studio is detected)

I save all my data into String/Number/Bool values placed within a Folder in ServerStorage, (I keep it outside of the player object)

AND I’ve never thought about using UpdateAsync for this, my function already has a retry feature though, is UpdateAsync any different? i’ll definitely be trying it out either way, im just curious.

thank you.

UpdateAsync allows you to save with a non-yielding transform function instead of passing the raw value to be saved. It provides the old value as a parameter to the function which you can then use to transform (or overwrite, similarly to SetAsync) data. The difference is that UpdateAsync’s function will be repeatedly called at certain points in the game until data saves. It should make a difference.

i’ll quickly make the change then, thank you.

To fix the saving twice, I would recommend waiting for 0.1 seconds, and check if the game is shutting down,

local gameShutDown = false
game.Players.PlayerRemoving:Connect(function(plr)
	wait(0.1)
	if not gameShutDown then
		...
	end
end)

game:BindToClose(function()
	gameShutDown = true
	...
end)

This will prevent throttling, and will probably be better.

im sorry if you misunderstood my issue, but i’m throttling it on purpose, its the only way I can save 100% of the time while in studio.

Just some advice for not throttling it, cause in the queue, if a key is throttled, it is temporarily skipped, but still in the queue, it is probably better if you don’t throttle it, this also saves 100% of the times, because BindToClose is actually handling the save, it’s just that BindToClose fires shortly after PlayerRemoving if the last player leaves, so it does save 100% of the times, and it’s probably better to prevent it from throttling

EDIT: I’ve found a different solution, using the autosaving concept.

basically you’ll create a table of ‘saved’ players, to be used in your Autosaving loop.

every time a player is successfully saved, then it’ll do something like

saved[player.Name]=true

this will reset to false in 6 or so seconds, after that they’ll be able to save again.
now when your script sees that the player has already been saved it’ll just skip.
this will allow me to save all players much more dynamically.

now if your script detects that the user is within studio then it can simply lower the autosave time to 7-10 seconds. (meaning you’ll save 1-3 seconds after entering the game on studio)

this has worked 100% of the time so far and I don’t have to purposely throttle. (or even accidently throttle lol.)