Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How could I limit my datastore rate?

So just found out saving every stat under a seperate key is a major issue because it will begin building up in the requests.

So my question is how can I jam-pack all of my separate keys into one key?

For example, save all of my leaderstats under one key in a table maybe?

5 comments

0

yes, use a table.

0

i normally only save on player leaving

0

can I have some type of an example on how to do this?

0

Send less requests

0

you'd never want to limit the datastore rate, you'd always want to request less.

2 answers

I annotated the script to better explain whats going on. This is the way I do it. If you have any questions let me know.

local PlayerSavedStuff = game:GetService('DataStoreService'):GetDataStore("PlayerSaveSystem")
local RunService = game:GetService("RunService")
local db = 3

function SaveTableFunc(player)--using function just makes getting table data easier
    local SaveTable = { --our datastore table
        Thing1 = player.PlayerSave.thing1.Value, -- Datastore name = reference to value
        Thing2 = player.PlayerSave.thing2.Value,
    }
    return SaveTable
end

game.Players.PlayerAdded:connect(function(player) -- left deprecated connect on purpose :D
    repeat wait() until player.Character
    repeat wait() until script:FindFirstChild("PlayerSave") -- we wait until playersave is found
    local save1 = script.PlayerSave:Clone() -- I use a folder in this case named PlayerSave, and then insert the corresponding bool/int/strings into it
    save1.Parent = player -- we basically just copy the folder into every player
    local PS = player.PlayerSave
    local save = SaveTableFunc(player) -- reference to our Datastore table function
    local playerkey = "player-"..player.userId
    local SaveFiles = PlayerSavedStuff:GetAsync(playerkey) -- reference to our datastore
    function dataInput(player, save) -- this is where we determine what values go where when player joins. its almost the opposite of whats in the "SaveTableFunc"
          PS.thing1.Value = SaveFiles.Thing1 -- reference to value = datastore name from table
          PS.thing2.Value = SaveFiles.Thing2
          print("Got saved data for "..player.Name)
    end
    local Passed, Error = pcall(function() -- pcall for error checking
            if SaveFiles == nil then
                print(player.Name.." has no save data yet") -- if no data nothing to load
            else
        dataInput(player, save) -- if data load
            end
    end)
    if Error then
        print("***ERROR GETTING SAVE FILE FOR "..player.Name) -- we try 5 times to get data, before giving up.
        local attempts = 0
        while wait(db) do
            local retries = attempts + 1
            attempts = retries
            local pass,err = pcall(function()
            if SaveFiles == nil then
                print(player.Name.." has no save data yet")
        else
        dataInput(player, save)
            end
      end)
            if pass or attempts == 5 then break end
        end
    end
end)

function SaveData(player) -- this is where we save players data when called
    local Success,Error = pcall(function() -- more pcall
        local playerkey = "player-"..player.userId
        local save = SaveTableFunc(player)
        PlayerSavedStuff:SetAsync(playerkey,save) -- << that's the saving
        print("Saved data for "..player.Name)
    end)
    if Error then -- more error checks and retrys
        print("***ERROR SAVING DATA FOR "..player.Name)
        local attempts = 0
        while wait (db) do
            local retries = attempts + 1
            attempts = retries
            local pass,fail = pcall(function()
                local playerkey = "player-"..player.userId
                local data = SaveData(player)
                PlayerSavedStuff:SetAsync(playerkey,save) -- << that's the saving
                print("Successfully saved data for "..player.Name)
            end)
            if pass or attempts == 5 then break end
        end
    end
end

game.Players.PlayerRemoving:Connect(SaveData) -- on player exit, we call SaveData, the above function. 

game:BindToClose(function() -- extra precautionary save.. just in case of bad stuff. 
    if RunService:IsStudio() then return end
    local Players = game:GetService("Players")
    for _,player in pairs(Players:GetPlayers()) do
        SaveData(player)
        print("Saved data for "..player.Name.." on shutdown.")
    end
end)

Okay so I made an attempt to use JSON Encode/Decode and have no Idea what I'm doing here. But here's what I tried:

local datatable = {PizzaPoints = "0",TotalDeliv = "0", rbirth = "1"} 
	
	local DataStoreService = game:GetService("DataStoreService") 
	
	local HTTPService = game.HttpService 
	
	local key = DataStoreService:GetDataStore("testkey")
	
	local data = HTTPService:JSONDecode(key)
		
		if data == nil then 
   				pizzap.Value = 0
				life.Value = 0
				deliv.Value = 1
		else
   		 --data exists
			pizzap.Value = data.PizzaPoints
    	 	life.Value = data.rbirth
		 	deliv.Value = data.TotalDeliv
		
		end
			
			local encoded = HTTPService:JSONEncode(data)
			HTTPService:SetAsync(key,encoded) 

I end up getting a "Can't parse JSON" error

3 comments

0

you dont need to use json

0

I thought it may be more efficient I saw it on the wiki

0

efficient? i dont think so. safer? probably.

This discussion is preserved as it was. New answers, comments, and votes are closed.