Answered by
2 years ago Edited 2 years ago
Solution
This is where RequestBudget
comes in. If there isn't enough RequestBudget
, it will show that warning. To fix that, you will need to wait until there is enough budget.
1 | local function waitForRequestBudget(requestType: Enum.DataStoreRequestType) |
2 | local currentBudget = DataStoreService:GetRequestBudgetForRequestType(requestType) |
3 | while currentBudget < 1 do |
4 | currentBudget = DataStoreService:GetRequestBudgetForRequestType(requestType) |
Now you can use that function in GetAsync()
and SetAsync()
.
2 | waitForRequestBudget(Enum.DataStoreRequestType.GetAsync) |
3 | local houseData = HouseData:GetAsync(player.UserId) or { } |
6 | waitForRequestBudget(Enum.DataStoreRequestType.SetAsync) |
7 | HouseData:SetAsync(player.UserId, Houses) |
Pcall (Protected Call)
I recommend using a pcall()
when using an asynchronous function since they can error and break the script. pcall()
calls a function and if it errors, it won't affect the script and the error message will just get returned by pcall()
. If it didn't error and it was successful, pcall()
will return everything returned by the called function.
02 | waitForRequestBudget(Enum.DataStoreRequestType.GetAsync) |
04 | local success, houseData = pcall ( function () |
05 | return HouseData:GetAsync(player.UserId) |
08 | local success, houseData = pcall (HouseData.GetAsync, HouseData, player.UserId) |
10 | if success = = true then |
11 | for houseName, houseValue in pairs (HouseData) |
12 | Houses [ houseName ] .Value = houseValue |
15 | print ( "Player " .. Player.Name .. " has no data!" ) |
Retries
If you use SetAsync()
once, there's a chance it might error, not saving the data. What you can do is retry until data is saved.
4 | waitForRequestBudget(Enum.DataStoreRequestType.SetAsync) |
5 | success = pcall (HouseData.SetAsync, HouseData player.UserId, Houses) |
UpdateAsync > SetAsync
UpdateAsync()
is safer to use in multi-server attempts than SetAsync()
, so you should use it except when using an OrderedDataStore
(commonly used in global leaderboards).
4 | waitForRequestBudget(Enum.DataStoreRequestType.UpdateAsync) |
5 | success = pcall (HouseData.UpdateAsync, HouseData, player.UserId, function () |
Final Script
001 | local DataStoreService = game:GetService( "DataStoreService" ) |
002 | local MainData = DataStoreService:GetDataStore( "MainData" ) |
003 | local HouseData = DataStoreService:GetDataStore( "HouseData" ) |
005 | local Players = game:GetService( "Players" ) |
006 | local ReplicatedStorage = game:GetService( "ReplicatedStorage" ) |
007 | local RunService = game:GetService( "RunService" ) |
009 | local function waitForRequestBudget(requestType: Enum.DataStoreRequestType) |
010 | local currentBudget = DataStoreService:GetRequestBudgetForRequestType(requestType) |
011 | while currentBudget < 1 do |
012 | currentBudget = DataStoreService:GetRequestBudgetForRequestType(requestType) |
018 | function loadHouseData(player: Player?) |
019 | local Plot = Instance.new( "StringValue" ) |
024 | local Houses = Instance.new( "Folder" ) |
025 | Houses.Name = "Houses" |
026 | Houses.Parent = player |
028 | for i, house in pairs (ReplicatedStorage.Houses:GetChildren()) do |
029 | local newValue = Instance.new( "BoolValue" ) |
030 | newValue.Name = house.Name |
031 | newValue.Value = false |
032 | newValue.Parent = Houses |
035 | waitForRequestBudget(Enum.DataStoreRequestType.GetAsync) |
036 | local success, houseData |
039 | waitForRequestBudget(Enum.DataStoreRequestType.GetAsync) |
040 | success, houseData = pcall (HouseData.GetAsync, HouseData, player.UserId) |
042 | until (success and houseData) or retries > = 5 |
045 | for houseName, houseValue in pairs (houseData) do |
046 | Houses [ houseName ] .Value = houseValue |
049 | print ( "Player " .. Player.Name .. " has no data!" ) |
055 | function saveHouseData(player: Player, dontWait: boolean?) |
056 | if workspace:FindFirstChild(player.Name.. "'sHouse" ) then |
057 | workspace:FindFirstChild(player.Name.. "'sHouse" ):Destroy() |
060 | local PlayerPlot = player.Plot |
061 | workspace:FindFirstChild(PlayerPlot.Value).CurrentOwner.Value = "" |
062 | player.Plot.Value = "" |
066 | for i, value in pairs (player.Houses:GetChildren()) do |
067 | Houses [ value.Name ] = value.Value |
073 | waitForRequestBudget(Enum.DataStoreRequestType.UpdateAsync) |
075 | success = pcall (HouseData.UpdateAsync, HouseData, player.UserId, function () |
081 | for _, player in ipairs (Players:GetPlayers()) do |
082 | coroutine.wrap(loadHouseData)(player) |
085 | Players.PlayerAdded:Connect(loadHouseData) |
086 | Players.PlayerRemoving:Connect(saveHouseData) |
088 | game:BindToClose( function () |
089 | if RunService:IsStudio() then |
092 | local finished = Instance.new( "BindableEvent" ) |
093 | local allPlayers = Players:GetPlayers() |
094 | local leftPlayers = #allPlayers |
096 | for _, player in ipairs (allPlayers) do |
097 | coroutine.wrap( function () |
098 | saveHouseData(player, true ) |
100 | if leftPlayers = = 0 then |
106 | finished.Event:Wait() |
Source