Cannot figure out how to handle datastores

Hi developers!

While making my game, I’ve been having trouble trying to figure out how on Earth to handle new players joining my experience. I’ve looked all over for anyone else who had the same question as me and couldn’t find anything so here I am out of desperation.

Lets say that a new player joins the game. I want the player’s save slots to show up when they join. If I attempt to get this player’s save slots with GetAsync, it will fail. Assuming that this player is new, it will generate a new key for this player, in this case their UserId followed by “_data”. Then, a blank table is saved in this key using SetAsync and no slots are displayed.

My issue comes when I try to wrap my head around how this code will operate in the event that there is an issue with datastores, or an outage at Roblox. If this happens, players could have their save slots deleted because the data stored within their datastore key will be overwritten. I don’t want to continually wait until player data is loaded, because then new players won’t have a table created for them and they won’t be able to save their characters. At the same time, I want to avoid the situation I described above, where existing players have their data erased because of an outage.

I’m losing my mind trying to come up with a solution and wrap my head around what I’m supposed to do here. I don’t want code, I want an explanation.

Thanks in advance.

2 Likes

This is how you’re supposed to do it though. When you first attempt to :GetAsync (which is wrapped in a pcall), check if the call was successful. If it was successful, proceed. Else retry.

Should :GetAsync be successful, check what is returned from the call. If what is returned is nil but the call succeeded, create new blank data since the player is joining for the first time.

Else, load their data.

There really isn’t anything you can do when data stores are having issues other than retry, or kick the player.

2 Likes

Will that pcall return true even if the player is brand new and doesn’t have any data saved?

1 Like

Yes, because pcalls usually return 2+ things:

1- Boolean dictating whether or not the call was successful.
2- If 1 was false, the error message stating why the call failed.
If 1 was true, the second and any subsequent results returned from pcall will be what the enclosed function returns,

So for example, a very artificial example would be this:

local success, result1, return2 = pcall(function()
    assert(math.random(1, 2) == 2, 'Random didn\'t return 2!')
    return 1, 2
end)

if success then
    print('pcall succeeded:', result1, result2) --> 1 2
else
    print('pcall failed because', result1) --> string: pcall failed because Random didn't return 2!
end

So in the case of data stores, a successful call to :GetAsync where the player has no data will return nil as the second argument.

local success, result = pcall(dataStore.GetAsync, dataStore, player.UserId)
if success then
    -- call was successful
    if not result then -- result is falsy (nil or false), unless you're saving an arbitrary boolean, the player has no data
        result = defaultData -- assign their data to be defaultData, this would just be your template data
    end
    -- load their data
else
    print('Can\'t get user data because', result) -- here you'd retry because the call to GetAsync failed likely due to Roblox server issues
end
3 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.