How is a boolean variable physically stored in DataStore?

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.

1 Like

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?

1 Like

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.

4 Likes

So my concern is real! A boolean variable will be passed as a string!

1 Like

I found this website while writing my first reply:

http://blog.millermedeiros.com/using-integers-to-store-multiple-boolean-values/

It actually seems kind of interesting, so i’m gonna tinker a little and try to make a function for serializing booleans.

1 Like

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.

1 Like

With bitwise operations you can compress that data even further and express that boolean array as 0b1011, or just simply 11.

You can store up to 32 different boolean values in a single integer that way, or 64 with long integers.

That’s wise.
Is there any existing compression data system in .lua?

By converting binary to base10 you could put 160 bytes of booleans into 4 bytes

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.

How does that work? 0 and 1 in binary are still 0 and 1 in decimal numbers.

There are bit operations in lua, yes.

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

1 Like

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

1 Like

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

There is a plugin called DataStoreEditor.

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.

1 Like

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
3 Likes

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

2 Likes