Not sure what’s causing it, or why this is happening. It has something to do with my global leaderboards though. There’s 4 of them.
Here’s the script that runs on StarterPlayer
local player = game.Players.LocalPlayer
local replicatedStorage = game:GetService('ReplicatedStorage')
local functions = replicatedStorage:WaitForChild('Functions')
local uploadWinsBoard = functions:WaitForChild('UploadWinsBoard')
local uploadTagsBoard = functions:WaitForChild('UploadTagsBoard')
local uploadCashBoard = functions:WaitForChild('UploadCashBoard')
local uploadLevelBoard = functions:WaitForChild('UploadLevelBoard')
while true do
uploadWinsBoard:InvokeServer()
uploadTagsBoard:InvokeServer()
uploadCashBoard:InvokeServer()
uploadLevelBoard:InvokeServer()
wait(600)
end
I figured with wait(600) would mean it wouldn’t fire too much, but apparently it does
You may need to give an example of the Script on the server that’s being invoked. Without the actual SetAsync or other Datastore operations, it’s difficult to pinpoint the issue.
I think the issue is that you are trying to use SetAsync with the same key to quickly.
You have to wait 6 seconds between write requests as stated in the article above.
function uploadWinsBoard.OnServerInvoke(player)
if player then
local myData = playerData[player.UserId]
if myData then
local orderedDataWins = dataStoreService:GetOrderedDataStore('OrderedDataWins')
orderedDataWins:SetAsync(player.Name, myData.wins)
end
end
end
function uploadTagsBoard.OnServerInvoke(player)
if player then
local myData = playerData[player.UserId]
if myData then
local orderedDataTags = dataStoreService:GetOrderedDataStore('OrderedDataTags')
orderedDataTags:SetAsync(player.Name, myData.tags)
end
end
end
function uploadCashBoard.OnServerInvoke(player)
if player then
local myData = playerData[player.UserId]
if myData then
local orderedDataCash = dataStoreService:GetOrderedDataStore('OrderedDataCash')
orderedDataCash:SetAsync(player.Name, myData.totalCash)
end
end
end
function uploadLevelBoard.OnServerInvoke(player)
if player then
local myData = playerData[player.UserId]
if myData then
local orderedDataLevel = dataStoreService:GetOrderedDataStore('OrderedDataLevel')
orderedDataLevel:SetAsync(player.Name, myData.level)
end
end
end
And it’s not possible that an exploiter would be firing those functions maliciously? That’d be a very simple explanation.
Either way you probably should not use a remote for this. The Server isn’t getting any new info from the players, you might as well just use a Server Script to loop through all players with a wait() in between each player. The possibility exists otherwise that all player scripts manage to be in sync, which means that even though it’s every 600 seconds, after that period a spam of 4 requests per player is overwhelming the server.
Yea, for saving the players data, but that’s only called upon when joining the game, and set once you leave. The only reason I have reason to believe that this was causing it was because its for leaderboards, and the leaderboards weren’t loading. When I had 2 leaderboards everything worked fine, but now that there’s 4 it doesnt want to work
If you are saving data when someone joins a game, you are technically sending 5 requests. One for the first person who joins the game and then the four that the global leaderboards use. All it would take then is another person to join the game at the same time as the first person or someone to join and leave immediately.
Do you know when this error normally occurs? Is it when a server starts up and a lot of people join at once or does it also happen when people join gradually? Does it happen even when no new players are joining the server?
The datastore set limit is (60 + numPlayers × 10) per minute, so there doesn’t seem to be a reason why it would be hitting the limit with only 4 sets every 10 minutes for global leaderboards. Are you sure your client side script is only running once per client and isn’t in StarterGui or somewhere else where it might be running each respawn?
It seemed to work when I played on my own, but I put sponsors up, so there’s been a constant 10-20 players on, and joining pretty quickly. But I wouldn’t think having 10 players would cause a problem when there a games with more leaderboards and 1000x more players
It seems like you do everything in a way that should work. Do you know if this might instead be caused by GetAsync or GetSortedAsync requests for the leaderboards? How do you do that?
The limits on GetSortedAsync (5 + numPlayers × 2 per minute) could explain why you had no issue with two leaderboards and also why there is no key listed in the error messages.
local dataStoreService = game:GetService('DataStoreService')
local orderedDataWins = dataStoreService:GetOrderedDataStore('OrderedDataWins')
local orderedDataTags = dataStoreService:GetOrderedDataStore('OrderedDataTags')
local orderedDataCash = dataStoreService:GetOrderedDataStore('OrderedDataCash')
local orderedDataLevel = dataStoreService:GetOrderedDataStore('OrderedDataLevel')
local replicatedStorage = game:GetService('ReplicatedStorage')
local events = replicatedStorage:WaitForChild('Events')
local updateWinsBoard = events:WaitForChild('UpdateWinsBoard')
local updateTagsBoard = events:WaitForChild('UpdateTagsBoard')
local updateCashBoard = events:WaitForChild('UpdateCashBoard')
local updateLevelBoard = events:WaitForChild('UpdateLevelBoard')
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
local pagesWins = orderedDataWins:GetSortedAsync(false, 100)
local dataWins = pagesWins:GetCurrentPage()
updateWinsBoard:FireClient(player, dataWins)
local pagesTags = orderedDataTags:GetSortedAsync(false, 100)
local dataTags = pagesTags:GetCurrentPage()
updateTagsBoard:FireClient(player, dataTags)
local pagesCash = orderedDataCash:GetSortedAsync(false, 100)
local dataCash = pagesCash:GetCurrentPage()
updateCashBoard:FireClient(player, dataCash)
local pagesLevel = orderedDataLevel:GetSortedAsync(false, 100)
local dataLevel = pagesLevel:GetCurrentPage()
updateLevelBoard:FireClient(player, dataLevel)
end)
end)
I think it might be because of the CharacterAdded? but I need that because when you reset the leaderboards disappear
Yeah, this looks like your problem. 4 GetSortedAsync requests for each character spawn will blow through your budget pretty quickly. I would recommend fixing this by having a function that caches each GetSortedAsync request for a minute. You simply save the result of requests in a table and if someone else needs it within a minute give them the data from the table.
e.g
local getFirstPageCache = {}
function isFresh(time)
return tick() - time < 60
end
function getFirstPage(orderedDataStore)
if getFirstPageCache[orderedDataStore] and isFresh(getFirstPageCache[orderedDataStore].Updated) then
return getFirstPageCache[orderedDataStore].Page
end
local pages = orderedDataStore:GetSortedAsync(false, 100)
local firstPage = pages:GetCurrentPage()
getFirstPageCache[orderedDataStore] = {
Updated = tick(),
Page = firstPage,
}
return firstPage
end
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
local dataWins = getFirstPage(orderedDataWins)
updateWinsBoard:FireClient(player, dataWins)
ect.
Another way of doing this would be by using one loop that gets the data every minute and updated a variable. This way you would never need to wait for data in the CharacterAdded function, you could always just send the data from the last request.
Ain’t working it works when the player joins, but when they reset the boards just go back to blank. SHould I add a print somewhere that prints a certain value to see what could be going wrong?
I seemed to have fixed it. I added a repeat wait() until player.Character after the CharacterAdded function, as I’ve had problems before where CharacterAdded fires before the character is added (seems to be a bug on Roblox’s end?) But yea, seems to be fixed now