I'm working on a system in Core to save the transforms of furniture, specifically position and rotation, which are both Vector3's. I have these in player storage, so at some point to save all the player's furniture, I think I will end up maxing out player storage. So I'm converting all the Vector3's to strings, with a modified version of a Roblox script that I found:
local API = {}
API.VectorToString = function(vec)
return math.floor(vec.x*100)/100 ..' '.. math.floor(vec.y*100)/100 ..' '.. math.floor(vec.z*100)/100
end
API.StringToVector = function(str)
local tab = {}
for a in string.gmatch(str,"(%-?%d*%.?%d+)") do
table.insert(tab,a)
end
return Vector3.New(tab[1],tab[2],tab[3])
end
return API
So the question is, does converting all these Vectors to strings actually save space in my player data storage?
Most likely the Vector3 format is more efficient than a string conversion for storage. Each number in the Vector3 requires 4 bytes to be stored because each number is a 16-bit float. By converting the Vector3 values to strings, additional bytes are required (each digit you add requires one byte since a character requires one byte). If you need to store a Vector3 as a string I would suggest using the method below.
For anyone who would like to learn how computers can store such a wide range of numbers in only four bytes, I would highly recommend researching the IEEE 754 format.
Video that explains the IEEE754 Format
You can use the string.pack and string.unpack functions to convert floats to byte arrays which can be sent as strings. This method will only require 12 bytes (12 characters) in total when sending data and has around 5 to 6 decimals points of precision. While this method may only save a few bytes it will allow you to send/save far more precise numbers/positions.
local API = {}
API.VectorToString = function(vec)
--Convert the x,y,z positions to bytes
local byteXValue = string.pack('f', vec.x, 0)
local byteYValue = string.pack('f', vec.y, 0)
local byteZValue = string.pack('f', vec.z, 0)
--Combine the floats bytes into one string
local combinedBytes = byteXValue + byteYValue + byteZValue
return combinedBytes
end
API.StringToVector = function(str)
--Convert the x,y,z positions from bytes to float values
--Every 4th byte represents a new float value
local byteXValue = string.unpack('f', string.sub(1, 4))
local byteYValue = string.unpack('f', string.sub(5, 8))
local byteZValue = string.unpack('f', string.sub(9, 12))
--Combine the x,y,z values into one Vector3 object
return Vector3.New(byteXValue, byteYValue, byteZValue)
end
return API