In terms of "compressing" colour values, what is the best approach?

Hi,

So I am planning on making a game that would require saving many values (CFrames, colours, vector3’s…), so I’m looking into sort of packing the values as much as I can, and I want to learn from this, not be spoonfed.

Anyway, for saving colours, I found one method that seems to work fine, and that’s by plugging the R, G, and B values into this formula:

65536 * r + 256 * g + b

This returns a number between 0 and 16777215, being black and white respectively.
What I’m unsure of is whether this is actually efficient in saving datastore space since I could be potentially using up to 8 characters when a hex code has 6. That being said, is it efficient to solely rely on the integer method, or is it more efficient to rely on hex codes? Or should I dynamically rely on one or the other depending on the length of the integer (if length of the int is smaller than 6, rely on integer method, else use hex)?

Hello, yeah I’d save it as a hex since it’s only a 6 character string.

This might help you with Color3 stuff.

https://developer.roblox.com/en-us/api-reference/datatype/Color3

Or you could find a tycoon model with a custom colors thing and see if you can find something in the scripts.

1 Like

You could try serialize the color in a table and use the JSON encode function of Http Service that will give you a long flesh of character to save

like that:

local ColorTable = {
Color.r,
Color.g,
Color.b
}

local ColorToSave = game:GetService(“HttpService”):JSONEncode(ColorTable)

1 Like

That is true but that isn’t very efficient when it comes to optimizing in order to not exceed the 4M character limit. If I were to serialize a Color3 to a string for example, it would be 9 characters, being RRRGGGBBB. The special thing about hex codes and the integer method I mentioned in the OP, is that the max lengths are 6 and 8 respectively, which might not seem like it’s reducing much but it definitely does add up.

1 Like

The easy option is to just use

Color3:ToHex()
And
Color3.fromHex()

But if you want to compress all numbers to only a few characters then watch this video

I know this is 2 months ago ok

You could probably compress the number into multiple strings using string.char and backwards with string.byte. It has 256 possible characters, although I don’t think anything beyond 128 in string.char is possible on a datastore so we get half of the characters, and I don’t think char 0 also works for datastores so that leaves us with 127 characters. It is still alot of numbers to fit into one character.

This is my attempt

local color = Color3.new(math.random(),math.random(),math.random()) -- Random color
local hex = tonumber("0x"..color:ToHex()) -- turn to number

local function compress(number)
	local s = ""
	repeat s ..= string.char(number%127+1)
		number = math.floor(number/127)
	until number <= 0
	return s
end
local function decompress(s)
	local n = 0
	for i, v in ipairs(string.split(s,"")) do
		n += 127^(i-1)*(string.byte(v)-1)
	end
	return n
end

local compressed = compress(hex)
local decompressed = decompress(compressed)
print(decompressed == hex, #compressed) -- is decompressed equal to original number; and how many characters

It turns the color values into a number, then compresses it using string.char. This shrinks the color values down to 4 characters. If 256 characters was possible, it would shrink it down to 3 characters which is amazing. Anyways, I’m too lazy to turn the number back into colors but I think you can do it.

Edit: this looks more like a compressor for numbers rather than colors, but it still does its job.

Edit2: this compressor doesn’t like big numbers. Numbers above 2^54 (from my tests) sometimes get inaccuracies about ~25.6%, and some specific numbers will decide to throw an error

I did some debugging, and apparently very large numbers have weird behavior with arithmetic.
image
How is the remainder more than the divisor?
image
The last two digits is 51 how is it 00?

Cause of this: please tell me cuz i dont know

2 Likes

That’s true, it’ll still definitely be useful though when I get to the compression/decompression stage. Thanks!

1 Like