Need help rewriting / fixing datastore script

You’re going to need to manually hardcode the key names into your script. If you reuse the key names from the then-current datastore, the format may have been changed (key removed or added). Then you just do

function loadAll16Keys()
    local oldData = {}

    local oldKeyNames = { "totalTimePlayed", "Credits", ... }
    local oldDataStore = datastoreservice:GetDataStore(oldDataStoreName)
    for _,keyName in pairs(oldKeyNames) do
        local value = oldDataStore:GetAsync(p.UserId..keyName) -- make sure to do error handling here
        oldData[keyName] = value
    end

    return oldData
end
4 Likes

This is really helpful.

Will come back here if I need anymore help. :slight_smile:

Great news, but also bad news:

The datastore now saves a table. However, when opening the DataStore with @Crazyman32’s datastore editor, the table is there, but Credits aren’t. I’m probably doing something wrong here.

local DataStoreService = game:GetService("DataStoreService")
local Currency = DataStoreService:GetDataStore("Currency","global")
local currencyTypes = {}

local saveData = function(player)
	for _, currency in pairs(player.Currency:GetChildren()) do
		
	end
	
	
	
	Currency:SetAsync("CurrencyTypes"..player.UserId, currencyTypes)
end

game.Players.PlayerAdded:Connect(function(player)
wait(6)
saveData(player)
end)

Edit: Nevermind.

I completely forgot to put in “currencyTypes[currency.Name] = currency.Value” on line 7.


Question though, @EchoReaper
How do developers have leaderboards for kills & stuff like that? I haven’t been able to figure that out yet, but it’s probably super simple.

You have to use OrderedDataStores: https://developer.roblox.com/articles/Data-store#ordered-data-stores

1 Like

Thank you!

On another note, I’m having problems with GetAsync() currently. Pretty much the last thing I’m having problems with and then I’ll be good to go. I intend on running both systems for about two weeks or so, notify players about the integration, and then remove the previous old buggy system.

	credits = Currency:GetAsync(("CurrencyTypes"..player.UserId), "Credits")

The datastore is structured like this:

  • CurrencyTypes
    ---- *Credits
    -----*Redshiftium
    I think I’m doing something wrong here.

Something similar has been asked before. You can check out my response on this thread: Using one datastore to save multiple tables?

Read the post I made in this thread: Using one datastore to save multiple tables?

Neither of those options seem efficient enough to me.

I pretty much just need to be able to view the information for both values, Credits & Redshifitium. Perhaps I’m just not understanding the two solutions. :frowning:

Actually, I played around with it a bit more and I finally figured out how to use it.
Didn’t realize “return fldr” meant it was giving me a folder with the table.convertr.

This does exactly what I need it to! :slight_smile:

Would like to thank @EchoReaper, @Nightrains, @Fm_Trick and @AllenTheNomad for assisting me in rewriting my datastore system. If I could, I’d accept all four of you as a solution, but I don’t have that option sadly. :frowning:

1 Like

No problem bro.

1 Like

One more question:

Is this a good way to save data every minute? Or would this cause the datastore to crash like it is currently?
This would also work alongside a function to save data when a player leaves.

while true do
	
	wait(60)
	for _, plr in pairs(game.Players:GetPlayers()) do
		saveData(plr)
	end
	
end

“saveData” doesn’t complete instantly I’m presuming, so you should do a check whether “plr” is still in-game (i.e. is parented under Players) since you obtain the player list at some point in time before the call happens. In other words suppose every call takes 1 second and there are 20 players in-game, the call for the 20th player happens 20 seconds later, and they may have already left the server (and thus had their data saved through the PlayerRemoving handler).

local Players = game:GetService("Players")

while wait(60) do
	for _, plr in pairs(Players:GetPlayers()) do
		if plr.Parent == Players then
			saveData(plr)
		end
	end
end
2 Likes

Does this not work for Studio?

I have BindToClose() and PlayerRemoving() functions, but my data doesn’t save in Studio.
Is there a reason for this?

Also, my while loop is throwing the datastore resource error for some reason.

In my experience, datastores don’t work very well in studio.

From what I know it’s something to do with PlayerAdded and PlayerRemoving.

I have found that they work better in non team create places though. If anyone has a detailed reason why they don’t work let me know.

1 Like

Alright, thanks for letting me know! :slight_smile:

Also, is it a bad idea to migrate everything like settings & the system datastore to the new system, but keep things like Credits on the old system?

Credits is only 1 key, but I suppose it’s a bit inefficient. Not really sure though tbh.

You’d need to look at how many players there are in your game, and probably toning down the autosave time to at least 120 seconds. But I don’t know why you would transfer everything except for credits.

The only reason i can see you doing this is for a ordered data store…?

I just don’t want to accidentally wipe someone’s credit data.

Settings & System are pretty easy to reset - all you’re losing is your field of view settings, or a value determining if you’re banned or not, and your previous data, which I was planning on resetting anyways.

Also, @Nightrains

The table conversion is returning Bools as Object values - what’s causing that?

When you save the data, do you convert the folder into a table with the module?, if the data folder has a BoolValue, when you convert the folder into a table and then this table convert it to a new folder it should give you BoolValue.

1 Like