Hello everyone! Recently I wrote a module which lets you “compress” different kinds of values (CFrame, Vector3, double, bool) into strings. Why, you might ask? For example, to save DataStore space! Compressed values take way less space. Note that this is only really going to benefit you if you’re using JSON strings to store data (that’s what I tested it on).
Alright, so how much space does it actually save?
It takes one character to store a compressed bool.
It takes 1-8 characters to store a number (double), and the amount of characters is based on the amount of decimals
It takes 5-24 characters to store a Vector3, same deal as with numbers
It takes 17-74 characters to store a CFrame, same deal as with vector3s, the more decimals, the more characters. I only save the position, look and up vectors for CFrames, since these are the only vectors needed to fully reconstruct a CFrame.
Source code:
local Compressor = {}
function Compressor:CompressBool(bool)
return string.char(bool and 8 or 9)
end
function Compressor:DecompressBool(str)
return string.byte(str) == 8
end
function Compressor:CompressDouble(item)
local str = tostring(item)
return string.len(str) > 7 and string.pack("d", item) or str
end
function Compressor:DecompressDouble(str)
return string.len(str) > 7 and string.unpack("d", str) or tonumber(str)
end
function Compressor:CompressVector3(vec)
local strArray = {
tostring(vec.X);
tostring(vec.Y);
tostring(vec.Z)
}
local concat = table.concat(strArray, ":")
return string.len(concat) > 23 and string.pack("ddd", vec.X, vec.Y, vec.Z) or concat
end
function Compressor:DecompressVector3(str)
local x, y, z
if string.len(str) > 23 then
x, y, z = string.unpack("ddd", str)
else
local array = string.split(str, ":")
local numArray = table.create(3, math.pi)
for i, v in ipairs(array) do
numArray[i] = tonumber(v)
end
x, y, z = table.unpack(numArray)
end
return Vector3.new(x, y, z)
end
function Compressor:CompressCFrame(cf)
local basePos = cf.Position
local mag = basePos.Magnitude
local vecArray = table.create(3, Vector3.new())
vecArray[1] = basePos;
vecArray[2] = basePos + cf.LookVector;
vecArray[3] = cf.UpVector;
local strArray = table.create(3, "")
for i, v in ipairs(vecArray) do
strArray[i] = self:CompressVector3(v)
end
return table.concat(strArray, "_")
end
function Compressor:DecompressCFrame(str)
local vecArray = table.create(3, Vector3.new())
for i, v in pairs(string.split(str, "_")) do
vecArray[i] = self:DecompressVector3(v)
end
return CFrame.lookAt(table.unpack(vecArray))
end
return Compressor
Put the code above into a module script.
The functions should be self-explanatory.
If you have and questions or concerns regarding the module, post a reply and I’ll answer asap!