How should I be using BindToClose()?

And I don’t see the problem with saving data twice?

It can give you a warning about data stores being over-loaded;

1 Like

When there’s only 1 player in a server? I rememebr that a maximum call of data stores is only 60 if only 1 player is in the server.

1 Like

Another thing I notice is, even though you have IsStudio on, it still will save the data twice if a player is in the game. When that last player left, the PlayerRemoving event and the BindToClose() will still be fired at the same time.

Yeah but multiple warnings all the time about data stores are annoying in studio.

To actually answer the question, I would just save the data and not kick the player. This method is also the only way to go about it if you’re trying to do a soft shutdown.

Which call? Because you’re checking if the environment is not in studio when you’re in a game server, so that conditional statement passes and the BindToClose event is connected.

This code example will prevent the data from being saved twice if there is only one player left in the server:

local RunService = game:GetService("RunService")

if not RunService:IsStudio() then
    game:BindToClose(function()
        if #game.Players:GetPlayers <= 1 then return end

        -- your data saving code here
    end)
end

These people above look really dumb, you clearly just asking to see which method is correct or not, you should always have a BindToClose() in your data store.

also this is the best way to save the player’s data on BindToClose().

game:BindToClose(function()
   if not RunService:IsStudio() and #Players:GetPlayers() > 1 then
     for _, player in ipairs(Players:GetPlayers()) do
          coroutine.wrap(yourSaveFunction)(player)
     end
   end
end)

note: BindToClose() is used to save data in studio (but you shouldn’t save data in studio because it can overwrite data) and also to save data when something unexpected happened to the client and yes the player removing event will always fire (if not shutdown) when the player object is destroyed but the point is, if you have data to save that is located in the player object the PlayerRemoving will not save it (if shutdown) but BindToClose() will (if shutdown).

1 Like

Quick question, if you just kicked everyone, and it automaticly starts saving because you kicked them, since its mass kicking, would’t the datastores start stop excepting requests due to so many set requests?

1 Like

Every data store call is individual for each player but global for the server, that’s why you have limited requests per players, 60 + numPlayers * 10 (i think that’s the formula to calculate how many requests)

Data Store Errors and Limits (roblox.com)

I think thats the case for get requsets, unless your saying you have to wait 6 seconds per set reqeust for a key, which then you can do multiple set requests, im not sure

GetAsync doesn’t have a cooldown only SetAsync & UpdateAsync +

Sorry for the late respoese, and yes i know, but i guess my question is how are you supppossed to save data with bind to close if you have a 6 second cool down for setasynces and update asyncs, so how exactly are you suppossed to save all that data because you could only save 3 players data since bindtoclose only allows 30 seconds. Is there a 6 second cool down per datastore key?

The code above uses coroutine to save the player’s data at the same time and its going to save because the cooldown is individual per key requests.

for example: if you call UpdateAsync on the same key 6 times you’ll get a queue limit warning but if you call it one time per key each 6 seconds the data will be saved but you will be using too many budget.

Thankyou! I was understanding the Datastores and limits wrong. This does make more sense, and it is going to make it easier for saving data without worrying, so if i had 2 datastores, i would not have to put a wait between them while saving?

You should only have one data store, but if you want to keep things organized you can use the second argument scope which works like a folder/dictionary

-- something like this
local mainData = {
   PlayerData = {
      player1 = {},
      player2 = {}
     -- etc 
   }
  Bans = {
    userId2 = true,
    userId3 = true
  }
}

Don’t say that. We never once said that you shouldn’t use BindToClose. We have them an answer but they were looking for full code, like you have spoonfed below.

Yes my bad, I was really confused because everyone were asking too many questions for something really simple, he just asked “which one should I use or which one is better”, the answer is really simple, point out which one is better or give a better solution.

1 Like

I ment ordered datastores insted of normaldatastrores,
like this

function BindToCloseDataSaving()
for _, Player in pairs(game:GetService("Players"):GetPlayers()) do
local Success1, _ = pcall(function()
OrderedDataStore1:SetAsync(Key, Data1)
end)
local Success2, _ = pcall(function()
OrderedDataStore1:SetAsync(Key, Data2)
end)
end
game:BindToClose(BindToCloseDataSaving)

try to make this your last comment since this is not our topic

2 Likes