How is a boolean variable physically stored in DataStore?

Always good to have variety :slight_smile:

Interesting topic. Here’s my take thanks to the snippets above:

local module = {}



module.compress32 = function(booleans_table)
  assert(#booleans_table <= 32, "can't compress tables longer than 32")
  
  local compressed_booleans = 0
  for i = 1, #booleans_table do
    if booleans_table[i] == true then
      compressed_booleans += 2 ^ (i - 1)
    end
  end
  
  return compressed_booleans
end

module.check_compressed_bit = function(compressed_booleans, bit_number)
  return bit32.extract(compressed_booleans, bit_number - 1) == 1
end

module.decompress32 = function(compressed_booleans)
  local booleans_table = {}
  local found_last_true = false
  for i = 32, 1, -1 do
    print(i)
    if module.check_compressed_bit(compressed_booleans, i) == true then
      found_last_true = true
      booleans_table[i] = true
    elseif found_last_true == true then
      booleans_table[i] = false
    end
  end
  
  return booleans_table
end



return module

Additionally

Since everything in datastores is encoded as a JSON string and the limit is string length instead of bit size, would it be useful to have numerical compression too? Basically convert numbers to as high base as possible so they appear shorter in the string. This could be useful for games that need huge numbers with precision or base building games that save a very precise CFrame. Here's an example:
local module = {}



local symbol_table = {"1", "2", "3", "4", "5", "6", "7", "8", "9",
  "a", "b", "c", "d", "e", "f",
  "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
  "A", "B", "C", "D", "E", "F",
  "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
symbol_table[0] = "0"



local function get_symbol_index(number_string, i)
  return table.find(symbol_table, string.sub(number_string, i, i)) or 0
end

local function to_base_10(number, from_base)
  local new_number = 0
  for i = 1, #number do
    new_number += get_symbol_index(number, #number - (i - 1)) * (from_base ^ (i - 1))
  end
  return new_number
end

local function to_base_x(base_10_number, to_base)
  local new_number = ""
  while base_10_number > 0 do
    local remainder = base_10_number % to_base
    base_10_number = math.floor(base_10_number / to_base)
    new_number = symbol_table[remainder].. new_number
  end
  return new_number
end



module.convert = function(number: string, from_base: number, to_base: number)
  if typeof(number) ~= "string" then number = tostring(number) end
  local base_10_number = to_base_10(number, from_base)
  local new_number = to_base_x(base_10_number, to_base)
  return new_number
end



return module