ModiBool - Efficient boolean state manager


ModiBool - Efficient boolean state manager

Get it on Creator Store:
https://create.roblox.com/store/asset/115453174706909/ModiBool


Introduction

ModiBool exists to solve a common problem while coding: when many systems each own independent boolean conditions, you frequently need to know simple aggregates. However, jumbled if-then chains and repeated boolean expressions quickly become brittle and hard to reason about. ModiBool combats this by allowing separate systems to set and remove unique keys, and for consumers to ask simple yes/no questions.


API

Lifecycle

-- Creates a new ModiBool class object
ModiBool.new(): Class
-- Cleans up and destroys a class object
Class:Destroy()

Flags

-- Sets the value of a flag
Class:Set(Key: any, Bool: boolean)
-- Removes a flag and its influence
Class:RemoveKey(Key: any)
-- Inserts an anonymous flag for a duration of time before being automatically removed
Class:SetTimed(Bool: boolean, Lifetime: number)
-- Calls back when there's a change to any flag
Class:Connect(Callback: ()->()): Connection

Queries

-- Returns if any one flag's value is 'true'
Class:IsAtleastOneTrue(): boolean
-- Returns if any one flag's value is 'false'
Class:IsAtleastOneFalse(): boolean

Utilities

-- ModiBool allows public access to 'Symbol' util for never-colliding keys
ModiBool.Symbol(Name: string?): any (userdata)

Debugging

-- Prints all entries. 
-- Includes 'Name' in output message if provided. Sinks if rate-limitted by Ratelimit
Class:Debug_PrintEntries(Name: string?, Ratelimit: number?)
-- Prints all entries after there's a change to any flag
-- Includes 'Name' in output message if provided
Class:Debug_PrintEntriesOnChanged(Name: string?)

Notes

  • The query methods are very fast, with O(1) time complexity
  • The module depends on Signal and Symbol (both modules by @ Sleitnick)
  • Keys can collide and overwrite, so for a scenario where a state can have lots of unpredictable keys, there’s public access to Symbol which can be used for unique keys. This is noted under the API section aswell

Examples

For example, here’s pseudo-code for a case where the player is only allowed to sprint under certain circumstances:

local ModiBool = require(script.ModiBool)
local SprintingEnabledState = ModiBool.new()

-- Independent systems
SprintingEnabledState:Set("Stamina", true) -- stamina allows sprinting
SprintingEnabledState:Set("Crouching", false) -- crouching disallows sprinting

-- Consumer: only allow sprinting if there are no false flags
local CanSprint = not SprintingEnabledState:IsAtleastOneFalse() -- (outputs 'false')

In this scenario, each system (stamina, crouch, etc.) owns a key and is responsible for its entry. The consumer does not need to know about each individual flag and is only is concerned about the aggregate outcome.

Let’s look at a more complex example. Here’s a scenario where a UI prompt will only be visible under certain circumstances:

local ModiBool = require(script.ModiBool)
local PromptEnabledState = ModiBool.new()

-- Initial/base flag
PromptEnabledState:Set("ActivePrompt", true)

local function UpdateVisibility()
	-- Consumer: only allow visibility if theres atleast one true flag and there cant be any false flags
	local Visible = 
		PromptEnabledState:IsAtleastOneTrue() 
		and not PromptEnabledState:IsAtleastOneFalse()
	
	print("Prompt visible:", Visible)
end

-- Call UpdateVisibility whenever a flag is changed
PromptEnabledState:Connect(UpdateVisibility)
UpdateVisibility() -- and once initially

-- Elsewhere: independent systems toggle their flags
PromptEnabledState:Set("ShopWindow", true) -- shop window is allowing; perhaps it's closed

PromptEnabledState:Set("SettingsWindow", false) -- settings window is disallowing; perhaps it's opened
-- When SettingsWindow closes:
PromptEnabledState:RemoveKey("SettingsWindow") -- removes the flag and its influence

-- Final result:
--> "Prompt visible: true"

Closing

Please let me know your thoughts on this! And also let me know if there’s any typos in this post or any part that could be written better. Thanks :slightly_smiling_face:


4 Likes

Id like to ask when did you make your avatar

1 Like

Have you considered employment?

1 Like