simple perfomant part serializing test.
results:
Processing: image.png…
test place:
MansionModelTest.rbxl (104.8 KB)
code:
-- note about the Serialize func:
-- im not ■■■■■■ its just that copying and paste some code will skip some additional bytecodes at the compiled script
local partFormat = "I1I2I1I1I1fffffffff"
local stringPack = string.pack
local function Serialize(model: Model)
local serializedData = ""
for i, v in model:GetDescendants() do
if v:IsA("Part") then
local color = v.Color
local size = v.Size
local position = v.Position
local orientation = v.Orientation
local specialMesh = v:FindFirstChildOfClass("SpecialMesh")
serializedData ..= stringPack(partFormat,
if specialMesh and specialMesh.TextureId == "" then 0 else v.Shape.Value,
v.Material.Value,
color.R*255, color.G*255, color.B*255,
size.X, size.Y, size.Z,
position.X, position.Y, position.Z,
orientation.X, orientation.Y, orientation.Z
)
elseif v:IsA("WedgePart") then
local color = v.Color
local size = v.Size
local position = v.Position
local orientation = v.Orientation
serializedData ..= stringPack(partFormat,
3,
v.Material.Value,
color.R*255, color.G*255, color.B*255,
size.X, size.Y, size.Z,
position.X, position.Y, position.Z,
orientation.X, orientation.Y, orientation.Z
)
elseif v:IsA("CornerWedgePart") then
local color = v.Color
local size = v.Size
local position = v.Position
local orientation = v.Orientation
serializedData ..= stringPack(partFormat,
4,
v.Material.Value,
color.R*255, color.G*255, color.B*255,
size.X, size.Y, size.Z,
position.X, position.Y, position.Z,
orientation.X, orientation.Y, orientation.Z
)
end
end
return serializedData
end
local stringUnpack = string.unpack
local partDataSize =
1 + -- Shape takes 1 byte (I1)
2 + -- Material takes 2 bytes (I2)
3 + -- Color takes 3 bytes (I1I1I1)
(4 * 3) * 3
print(`bytes per part: {partDataSize}`)
local function Unserialize(serializedData: string)
local dataLenght = #serializedData
local i = 1
local j = 1
local model = Instance.new("Model")
while j < dataLenght do
j = i + partDataSize
local shapeValue,
materialValue,
colorR, colorG, colorB,
sizeX, sizeY, sizeZ,
positionX, positionY, positionZ,
orientationX, orientationY, orientationZ = stringUnpack(partFormat,
serializedData:sub(i, j)
)
local part = Instance.new("Part")
part.Shape = Enum.PartType:FromValue(shapeValue)
part.Material = Enum.Material:FromValue(materialValue)
part.Color = Color3.fromRGB(colorR, colorG, colorB)
part.Size = Vector3.new(sizeX, sizeY, sizeZ)
part.Position = Vector3.new(positionX, positionY, positionZ)
part.Orientation = Vector3.new(orientationX, orientationY, orientationZ)
part.Anchored = true
part.Parent = model
i = j
end
return model
end
warn("Serializing:")
local start = os.clock()
local serializedData = Serialize(workspace.Mansion)
local elapsed = os.clock() - start
print(`elapsed: {elapsed}`)
local serializedDataKB = #serializedData/1024
print(`serialized data size: {serializedDataKB}kb`)
print(`| size with ZLib lv.5 compression: ~{serializedDataKB/4.75}kb`) -- I think zlib level 5 would reduce something between 80% of the size
warn("Deserializing:")
local start = os.clock()
local model = Unserialize(serializedData)
local elapsed = os.clock() - start
print(`elapsed: {elapsed}`)
local dataLenght = #serializedData
print(`parts: {dataLenght/partDataSize}`)
model.Parent = workspace
forgoted to mention that:
it serializes to uft8 so copying and pasting wont really work, you would need to encode it first.