Development / ROBLOX
Luau conditions: ordering if and elseif at progress thresholds
Select one understandable state from a completed-stage count. Learn branch priority, exact boundaries, independent if statements and a reproducible test matrix using original teaching data.
Define the states first #
Imagine a fictional ten-stage challenge. The teaching label needs four states: new at zero, started from one, halfway from five and complete from ten. These identifiers belong to our original example. Classifying a number does not confirm actual completion, award a badge or save progress.
Write the thresholds before writing code. At 5, both at-least-one and at-least-five conditions are true. Decide which state takes priority. A panel displaying one label needs a single selected state rather than competing messages. This agreement shows which checks belong earlier and what outputs the caller should expect.
Check the higher threshold first #
The first example, classifyProgress, checks 10, then 5, then 1. An if, elseif, else chain executes the first matching branch. Seven matches the five threshold, returning halfway without continuing to the lower threshold. Zero matches none, so the else branch handles it.
Run the sample independently and compare four lines: new, started, halfway, complete for 0, 1, 5 and 10. The inputs are deliberately small and known. These originals were actually executed in a standalone Luau interpreter. That verifies language behavior, not any Roblox player's state or a working progression system.
local function classifyProgress(count)
if count >= 10 then
return "complete"
elseif count >= 5 then
return "halfway"
elseif count >= 1 then
return "started"
else
return "new"
end
end
for _, count in {0, 1, 5, 10} do
print(classifyProgress(count))
endDiagnose reversed priority #
Putting count >= 1 first makes 10 select started. Later branches do not run, even though the completion condition is also true. The mistake is neither the number nor the >= comparison: it is branch priority. An earlier broad condition takes inputs that a later specific condition needs.
Record the input, all matching conditions and the first selected branch. Replacing the started label with complete does not repair the agreement: one stage would then count as completion too. Fix priority or redefine the states. Explicit non-overlapping ranges are useful when conditions cannot be arranged by specificity.
Compare independent if statements #
The second example uses count=7 and two independent if statements. Both match, so it prints started and halfway. A subsequent elseif chain on the same data prints halfway only. Separate if statements are evaluated independently; the chain chooses one branch.
Independent checks are appropriate for several compatible actions. A single teaching label normally needs an exclusive choice. Predict the message count before execution, then compare the actual count. Several if statements are not universally wrong: they are wrong only when they contradict the required behavior of this task.
local count = 7
if count >= 1 then
print("started")
end
if count >= 5 then
print("halfway")
end
if count >= 5 then
print("halfway")
elseif count >= 1 then
print("started")
endSeparate truthiness from comparison #
In Luau, zero and the empty string are truthy; false and nil are falsey. Consequently if count then does not test whether the first stage was reached. Our exercise needs an explicit numeric threshold, count >= 1, instead of testing whether a value exists.
Before classifying real inputs, separately verify that they are finite integers within the agreed range. These examples deliberately use known teaching numbers. They do not validate client-reported player progress. Do not silently interpret nil or a string as a new participant and later use that classification for rewards.
Test both sides of each threshold #
Prepare inputs 0, 1, 4, 5, 9 and 10. Expected states are new, started, started, halfway, halfway and complete. Check zero versus one for the first boundary, then the value immediately below each later threshold and the threshold itself. This catches accidentally using > instead of >=.
The assertion file additionally compares correct and reversed priority at ten and counts outputs from independent checks. It verifies this original exercise. Adding ranges or states requires updating the matrix: an earlier passing check does not prove new rules that were not tested.
Separate classification from display #
classifyProgress returns a technical identifier. Choose the visible localized label separately using that ID. A translation should not change thresholds. Keeping rules solely in button text risks giving the code and its translated label different meanings.
Document all four IDs and their meanings for handoff. Changing a label performs no game action. If a future state affects access, validate server rules separately. A visible complete string does not establish where the input came from and should not alone authorize a reward.
| Check | Expectation |
|---|---|
| 0 | new |
| 4 | started |
| 5 | halfway |
| 10 | complete |
Hand over rules and checks together #
Save threshold priority, permitted inputs, expected IDs and test values around every boundary. State whether the task needs one classification or several independent actions. Another developer can then reproduce the decision and understand why reordering conditions changes the result.
Add a future boundary to the matrix before modifying code, then check neighboring values and previous states. This remains pure Luau computation with no Roblox objects, networking, persistent storage or real completion. The useful outcome is a testable agreement for one selected state.
| Field | Record |
|---|---|
| Input | Known stage count |
| Priority | Higher threshold first |
| Result | One state ID |
| Checks | Both sides of boundaries |