Logic gate based library. Useful if you wanna make ifs or ands or anything like that more readable in a logical way, other than that its 94-98% close to lua runtime by following luau.org/preformance
V1.2
```
--!optimize 2
--@Simply.Bamb000 / Disc: simply.bamboo
--Version 1.2
--[=[
@class Logic
Boolean gates that accept `any`, so they drop straight onto values
arriving from remotes or attributes without unwrapping each one first.
Luau only counts `nil` and `false` as missing, so `0` and `""` both read
as set. Reach for `Logic.Empty` when a zero or a blank string should
count as missing too.
```lua
local Logic = require(ReplicatedStorage.Logic)
-- A feature gate, instead of three guards and an early return.
if Logic.And(IsAlive, Not(IsInJail), HasTool) then
StartBuilding()
end
-- Conditions that belong together, kept on one line.
local CanJump = Logic.And(Not(IsOnCooldown), IsGrounded, Stamina >= 10)
-- "Exactly one of these" is a gate, not a hand written branch.
Logic.Xor(IsNight, IsUnderground)
```
]=]
--[=[
@within Logic
A function that answers a yes/no question, so it can be negated and
passed around without an adapter.
]=]
export type Predicate<A...> = (A...) -> boolean
const Logic = {}
--[=[
@within Logic
@param value any
@return boolean
`true` when `value` is neither `nil` nor `false`.
```lua
-- Bindings report 0 while no key is held, and 0 reads as set.
Logic.True(0) --> true
Logic.True("") --> true
Logic.True(nil) --> false
```
]=]
function Logic.True(value: any): boolean
return not not value
end
--[=[
@within Logic
@param value any
@return boolean
`true` when `value` is `nil` or `false`. Inverse of `Logic.True`.
```lua
-- "There is no nickname set" without a second condition.
Logic.False(player.Nickname)
```
]=]
function Logic.False(value: any): boolean
return value == nil or value == false
end
--[=[
@within Logic
@param value any
@return boolean
`true` for `nil`, `false`, `""` or `0`. The blank check that C# and
JavaScript spell `string.IsNullOrEmpty` and `== 0`. Stricter than
`Logic.False`.
```lua
-- Treat an empty text box and a zeroed slider as unset.
Logic.Empty(nameBox.Text) --> true
Logic.Empty(0) --> true
Logic.Empty("0") --> false, a string is never == a number
```
]=]
function Logic.Empty(value: any): boolean
return value == nil or value == false or value == "" or value == 0
end
--[=[
@within Logic
@param a any
@param b any
@param ... any
@return boolean
`true` when every argument reads as set, stopping at the first one that
does not.
```lua
-- A build permission check.
Logic.And(IsAlive, IsOwner, IsDaytime)
-- A dash that also has to respect the buffs on the player.
Logic.And(Not(HasStatus(Stunned)), Not(HasStatus(Invisible)), Stamina >= 25, IsGrounded)
Logic.And() is Logic.And(nil, nil), which is false
```
]=]
function Logic.And(a: any, b: any, ...: any): boolean
if not a or not b then
return false
end
const n = select("#", ...)
for i = 1, n do
if not (select(i, ...)) then
return false
end
end
return true
end
--[=[
@within Logic
@param a any
@param b any
@param ... any
@return boolean
`true` when any argument reads as set, stopping at the first one that does.
```lua
-- Any one of the unlock paths grants access.
Logic.Or(IsPremium, HasGamePass, IsInTrial)
-- Fall back through a chain of options.
Logic.Or(HasOverride, LoadedConfig, DefaultConfig)
```
]=]
function Logic.Or(a: any, b: any, ...: any): boolean
if a or b then
return true
end
const n = select("#", ...)
for i = 1, n do
if select(i, ...) then
return true
end
end
return false
end
--[=[
@within Logic
@param a any
@param b any
@param ... any
@return boolean
`true` when an odd number of arguments read as set. The one gate that
cannot stop early, since no single argument settles the answer.
```lua
-- Reject a double trigger where either input alone is acceptable.
Logic.Xor(JumpPressed, DashPressed)
-- Odd one out of three.
Logic.Xor(FlagA, FlagB, FlagC)
```
]=]
function Logic.Xor(a: any, b: any, ...: any): boolean
local odd = (not not a) ~= (not not b)
const n = select("#", ...)
for i = 1, n do
odd = odd ~= (not not (select(i, ...)))
end
return odd
end
--[=[
@within Logic
@param a any
@param b any
@param ... any
@return boolean
Negated `Logic.And`, stopping at the first argument that is not set.
```lua
-- Blocked whenever the player is stunned, whatever else is true.
Logic.Nand(HasStatus(Stunned), HasInput)
```
]=]
function Logic.Nand(a: any, b: any, ...: any): boolean
return not Logic.And(a, b, ...)
end
--[=[
@within Logic
@param a any
@param b any
@param ... any
@return boolean
Negated `Logic.Or`, stopping at the first argument that is set.
```lua
-- Chat is blocked only when nothing at all is happening.
Logic.Nor(IsDead, IsJailed, IsMuted)
```
]=]
function Logic.Nor(a: any, b: any, ...: any): boolean
return not Logic.Or(a, b, ...)
end
--[=[
@within Logic
@param a any
@param b any
@param ... any
@return boolean
Negated `Logic.Xor`, so an even number of arguments read as set.
```lua
-- Both toggles agree with each other.
Logic.Xnor(IsMuted, IsHidden)
```
]=]
function Logic.Xnor(a: any, b: any, ...: any): boolean
return not Logic.Xor(a, b, ...)
end
--[=[
@within Logic
@param value any
@return boolean
`true` when `value` is `nil` or `false`. Same as `Logic.False`, named
for the gate.
```lua
if Logic.Not(leaderstats) then
WaitForStats()
end
```
]=]
function Logic.Not(value: any): boolean
return value == nil or value == false
end
--[=[
@within Logic
@param a any
@param b any
@return boolean
Reads as "if `a`, then `b`", so `true` unless `a` is set and `b` is not.
Same as `not a or b` but always returns a real `boolean`.
```lua
-- An admin skips the whitelist; everyone else has to be on it.
Logic.Implies(IsAdmin, IsWhitelisted)
-- "If the server is locked down, the event must be trusted too."
Logic.Implies(IsLockedDown, IsFromServer)
```
]=]
function Logic.Implies(a: any, b: any): boolean
return (not a) or (not not b)
end
--[=[
@within Logic
@param a any
@param b any
@return boolean
`true` when both arguments read the same way, so two set values and two
missing values both pass.
```lua
-- The client and the server agree on the mode.
Logic.Equiv(ClientMode, ServerMode)
```
]=]
function Logic.Equiv(a: any, b: any): boolean
return (not not a) == (not not b)
end
--[=[
@within Logic
@param ... any
@return number
How many arguments read as set.
```lua
-- Score how many hazard signals a room raises.
local danger = Logic.Count(IsDark, IsFoggy, IsNarrow)
```
]=]
function Logic.Count(...: any): number
local count = 0
const n = select("#", ...)
for i = 1, n do
if select(i, ...) then
count += 1
end
end
return count
end
--[=[
@within Logic
@param needed number
@param ... any
@return boolean
`true` when at least `needed` arguments read as set, stopping as soon as
the count is reached. `needed` of 0 or less is always `true`.
```lua
-- Two of the three conditions make it a hard encounter.
Logic.AtLeast(2, IsDark, IsFoggy, IsNarrow)
-- A co-op difficulty that scales with the party.
Logic.AtLeast(4, PlayersAlive)
```
]=]
function Logic.AtLeast(needed: number, ...: any): boolean
if needed <= 0 then
return true
end
local count = 0
const n = select("#", ...)
for i = 1, n do
if select(i, ...) then
count += 1
if count >= needed then
return true
end
end
end
return false
end
--[=[
@within Logic
@param allowed number
@param ... any
@return boolean
`true` when at most `allowed` arguments read as set, returning as soon as
one too many is seen.
```lua
-- Stop stacking buffs once three are already on.
Logic.AtMost(3, HasBuff(Regen), HasBuff(Haste), HasBuff(Shield))
```
]=]
function Logic.AtMost(allowed: number, ...: any): boolean
local count = 0
const n = select("#", ...)
for i = 1, n do
if select(i, ...) then
count += 1
if count > allowed then
return false
end
end
end
return true
end
--[=[
@within Logic
@param predicate Predicate<A...>
@return Predicate<A...>
Logical inverse, keeping the original arguments. Lets a named check be
flipped at the call site without editing the original.
```lua
const IsReady = function(player) return player.Character ~= nil end
const IsDead = Logic.Negate(IsReady)
Network.On("hit", IsReady)
Network.On("leave", IsDead)
```
]=]
function Logic.Negate<A...>(predicate: Predicate<A...>): Predicate<A...>
return function(...: A...): boolean
return not predicate(...)
end
end
return Logic
```
V1.3 -- Use the new luau beta thing for locals
--!optimize 2
--@Simply.Bamb000 / Disc: simply.bamboo
--Version 1.3
--[=[
@class Logic
Boolean gates that accept `any`, so they drop straight onto values
arriving from remotes or attributes without unwrapping each one first.
Luau only counts `nil` and `false` as missing, so `0` and `""` both read
as set. Reach for `Logic.Empty` when a zero or a blank string should
count as missing too.
```lua
local Logic = require(ReplicatedStorage.Logic)
-- A feature gate, instead of three guards and an early return.
if Logic.And(IsAlive, Not(IsInJail), HasTool) then
StartBuilding()
end
-- Conditions that belong together, kept on one line.
local CanJump = Logic.And(Not(IsOnCooldown), IsGrounded, Stamina >= 10)
-- "Exactly one of these" is a gate, not a hand written branch.
Logic.Xor(IsNight, IsUnderground)
```
]=]
--[=[
@within Logic
A function that answers a yes/no question, so it can be negated and
passed around without an adapter.
]=]
export type Predicate<A...> = (A...) -> boolean
const Logic = {}
--[=[
@within Logic
@param value any
@return boolean
`true` when `value` is neither `nil` nor `false`.
```lua
-- Bindings report 0 while no key is held, and 0 reads as set.
Logic.True(0) --> true
Logic.True("") --> true
Logic.True(nil) --> false
```
]=]
function Logic.True(value: any): boolean
return not not value
end
--[=[
@within Logic
@param value any
@return boolean
`true` when `value` is `nil` or `false`. Inverse of `Logic.True`.
```lua
-- "There is no nickname set" without a second condition.
Logic.False(player.Nickname)
```
]=]
function Logic.False(value: any): boolean
return not value
end
--[=[
@within Logic
@param value any
@return boolean
`true` for `nil`, `false`, `""` or `0`. The blank check that C# and
JavaScript spell `string.IsNullOrEmpty` and `== 0`. Stricter than
`Logic.False`.
```lua
-- Treat an empty text box and a zeroed slider as unset.
Logic.Empty(nameBox.Text) --> true
Logic.Empty(0) --> true
Logic.Empty("0") --> false, a string is never == a number
```
]=]
function Logic.Empty(value: any): boolean
return not value or value == "" or value == 0
end
--[=[
@within Logic
@param a any
@param b any
@param ... any
@return boolean
`true` when every argument reads as set, stopping at the first one that
does not.
```lua
-- A build permission check.
Logic.And(IsAlive, IsOwner, IsDaytime)
-- A dash that also has to respect the buffs on the player.
Logic.And(Not(HasStatus(Stunned)), Not(HasStatus(Invisible)), Stamina >= 25, IsGrounded)
Logic.And() is Logic.And(nil, nil), which is false
```
]=]
function Logic.And(a: any, b: any, ...: any): boolean
if not a or not b then return false end
for i = 1, select("#", ...) do
if not select(i, ...) then return false end
end
return true
end
--[=[
@within Logic
@param a any
@param b any
@param ... any
@return boolean
`true` when any argument reads as set, stopping at the first one that does.
```lua
-- Any one of the unlock paths grants access.
Logic.Or(IsPremium, HasGamePass, IsInTrial)
-- Fall back through a chain of options.
Logic.Or(HasOverride, LoadedConfig, DefaultConfig)
```
]=]
function Logic.Or(a: any, b: any, ...: any): boolean
if a or b then return true end
for i = 1, select("#", ...) do
if local val = select(i, ...) then return true end
end
return false
end
--[=[
@within Logic
@param a any
@param b any
@param ... any
@return boolean
`true` when an odd number of arguments read as set. The one gate that
cannot stop early, since no single argument settles the answer.
```lua
-- Reject a double trigger where either input alone is acceptable.
Logic.Xor(JumpPressed, DashPressed)
-- Odd one out of three.
Logic.Xor(FlagA, FlagB, FlagC)
```
]=]
function Logic.Xor(a: any, b: any, ...: any): boolean
local odd = (not not a) ~= (not not b)
for i = 1, select("#", ...) do
if local val = select(i, ...) then
odd = not odd
end
end
return odd
end
--[=[
@within Logic
@param a any
@param b any
@param ... any
@return boolean
Negated `Logic.And`, stopping at the first argument that is not set.
```lua
-- Blocked whenever the player is stunned, whatever else is true.
Logic.Nand(HasStatus(Stunned), HasInput)
```
]=]
function Logic.Nand(a: any, b: any, ...: any): boolean
return not Logic.And(a, b, ...)
end
--[=[
@within Logic
@param a any
@param b any
@param ... any
@return boolean
Negated `Logic.Or`, stopping at the first argument that is set.
```lua
-- Chat is blocked only when nothing at all is happening.
Logic.Nor(IsDead, IsJailed, IsMuted)
```
]=]
function Logic.Nor(a: any, b: any, ...: any): boolean
return not Logic.Or(a, b, ...)
end
--[=[
@within Logic
@param a any
@param b any
@param ... any
@return boolean
Negated `Logic.Xor`, so an even number of arguments read as set.
```lua
-- Both toggles agree with each other.
Logic.Xnor(IsMuted, IsHidden)
```
]=]
function Logic.Xnor(a: any, b: any, ...: any): boolean
return not Logic.Xor(a, b, ...)
end
--[=[
@within Logic
@param value any
@return boolean
`true` when `value` is `nil` or `false`. Same as `Logic.False`, named
for the gate.
```lua
if Logic.Not(leaderstats) then
WaitForStats()
end
```
]=]
function Logic.Not(value: any): boolean
return not value
end
--[=[
@within Logic
@param a any
@param b any
@return boolean
Reads as "if `a`, then `b`", so `true` unless `a` is set and `b` is not.
Same as `not a or b` but always returns a real `boolean`.
```lua
-- An admin skips the whitelist; everyone else has to be on it.
Logic.Implies(IsAdmin, IsWhitelisted)
-- "If the server is locked down, the event must be trusted too."
Logic.Implies(IsLockedDown, IsFromServer)
```
]=]
function Logic.Implies(a: any, b: any): boolean
return if a then not not b else true
end
--[=[
@within Logic
@param a any
@param b any
@return boolean
`true` when both arguments read the same way, so two set values and two
missing values both pass.
```lua
-- The client and the server agree on the mode.
Logic.Equiv(ClientMode, ServerMode)
```
]=]
function Logic.Equiv(a: any, b: any): boolean
return if a then not not b else not b
end
--[=[
@within Logic
@param ... any
@return number
How many arguments read as set.
```lua
-- Score how many hazard signals a room raises.
local danger = Logic.Count(IsDark, IsFoggy, IsNarrow)
```
]=]
function Logic.Count(...: any): number
local count = 0
for i = 1, select("#", ...) do
if local val = select(i, ...) then count += 1 end
end
return count
end
--[=[
@within Logic
@param needed number
@param ... any
@return boolean
`true` when at least `needed` arguments read as set, stopping as soon as
the count is reached. `needed` of 0 or less is always `true`.
```lua
-- Two of the three conditions make it a hard encounter.
Logic.AtLeast(2, IsDark, IsFoggy, IsNarrow)
-- A co-op difficulty that scales with the party.
Logic.AtLeast(4, PlayersAlive)
```
]=]
function Logic.AtLeast(needed: number, ...: any): boolean
if needed <= 0 then return true end
local count = 0
for i = 1, select("#", ...) do
if local val = select(i, ...) then
count += 1
if count >= needed then return true end
end
end
return false
end
--[=[
@within Logic
@param allowed number
@param ... any
@return boolean
`true` when at most `allowed` arguments read as set, returning as soon as
one too many is seen.
```lua
-- Stop stacking buffs once three are already on.
Logic.AtMost(3, HasBuff(Regen), HasBuff(Haste), HasBuff(Shield))
```
]=]
function Logic.AtMost(allowed: number, ...: any): boolean
local count = 0
for i = 1, select("#", ...) do
if local val = select(i, ...) then
count += 1
if count > allowed then return false end
end
end
return true
end
--[=[
@within Logic
@param predicate Predicate<A...>
@return Predicate<A...>
Logical inverse, keeping the original arguments. Lets a named check be
flipped at the call site without editing the original.
```lua
const IsReady = function(player) return player.Character ~= nil end
const IsDead = Logic.Negate(IsReady)
Network.On("hit", IsReady)
Network.On("leave", IsDead)
```
]=]
function Logic.Negate<A...>(predicate: Predicate<A...>): Predicate<A...>
return function(...: A...): boolean
return not predicate(...)
end
end
return Logic