I decided to try out this method to prevent datastore problems with players. Basically it goes like this: I put the section of the script responsible for obtaining the player’s data inside a local function. Then when the player joins, the function inside the player added event will be called to retrieve the data. However just in case it does not work, the function will call itself inside the function, which will make the script try again continuously until it manages to obtain the data. My question is, will this prevent problems in the future or cause more problems?
Script:
local dataStoreService = game:GetService("DataStoreService")
local cars = dataStoreService:GetDataStore("Cars")
local loadGarage = game.ReplicatedStorage.Remotes.LoadGarage
game.Players.PlayerAdded:Connect(function(player)
local boughtCars
local equipped
local function obtainData()
local success, notSuccess = pcall(function()
boughtCars = cars:GetAsync(player.UserId.."-boughtCars")
equipped = cars:GetAsync(player.UserId.."-equippedCar")
end)
if success then
if not boughtCars then
boughtCars = {"GoKart"}
end
if not equipped then
equipped = "GoKart"
end
loadGarage:FireClient(player, boughtCars, equipped)
print("Cars Obtained")
else
warn(notSuccess)
obtainData()
end
end
obtainData()
end)
So, similar to a recursive? Those are usually very powerful and can cause problems. And if the player doesn’t have any saved data to begin with, it’ll still continue. So I personally would not recommend doing this.
Speaking of Data Stores how would one add data to it if colliding with an object? I have two tables in the Data Store, RelicCoins, and Wins. If I collided with a RelicCoin I would want it to add 1 to the RelicCoins counter and 1 to the Wins counter. If player has x number of RelicCoins player can access this level. How would I accomplish these things?
As long as you properly index the Tables upon saving them to the Data Store, you can always recall them using the same Index. And a Touched event should work for the RelicCoins.
This is how I usually work with Tables in a DataStore :
local Stats = {}
local DataStoreService = game:GetService('DataStoreService')
local DataStore = DataStoreService:GetDataStore('DataStoreName')
game.Players.PlayerAdded:Connect(function(player)
local success, fail = pcall(function()
if DataStore:GetAsync(player.UserId) then
table.insert(Stats, player.UserId, {['Coins'] = DataStore:GetAsync(player.UserId).Coins, ['SomeOtherStat'] = DataStore:GetAsync(player.UserId).SomeOtherStat})
end
end)
if not success then
print(fail)
table.insert(Stats, player.UserId, {['Coins'] = 0, ['SomeOtherStat'] = 0})
end
end
Of course that is how I usually do it. But if you like to do it some way else, that is fine. As long as you understand what you are doing.
There’s the possibility that it could clog up the DataStore request, and have it end up timing out, if it isn’t able to retrieve the data. The best idea to prevent Data being lost, in my opinion, is by using DataStore:UpdateAsync() → This way, you can still access past Data.
Or another alternative would be to use Two DataStores to save the same Data. And you would only ever call on the second if the first fails. While saving them both with the same Data.
This is using DataStore:GetAsync(), will using recursive functions cause problems with DataStore requests that ask to retrieve data rather than update it? I am not planning to use this method on updating data, since I am obviously gonna use DataStore:UpdateAsync(). Also the reason I implemented this method was because of a certain DataStore error that happens from time to time which has the word “DnsResolve” in it, but whenever I try loading the data after the DnsResolve error happens, it gets it the second time.