How is a boolean variable physically stored? As a number (0, 1) or a string (“true”, “false”)?
I ask this because I created a system of conversion dictionaries to reduce data transmission, but I did not put boolean variables in this conversion because I imagine they are already stored as 0 or 1. But if they happen to be stored as a string, I will have to include the conversion also for that.
A boolean is probably the smallest data type there is, since it only exists in one of two possible values, so it is possible to express one in a single bit. Theoretically it could be possible to optimize a system to store up to 8 values in a single byte. (for that you would need to use bitwise operations to extract specific values since there’s no other way to read or write onto individual bits)
Numbers however take up multiple bytes, so storing a single boolean as a number might be wasteful. (unless you’re doing something like mentioned above) Strings could be used, since each character takes up one byte, but the String object itself would take up more space than just it’s text value.
Thanks, but I didn’t understand if my question was answered.
I understand that boolean theoretically takes up less space.
But my question is how the boolean is actually transmitted to Roblox Servers during DataStore.
This is what will make the difference in data compression during transmission. Because if I have, for example, an array with 1000 booleans, how many bytes will actually be transmitted? 1000? 5000? 10,000?
In Roblox datastores, the data is serialized into JSON format:
Since keys, names, and scopes are strings, their length can be checked with string.len() . Data is also saved as a string in data stores, regardless of its initial type. The size of data can be checked with the JSONEncode() function that converts Lua data into a serialized JSON table.
So without optimization a plain boolean would become a 4-5 character substring of the JSON string.
I think that it’s using text because of using JSON, but you could probably save them in a more efficient way by storing something like 4 bool values in 1 integer, by merging the number so that 1 = true and 0 = false, and then decoding it when loading, so it looks something like this
true false true true
1011
That’s what I’m talking about.
So the final JSON string to be transmitted to servers actually converts a boolean value to string…
In this case, an array with 1000 booleans set as “false” will spend 5 bytes (or more) for each boolean: string “false” = 5 bytes…
Resulting in 5000 bytes. In my dictionary conversion system I can reduce this to a single byte.
I don’t think there is, but it should be possible to make one. You would need a function that can take a number and read/write a specific bit in that number.
You would also need to define a context for what the bit in each position represents as the in-game value, since you’d only be storing and retrieving the number.
You write down the number in base2 (binary) then convert it to base10 (decimal)
You should see a tutorial in how bits work, base2 is basically on or off, for example: here is a lit of base10 to base2
BASE-10 : BASE-2
10 | 1010
62 | 111110
251 | 11111011
As you can see there are a lot of bits to store a simple decimal
What I meant is that a boolean can be expressed as a single bit. A bit is the smallest unit of data there is.
A 32 bit integer looks like this:
00000000 00000000 00000000 00000000
Supposed you had an array of 32 booleans that looked like this:
01101010 11100000 00100010 11100000
If stored as a decimal that number would be 1793073888 (checked on google).
If this were an unsigned data type the number range would be between 0 and 2 ^ 32 - 1
That’s exactly what I meant, storing booleans using bits, saving them in datastore as a decimal and loading them as a decimal then converting them back to bits
It lets you type in a key and a scope, and then you can edit the datastore directly in roblox studio.
Its 15 robux, but worth like 1k robux. If you can buy it, i’d genuinely recommend it.
You could probably use something like this if you’re very concerned.
The loops could be unrolled and the out array presized or reused if you need better performance.
-- given an array of 32 booleans, this returns an integer whose bits correspond
-- to those bools. So if bools[1] is true, the 0th bit of the returned int will
-- be true
local function Save32Bools(bools)
assert(#bools == 32)
local out = 0
for i = 0, 31 do
if (bools[i+1]) then
out = bit32.band(out, bit32.lshift(1, i))
end
end
return out
end
-- given a uint32, returns an array of 32 bools based on the bits of that
-- integer
local function Load32Bools(bitmask)
-- preload with 32 bools
local out = {}
for i = 0, 31 do
out[i + 1] = bit32.btest(bitmask, bit32.lshift(1, i))
end
return out
end
With the bit32 library it was easier than I thought it would be.
local array = {true, false, true, true}
local function serialize(a)
local n = 0
for i = 1, #array do
n = n + 2 ^ (i - 1) * (array[i] and 1 or 0)
end
return n
end
local function value(n, i)
return bit32.extract(n, i) == 1
end
local x = serialize(array)
print(x) -- 13 (not 11 since in this method the values are stored right-to-left)
print(value(x, 0)) -- true
print(value(x, 1)) -- false
print(value(x, 2)) -- true
print(value(x, 3)) -- true
edit: didn’t realize someone already posted a script at the same time