This is a classic mistake. Let’s go over truthy and falsy values really quick.
We know the standard:
if true then
-- runs always
end
Of course there are logical operations we can use, and
, or
, and not
:
if true and true then
-- runs always
end
if not true or false then
-- runs never
end
This is great, but you might have seen something this:
local x = workspace:FindFirstChild("x")
if not x then
return
end
Or this:
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
local character = localPlayer.Character or localPlayer.CharacterAdded:Wait()
Or even this:
local text = name and name or "No Name"
This is because Luau has truthy and falsy values, i.e. values that act as if true
or as if false
when used in a boolean context. All values in Luau are truthy except false
and nil
, so when we look back at our examples they might make a bit more sense with this info:
local x = workspace:FindFirstChild("x") --> `Part?` (`Part | nil`)
--[[
`x` cannot be true or false, it can be `Part` or `nil`,
in this case, if it is `nil` (falsy) then `not x` will result
in `true` (`not falsy` is defined to be `true`)
]]
if not x then
-- we know here that `x` is `nil`
return
end
-- we know here that `x` is `Part`
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
-- we need a character here, but the character might not be there just yet.
--[[
in this case it is popular to use the below pattern which uses the truthiness
or falsiness of `localPlayer.Character` to *select* a value. it does not evaluate
to a boolean `true` or `false`. this also shows "short-circuiting" behaviour, in which
the expression completes evaluating when the result is guaranteed, for example
in `true or somethingElse` the expression can immediately evaluate to `true` by
virtue of `or` always being `true` if either of its operands are `true`, so `somethingElse`
is never evaluated, if it were a function call for example that function would never
be called. the same is the case for `false and somethingElse`, we know that `and` should
be `false` if either of its operands are `false`, so `somethingElse` need not be evaluated.
]]
local character =
localPlayer.Character or --> `Model?`; if truthy the expression evaluates to this
localPlayer.CharacterAdded:Wait() --> `Model`, evaluates if and only if falsy
--[[
we can see short-circuiting behaviour used in the form of a "ternary operator"
which selects between between 2 values based on a condition
]]
local text =
name and --> if `name` is falsy (`nil`) short circuits to `false` for the fallback case
name or --> if `name` is truthy (`string`) evaluates to `name`
"No Name" --> if `name` was falsy becomes `false or "No Name"` which evaluates to `"No Name"`
Note for the last example Luau has a built-in ternary operator called an if-then-else expression which is much more readable:
local text = if name then name else "No Name"
Note that if-then-else expressions can only have single expressions in their arms.
So in your case, day == 1 or 7
you either get true or 7
or false or 7
, which will always result in the truthy value 7
, in which case you get true and RSK ~= 6
, which is the same as RSK ~= 6
. The proper way to write what you intend to express is day == 1 or day == 7 and RSK ~= 6
.