I can’t give you the code to do this, as it won’t be good for you to put direct code into your game without learning it. But I can tell you how you could do it in one way, what you can do is Run a loop through the stuff you want to save, Insert the key & value to a table, and then after the Loop has ended you just need to Set that value to the datastore and its saved.
Then when you need to do load it you can do a loop again, to create new value instances and give the correct value.
Creating, saving and loading DataStores is pretty easy. Let me give you a small example:
local DSS = game:GetService("DataStoreService") -- we get the DSS
local MoneyStore = DSS:GetDataStore("MoneyData") -- here, we get a "Store". You can call it however you prefer, I called it "MoneyStore" so I'll remember it stores the player's money data. In the brackets, you can find the key we gave for that specific data: in this case, it's "MoneyData".
game:GetService("Players").PlayerAdded:Connect(function(plr) -- this fires when a new player joins the server, which is flagged as "plr"
local leaderstats = Instance.new("Folder") -- this is the leaderstats folder
leaderstats.Name = "leaderstats"
leaderstats.Parent = plr -- we set the leaderstats to the player
local moneyVal = Instance.new("IntValue") -- we create a new IntValue here
moneyVal.Name = "Money" -- we set the name of the value we made. You'll need to remember the name and path of this IntValue
moneyVal.Parent = leaderstats -- we set the parent of the IntValue to the leaderstats folder
moneyVal.Value = MoneyStore:GetAsync(plr.UserId) or 0 -- this might look confusing, but let me explain: firstly, we GET (GetAsync) the data from the player's UserId (plr.UserId). I don't recommend using plr.Name as if the player changes name, they will lose their data. Then, we are basically telling that if the store doesn't find any data for that player, then the data will be set to 0 (or 0)
Now that we’ve made the part where the player’s data is loaded or created, then we can make the part where the player’s data is saved. We have two options here:
Set the new data everytime the value changes (Not recommended, as if the value is changed consistently, then you’ll get an error). This should go under the PlayerAdded event:
MoneyStore:SetAsync(plr.UserId, newVal) -- we set the new data saved on the player's UserId as the key, and the Money as the value. Here we don't need to write down the path of the IntValue as the value is still defined under the PlayerAdded event.
Or (best option) is to save the data when the player leaves:
MoneyStore:SetAsync(plr.UserId, plr.leaderstats.Money.Value) -- same thing as the first method, except this time we need to write down the path of the value, as it's not defined under this PlayerRemoving event
I know about the DSS limits, that’s why I did put the reason he shouldn’t use the first method under (). About your methods, yes I should’ve mentioned the BindToClose. Saving every X minute isn’t necessary and it just adds additional code. I didn’t wanna go in depth tho as it looks like this is the first time he uses DataStores. You shouldn’t say “No, this are the best options” as everyone has their ways. I personally rather use DataStore2 than Roblox’ DSS, that’s why i’m a little rusty. Thanks anyways for adding those methods I didn’t mention.