This is a bit of an awkward question, but I’m making an open world building game and I made a serialiser (compressed also with JSON.Encode).
Sometimes, the strings spat out can be more then 1 million characters [even compressed, 52 instances is averaging 12000 characters] sometimes so I don’t know about using Datastore to save the serialised builds.
Should I stick to datastore and compress it more [through some method] or use a third party (and if so what one?)
local HttpService = game:GetService("HttpService")
local serialiser = {}
function serialiser.Serialise(obj)
local function serialiseInstance(instance)
local data = {
ClassName = instance.ClassName,
Name = instance.Name,
Properties = {},
Children = {}
}
local hasPosition = pcall(function() return instance.Position end)
if hasPosition then
local propertiesToSerialize = {"Position", "Rotation", "Material", "Color", "Size", "Reflectance", "Transparency", "CanCollide", "Name"}
for _, propertyName in ipairs(propertiesToSerialize) do
local success, propertyValue = pcall(function() return instance[propertyName] end)
if success then
local propertyData = {}
if typeof(propertyValue) == "BrickColor" then
propertyData.Type = "BrickColor"
propertyData.Value = propertyValue.Name
elseif typeof(propertyValue) == "Vector3" then
propertyData.Type = "Vector3"
propertyData.Value = {propertyValue.X, propertyValue.Y, propertyValue.Z}
elseif typeof(propertyValue) == "Color3" then
propertyData.Type = "Color3"
propertyData.Value = {propertyValue.R, propertyValue.G, propertyValue.B}
elseif typeof(propertyValue) == "Vector2" then
propertyData.Type = "Vector2"
propertyData.Value = {propertyValue.X, propertyValue.Y}
elseif typeof(propertyValue) == "UDim2" then
propertyData.Type = "UDim2"
propertyData.Value = {propertyValue.X.Scale, propertyValue.X.Offset, propertyValue.Y.Scale, propertyValue.Y.Offset}
elseif typeof(propertyValue) == "CFrame" then
propertyData.Type = "CFrame"
propertyData.Value = {propertyValue:components()}
elseif typeof(propertyValue) == "UDim" then
propertyData.Type = "UDim"
propertyData.Value = {propertyValue.Scale, propertyValue.Offset}
elseif typeof(propertyValue) == "EnumItem" then
propertyData.Type = "EnumItem"
propertyData.EnumType = tostring(propertyValue.EnumType)
propertyData.Value = propertyValue.Name
elseif typeof(propertyValue) == "number" then
propertyData.Type = "Number"
propertyData.Value = tostring(propertyValue)
else
propertyData.Type = typeof(propertyValue)
propertyData.Value = propertyValue
end
data.Properties[propertyName] = propertyData
end
end
else
local success, properties = pcall(function() return APIService:GetProperties(instance) end)
if success and properties then
for propertyName, propertyValue in pairs(properties) do
local propertyData = {}
if typeof(propertyValue) == "BrickColor" then
propertyData.Type = "BrickColor"
propertyData.Value = propertyValue.Name
elseif typeof(propertyValue) == "Vector3" then
propertyData.Type = "Vector3"
propertyData.Value = {propertyValue.X, propertyValue.Y, propertyValue.Z}
elseif typeof(propertyValue) == "Color3" then
propertyData.Type = "Color3"
propertyData.Value = {propertyValue.R, propertyValue.G, propertyValue.B}
elseif typeof(propertyValue) == "Vector2" then
propertyData.Type = "Vector2"
propertyData.Value = {propertyValue.X, propertyValue.Y}
elseif typeof(propertyValue) == "UDim2" then
propertyData.Type = "UDim2"
propertyData.Value = {propertyValue.X.Scale, propertyValue.X.Offset, propertyValue.Y.Scale, propertyValue.Y.Offset}
elseif typeof(propertyValue) == "CFrame" then
propertyData.Type = "CFrame"
propertyData.Value = {propertyValue:components()}
elseif typeof(propertyValue) == "UDim" then
propertyData.Type = "UDim"
propertyData.Value = {propertyValue.Scale, propertyValue.Offset}
elseif typeof(propertyValue) == "EnumItem" then
propertyData.Type = "EnumItem"
propertyData.EnumType = tostring(propertyValue.EnumType)
propertyData.Value = propertyValue.Name
elseif typeof(propertyValue) == "number" then
propertyData.Type = "Number"
propertyData.Value = tostring(propertyValue)
else
propertyData.Type = typeof(propertyValue)
propertyData.Value = propertyValue
end
data.Properties[propertyName] = propertyData
end
end
end
for _, child in ipairs(instance:GetChildren()) do
local childData = serialiseInstance(child)
if childData then
table.insert(data.Children, childData)
else
warn("Skipping child: " .. child.Name)
end
end
return data
end
local serialize = serialiseInstance(obj)
print(HttpService:JSONEncode(serialize))
return HttpService:JSONEncode(serialize)
end
function serialiser.Deserialise(data)
local function deserialiseInstance(data)
local blockType = game.ReplicatedStorage.Files.BlockTypes:FindFirstChild(data.Name)
local instance
if blockType then
instance = blockType:Clone()
else
instance = Instance.new(data.ClassName)
end
instance.Name = data.Name
local parent = nil
local success = pcall(function()
for propertyName, propertyData in pairs(data.Properties) do
local propertyValue
if propertyData.Type == "BrickColor" then
propertyValue = BrickColor.new(propertyData.Value)
elseif propertyData.Type == "Vector3" then
propertyValue = Vector3.new(unpack(propertyData.Value))
elseif propertyData.Type == "Color3" then
propertyValue = Color3.new(unpack(propertyData.Value))
elseif propertyData.Type == "Vector2" then
propertyValue = Vector2.new(unpack(propertyData.Value))
elseif propertyData.Type == "UDim2" then
propertyValue = UDim2.new(unpack(propertyData.Value))
elseif propertyData.Type == "CFrame" then
propertyValue = CFrame.new(unpack(propertyData.Value))
elseif propertyData.Type == "UDim" then
propertyValue = UDim.new(unpack(propertyData.Value))
elseif propertyData.Type == "Number" then
local convertedValue = tonumber(propertyData.Value)
if convertedValue then
propertyValue = convertedValue
else
propertyValue = propertyData.Value
end
elseif propertyData.Type == "EnumItem" then
local enumType = Enum[propertyData.EnumType]
if enumType then
propertyValue = enumType[propertyData.Value]
else
warn("Failed to find Enum type: " .. propertyData.EnumType)
end
elseif propertyName == "Parent" then
parent = propertyData.Value
else
propertyValue = propertyData.Value
end
if instance[propertyName] ~= nil and propertyName ~= "Parent" and propertyName ~= "DataCost" and propertyName ~= "ClassName" then
local success, errorMsg = pcall(function()
instance[propertyName] = propertyValue
end)
if not success then
warn("Failed to set property: " .. propertyName .. " - " .. errorMsg)
end
elseif propertyName ~= "DataCost" and propertyName ~= "ClassName" and propertyName ~= "className" then
warn("Property not found: " .. propertyName)
end
end
end)
if not success then
warn("Failed to set properties for " .. data.Name)
end
for _, childData in ipairs(data.Children) do
local childInstance = deserialiseInstance(childData)
if instance.Name == "SpawnLocation" then
if instance:FindFirstChild("SpawnDecal") then
local a = 0
for _, decal in pairs(instance:GetChildren()) do
if instance:FindFirstChild("SpawnDecal") then
a = a + 1
end
if a == 2 then
instance:FindFirstChild("SpawnDecal"):Destroy()
a = a - 1
end
end
end
end
childInstance.Parent = instance
end
if parent then
instance.Parent = game.Workspace:FindFirstChild(parent)
end
return instance
end
local deserialisedInstance = deserialiseInstance(HttpService:JSONDecode(data))
print(deserialisedInstance)
return deserialisedInstance
end
return serialiser```