I have a datastore that saves a table and when I print the table result when the player loads it prints this: table: 19918444
and it is not a table as far as I can see. Could someone help me with this? If you need the script I will post it. Also the for loop that is supposed to loop through the table doesnt work. Hope you guys can help me. Thanks!
Edit 1. saving part:
game.Players.PlayerRemoving:Connect(function(plr) if plr.CanSave.Value then local specialKey = "User_"..plr.UserId local plrName = plr.Name local plrInfo = game.ServerStorage:FindFirstChild(plrName):WaitForChild("PlayerInfo") if plrInfo.OwnsTycoon.Value then local tycoonName = plrInfo.OwnedTycoon.Value local tycoon = game.Workspace.Tycoons:FindFirstChild(tycoonName) local moneyToSave = plrInfo.Money.Value local buildLevelToSave = plrInfo.BuildLevel.Value local purchasedItemsTable = getTableForDataStore(tycoon, plrInfo) local mainTableToSave = {moneyToSave, buildLevelToSave, purchasedItemsTable} local success, message = pcall(function() mainDataStore:SetAsync(specialKey, mainTableToSave) end) end end end
loading part:
script.Parent.Touched:Connect(function(hit) if script.Parent.CanCollide then if hit.Parent:FindFirstChild("Humanoid") then if hit.Parent.Humanoid.Health > 0 then local plr = game.Players:GetPlayerFromCharacter(hit.Parent) local plrName = plr.Name local plrInfo = game.ServerStorage:FindFirstChild(plrName):WaitForChild("PlayerInfo") local specialKey = "User_"..plr.UserId local tycoon = script.Parent.Parent.Parent.Parent local tycoonName = tycoon.Name local mainDataTable local serverTycoon = game.ServerStorage:FindFirstChild("Model"..tycoon.Color.Value.."Tycoon") if not plrInfo.OwnsTycoon.Value then if not tycoon.IsOwned.Value then tycoon.IsOwned.Value = true tycoon.Owner.Value = plrName plrInfo.OwnedTycoon.Value = tycoon.Name plrInfo.OwnsTycoon.Value = true script.Parent.Transparency = 1 script.Parent.CanCollide = false local success, message = pcall(function() mainDataTable = mainDataStore:GetAsync(specialKey) end) if success then print("Player Data Loaded Successfully") plrInfo.Money.Value = mainDataTable[1] or 0 plrInfo.BuildLevel.Value = mainDataTable[2] or 1 local buildLevel = plrInfo.BuildLevel.Value local baseplate = findBaseplate(buildLevel, serverTycoon) local baseplateName = baseplate.Name local tycoonBaseplate = tycoon:FindFirstChild("Baseplates"):WaitForChild(baseplateName) local serverBaseplate = serverTycoon:WaitForChild(baseplateName) local copy = baseplate.BaseplateEssentials:Clone() copy.Parent = tycoon.Baseplates:FindFirstChild(baseplateName) print(mainDataTable[3])
and the print at the end is what gives the output I set Please help!
To expand on iiiGodRoblox's answer
Arrays
and dictionaries
usually cannot be printed in a human readable format if just printed to console or tostringed.
tostring(table t)
will return some weird string that we know is table: some hexadecimal number
, but that doesn't really give a lot of information about the table, sure it's nice that we can print it but it's not really too useful to use right now.
For us to actually view and inspect an array
or dictionary
, we can either use some that returns the table as a string or __tostring
metamethod.
How To Implement
If you're bored of reading and just want an easy solution, you can use
local function DumpTable(t) local str = {} for Index, Value in pairs(t) do table.insert(str, tostring(Value)) end return "{" .. table.concat(str, ", ") .. "}" end
It's not necessarily the best solution, but it works and it's simple enough to understand at a glance.
If you're curious for more information, you can keep on reading.
There's an obvious problem with the code above, it doesn't support nested tables; let's say we have a table structured as such
{ Hello = "World", Programmed = { "To" "Work" }, And = { Not = "to", Feel = true } }
What our code above might output would be something along the lines of {World, table: 0xBAADF00D, table: 0xFFFFFF}
Yeah, it prints it out but now we're back to our original problem, it's printing table: hex
again.
What we can do is have some kind of recursive implementation that checks the type of Value
and if it's a table
, then dump that table
The code may fall something along the lines like
local function DumpTable(t) local str = {} for Index, Value in pairs(t) do if type(Value) == "table" then table.insert(str, DumpTable(Value)) else table.insert(str, tostring(Value)) end end return "{" .. table.concat(str, ", ") .. "}" end
If we inspect the code, we can see that it'll handle tables inside tables and tables inside those tables correctly.
Self referential tables
This should be enough for most people, but what if you're really eccentric and have something like
local a = {} local b = {a} a[1] = a
Now, at first, this may seem to work, its just tables inside tables but now this presents another problem: self-referential tables
This is what our little function will do
DumpTable(a) -> __index(a, 1) = b -> DumpTable(b) -> __index(b, 1) = a -> DumpTable(a) -> __index(a, 1) = b -> DumpTable(b) ... forever
Now that's a problem, it just keeps on dumping a
and b
! This will go on infinitely and will cause a stack overflow which isn't good for both us and the computer.
What we can do to solve this is keep track of the tables that we already turned into strings, if it hasn't then do whatever we usually do, else just return tostring(t)
local function DumpTable(t, Printed) Printed = Printed or {} if Printed[t] then return tostring(t) --this is where we stop self-referential tables end Printed[t] = true local str = {} for Index, Value in pairs(t) do if type(Value) == "table" then table.insert(str, DumpTable(Value, Printed)) else table.insert(str, tostring(Value)) end end return "{" .. table.concat(str, ", ") .. "}" end
Now, this is what our function will do with the table a
and b
problem:
DumpTable(a, {}) -> __index(a, 1) = b -> DumpTable(b, Printed) ->__index(b, 1) = a -> DumpTable(a, Printed) -> a is in Printed, return tostring(a) -> return "{" .. tostring(a) .. "}" ->return "{{" .. tostring(a) .. "}} DumpTable(a) == "{{" .. tostring(a) .. "}}"
This may seem not that useful but that's just because it isn't necessarily the best example; however, it clearly illustrates that, yes, it can handle self-referential tables while not having a stroke and dying.
Of course, this doesn't solve all our problems, it shows strings as String
rather than "String"
, which isn't optimal and while yes it works with both arrays
and dictionaries
, dictionary
support isn't exactly the best as it doesn't include the index. Using what you learned in this answer, try extending our code to work and solve these little problems.
If you want to use existing code to inspect tables, you can use Kikito's inspect.lua or my own table.FormatValue
Well you could see the content of the table by using a for loop like the following
local tab = {'a','b','c','d',...} for i,v in pairs(tab) do print(i,v) end