Why do DataStores not save Mixed Arrays?

Title says it all. I am a little confused on why dataStores do not save mixed arrays / dictionaries. Could someone explain to me?

local _DATASTORE_SEVER = game:GetService("DataStoreService"):GetDataStore("____SEERRRVVVEEREEEERR_DDDAAAATTTTAAAAAAA_______")

local DAATA = {

	Test = {6,8,9,0, 
		yes99=false}, --MIXED ARRAY

}

local data = _DATASTORE_SEVER:GetAsync("TEST")

if data == nil then
	local Save__DATA, _message = pcall(function()
		_DATASTORE_SEVER:SetAsync("TEST", DAATA)
	end)

	if Save__DATA == true then
		print("Saved ")
	else
		warn(_message)
	end
else
	print(data)
end

Everything above works fine. However, the data that is loaded is altered for some reason. ‘yess99’ is left out when loading data. Which is why I am wondering what could be the issue.

You can resolve this issue by stringing your numeric indices.

How would I go about doing that? Could I possibly get an example

My bad, I didn’t mean stringing, I meant converting the array part into a dictionary part.

local DAATA = {

	Test = {[6] = true,[8] = true,[9] = true,[0] = true, 
		yes99=false}, --MIXED ARRAY

}
1 Like

I assume mixed arrays cause issues in the way in which Roblox internally handles/compresses DataStore data.

1 Like

Is there some kind of documentation stating this information anywhere? I’d like to read into this if possible

The same behavior is present for remote events/functions

Like what @Forummer said, if you still want to use a mixed table, you will have to convert the numerical keys to strings

type dictionary = {[string]: any}
local data: dictionary = {
  ['1'] = something, --string key
  ['2'] = something, --also string key
  real123 = something, --definitely a string key
}
2 Likes

The indices can be numerical (don’t start from 1), just the table must take the form of a dictionary.

--SERVER
local players = game:GetService("Players")
local replicated = game:GetService("ReplicatedStorage")
local remote = replicated.RemoteEvent

players.PlayerAdded:Connect(function(player)
	task.wait(1)
	remote:FireClient(player, {[5] = true, [6] = true, ["a"] = true})
end)
--LOCAL
local replicated = game:GetService("ReplicatedStorage")
local remote = replicated:WaitForChild("RemoteEvent")

remote.OnClientEvent:Connect(function(data)
	for index, value in pairs(data) do
		print(index, value)
	end
end)

Output:
image

When I change the data transmitted to:

remote:FireClient(player, {true, false, ["a"] = true})

The output becomes:
image

As you stated this behavior is also present for RemoteEvents/RemoteFunctions, in addition to this, it is also present for BindableEvents/BindableFunctions, as the following code snippet will exemplify.

local players = game:GetService("Players")
local replicated = game:GetService("ReplicatedStorage")
local bindable = replicated.Event

bindable.Event:Connect(function(data)
	for index, value in pairs(data) do
		print(index, value)
	end
end)

bindable:Fire({true, false, ["a"] = true})

Output:
image

2 Likes