Simply put I have a script similar to this-->
local maintable = {} local addtable = {"Stuff","MoreStuff"} local metatable = {"MoreMoreStuff","ExtraMoreStuff"} setmetatable(addtable,metatable) table.insert(maintable,1,addtable) local DataStore = game:GetService("DataStoreService"):GetDataStore("FakeDataStore") local http = game:GetService("HttpService") local JSON = http:JSONEncode(maintable) DataStore:SetAsync("JsonSave",JSON)
The whole thing works fine and when I load the JSON again I have everything... except the meta table. I try-->
--Of course not in the same script local DataStore = game:GetService("DataStoreService"):GetDataStore("FakeDataStore") local LoadedMainTable = DataStore:GetAsync("JsonSave") local Decodedtable = http:JSONDecode(LoadedMainTable) local addtable = Decodedtable[1] if addtable then local metatable = getmetatable(addtable) if metatable then print("GotMetaTable") else print("--MetaTable = nil") end end
This script results in this in the output-->
--MetaTable = nil
So my question is: Does JSONEncode/Decode get ride of all meta tables? If not then how would you successfully get a meta table from a decoded JSON format?
Metatables can't be meaningfully serialized (turned into text) because they have functions attached to them. (This is documented)
This is impossible because functions can be closures--they can refer to particular variables ruining in the program, which doesn't make sense to give to someone on another computer.
I would suggest making an extra property recording the "type" of the thing, and looking up the appropriate metatable and then applying it.
Here is an example of the kind of thing I am suggesting:
function setupHouse(data) setmetatable(data, houseMeta) end function setupLine(data) setmetatable(data, lineMeta) end -- `data` is the result of DecodeJSON. -- It attaches the appropriate metatable function receiveData(data) if data.type == "house" then setupHouse(data) elseif data.type == "line" then setupLine(data) elseif ... etc then end end
Then you have to remember that when you serialize to JSON, you have to include the proper .type
property.
You can shorten all of the elseif
s using a dictionary:
local metas = { house = houseMeta, line = lineMeta, dog = dogMeta, -- etc } function receiveData(data) local meta = metas[data.type] if meta then setmetatable(data, meta) end end -- adds the `.type` property to `.data`, which is an object with (maybe) a metatable -- (use :EncodeJSON on the `data` after this) function sendData(data) local meta = getmetatable(data) for kind, m in pairs(metas) do if m == meta then data.type = kind end end end