Kinda interestingly stumped upon this bug. Basically, Color3 values created on macs and windows machines differ after about 7 decimal places. After which floating point issues causes comparison of same colors created on two different machines to be false. IE If a developer created a color on a windows machine in studio then a mac player tried to compare that color to a color3 created on their machine.
I have created a repo place here: Color3BugDemo.rbxl (15.7 KB)
You can look inside the localscript in the gui for some notes.
To use this repo place, open the place on a mac, the values on the bottom of the grey panel should mismatch after 7 places, if you open that same place on a windows machine, those same values will match, unless you change the reference imagecolor3.
Look at the bottom of the grey panel in these images, and compare the numbers from the left and right sides. The top of the grey panel shows the raw tostring(color3). The bottom shows each color channel (R, G, B) with decimal places, this is where the bug is shown.
Yes I think it matters, that green box is a button I made on a windows machine which is how I found this. I was simply checking to see if the button was green and it was returning false on mac machines (breaking part of the game for mac users), where on a windows machine it worked just fine. In my local script I check to see if that image color matches green, this green is represented like color3.fromRGB(100,220,100) but since I made that to compare on a mac, that throws it off and returns false because of those floating point errors. AKA mac green doesn’t equal windows green, making if statements comparing colors impossible between machines without doing something like
if (math.floor(SomeColor3.r*1000) == math.floor(CompareColor3.r*1000)) and (math.floor(SomeColor3.g*1000) == math.floor(CompareColor3.g*1000)) and (math.floor(SomeColor3.b*1000) == math.floor(CompareColor3.b*1000)) then
My question is, why do you use the Color of a screen element to track a client’s state instead of abstracting it further. For example, what makes the element turn green? Why not send that data?
I made a similar mistake to this once with The Stalker: Reborn due to dumb design choices on my part. Each item in my game is given a unique numerical value so I can store and reference them easier using the item database table. Sometimes I would just type a random long number and I’d be like hey that’s pretty good. The problem was that I was storing the values as strings in the lookup array, and for some reason there was a difference between how PCs and Macs were dealing with the integer overflow, so I couldn’t properly look up the physical item to display in Module3D from a Mac’s client and it was breaking their wardrobe. I fixed this by doing mod 2^32 on each unique id.
I feel like some of your replies are missing the real point. My example is just that, an example and just so happens how I found the glitch. Critiquing development practices for the sake of this repo doesnt help the conversation, its simply to show how the bug is reproduced. The issue is that color3 values instanced on Macs and Windows machines differ, making comparing colors between machines impossible, which I think is an issue worth talking about. Comments like “this is so minor that it’s just silly” arent helpful…
We’re not critiquing development practices – you’re just not doing it right. This is the same kind of question as “Why doesn’t part.red = color work?” on Scripting Helpers, the difference here being they’re lacking understanding of programming, while you’re lacking an understanding of computing.
There are two reasons they’re not the same:
Floating point values are, by nature, imprecise
Different operating systems represent numbers differently, which is the cause of the discrepancy
Neither of which are ROBLOX issues. In physics calculations – which you may be more familiar with – there’s always an inherit amount of error you have to take into account because of measurement device imprecision. This is not so different.
Comparing two colors isn’t that difficult or ugly in RBXLua, provided you’re willing to sacrifice some granularity:
local function AreTheseColorsTheSameOrAtLeastVerySimilarAtFirstGlance(color1,color2)
return BrickColor.new(color1) == BrickColor.new(color2)
end
That said, given there’s only a 1 in 16,777,216 chance that any two 24-bit colors are the same, it’s not a very good practice to even assume that two colors might be the same. The above code works because it cuts down the number of possible colors from 16,777,216 to fewer than 500.
I don’t know if you are trying to use the color of an element as part of the game’s logic, or if the example is purely academic, but as I said before: using colors to determine your game’s state is not a good idea.
To use the color of an element as a part of the game’s logic is somewhat similar to finding a car’s speed by pointing a camera at the dashboard and using machine vision to track the needle. The reliability and simplicity of an encoder to the input shaft is far greater.
Will make another reply about how you shouldn’t check direct equality when comparing floats. Here is better way to compare floats and this is something that is used in LuaUnit, Lua package for unit testing.
function compareFloats(f1, f2, precision)
return math.abs(f1 - f2) < precision
end
local float1, float2 = 1.2345678, 1.2345679
print(compareFloats(float1, float2, 10^(-4)))
print(float1 == float2)
It’s not something that can be fixed by Roblox! Floating point is floating point. This is literally exactly why you shouldn’t use == with floating point values in languages that use bit-equality.
You will need to be smarter about how you do this. It isn’t impossible. Convert the colors to 0-255, floor them, and then compare. 1 in 10^7 is a much smaller error than 1 in 255, so there’s basically no way you’ll have a difference here.