I am trying to make a script which saves the instances in the workspace after you leave. And the way I am doing this is:
Game runs. Game gets the data of the game from the datastore, a JSON encoded array. Data get JSON decoded into an array. Data (the array ) then gets deserialized by my own deserializer. For every new child added or removed the workspace array gets the elements of the workspace and their properties and adds them in the array, currently it only gets 5 properties and can only save parts which contain these properties, does not save the baseplate, camera, the terrain or my character. Basically here the serialization process occurs. Game shuts down. The workspace array gets JSON encoded. The workspace array gets saved in the datastore.
OK so the array should look like this:
local Workspace = { { Position = {X,Y,Z}; Size= {x,y,z}, Name= {String}; ClassName = {String}; Anchored = {Boolean} } }
And what my deserializer does is that it loops through every dictionary inside the workspace array and it looks for an index called ClassName, it creates a new instance based off the class name and after that its properties get assigned based on the other indexes. That is the function of the decoder. Code:
function DecodeDictionary(dic) local inst = nil for i, v in pairs(dic) do for a, b in pairs(v) do if a == "ClassName" then inst = Instance.new(b[1]) end end for a, b in pairs(v) do if a == "Size" then inst.Size = Vector3.new(b[1], b[2], b[3]) elseif a == "Position" then inst.Position = Vector3.new(b[1],b[2],b[3]) elseif a == "Name" then inst.Name = b[1] elseif a == "Anchored" then inst.Anchored = b[1] end end end inst.Parent = workspace end
And now about my serializer, my serializer runs every time a workspace element gets added or removed. Every time it runs it doesn't save the baseplate camera or terrain, it doesn't save my character either. Code:
local Workspace = {} local function updateDictionary() for i, v in pairs(workspace:GetChildren()) do if v.Name ~= "Camera" and v.Name ~= "Terrain" and v.Name ~= "Baseplate" and v.Name ~= "vamik64" then print(v.Name) local a = {} a.Position = {v.Position.X, v.Position.Y, v.Position.Z} a.Size = {v.Size.X, v.Size.Y, v.Size.Z} a.Name = {v.Name} a.Anchored = {v.Anchored} a.ClassName = {v.ClassName} table.insert(Workspace, a) else print("can't save: ".. v.Name) end end for i, v in pairs(Workspace) do print(v) for a, b in pairs(v) do print(a,b) for x,d in pairs(b) do print(x,d) end end end dataTOsave = HttpService:JSONEncode(Workspace) end
The problem is that when the game shuts down, every element in the workspace gets removed except camera, terrain and baseplate. The workspace array turns into an empty array and the empty array gets saved in my datastore.
Full code:
local DSS = game:GetService("DataStoreService") local HttpService = game:GetService("HttpService") local serverDSS = DSS:GetDataStore("serverDSS") local Players = game:GetService("Players") local Workspace = {} local function updateDictionary() for i, v in pairs(workspace:GetChildren()) do if v.Name ~= "Camera" and v.Name ~= "Terrain" and v.Name ~= "Baseplate" and v.Name ~= "vamik64" then print(v.Name) local a = {} a.Position = {v.Position.X, v.Position.Y, v.Position.Z} a.Size = {v.Size.X, v.Size.Y, v.Size.Z} a.Name = {v.Name} a.Anchored = {v.Anchored} a.ClassName = {v.ClassName} table.insert(Workspace, a) else print("can't save: ".. v.Name) end end for i, v in pairs(Workspace) do print(v) for a, b in pairs(v) do print(a,b) for x,d in pairs(b) do print(x,d) end end end dataTOsave = HttpService:JSONEncode(Workspace) end function DecodeDictionary(dic) local inst = nil for i, v in pairs(dic) do for a, b in pairs(v) do print(a, unpack(b)) if a == "ClassName" then inst = Instance.new(b[1]) end end for a, b in pairs(v) do print(a, unpack(b)) if a == "Size" then inst.Size = Vector3.new(b[1], b[2], b[3]) elseif a == "Position" then inst.Position = Vector3.new(b[1],b[2],b[3]) elseif a == "Name" then inst.Name = b[1] elseif a == "Anchored" then inst.Anchored = b[1] end end end inst.Parent = workspace end local JSONdata = serverDSS:GetAsync("server_key") if JSONdata ~= nil and JSONdata ~= "[]" then local data = HttpService:JSONDecode(JSONdata) DecodeDictionary(data) end workspace.ChildAdded:Connect(function() updateDictionary() end) workspace.ChildRemoved:Connect(function() updateDictionary() end) game:BindToClose(function() print(dataTOsave) serverDSS:SetAsync("server_key", dataTOsave) end)
The code is not well-written as I am making a game serializer and deserializer. These are the early stages of development.
P.S: I am aware that if there are 2 servers running at the same time this won't work properly