05. Failure Checks
5.1 Limit single line Failable Expressions count to three
Limit conditional checks/failable expressions on a single line to a maximum of three.
if (Damage > 10, Player := FindRandomPlayer[], Player.GetFortCharacter[].IsAlive[]): EliminatePlayer(Player)
Use the form of
if
with parentheses()
when the number of conditions is less than three.Do:
if (Damage > 10, Player := FindRandomPlayer[]): EliminatePlayer(Player)
Don't:
if: Damage > 10 Player := FindRandomPlayer[] then: EliminatePlayer(Player)
It is essential to avoid splits code over multiple lines
If using more than two words for each expression, a maximum of two expressions on a single line is often more readable.
if (Player := FindAlivePlayer[GetPlayspace().GetPlayers()], Team := FindEmptyTeam[GetPlayspace().GetTeamCollection().GetTeams()]): AddPlayerToTeam(Player, Team)
You can also apply the rule as in a failure context on a single line, don't use more than nine words. When over the limit, use the spaced, multiline form.
Evaluate whether grouping multiple failable conditions into a single
<decides>
function would make the code easier to read and reuse. Note that if the code is only ever used in one place, a "section" comment without an ad hoc function can suffice.if: Player := FindRandomPlayer[] IsAlive[Player] not IsInvulnerable[Player] Character := Player.GetFortCharacter[] Character.GetHealth < 10 then: EliminatePlayer(Player)
Should be rewritten as:
GetRandomPlayerToEliminate()<decides><transacts>:player= Player := FindRandomPlayer[] IsAlive[Player] not IsInvulnerable[Player] Character := Player.GetFortCharacter[] Character.GetHealth < 10 Player if (Player := GetRandomPlayerToEliminate[]): Eliminate(Player)
The same guideline applies to expressions in
for
loops. For example:set Lights = for (ActorIndex -> TaggedActor : TaggedActors, LightDevice := customizable_light_device[TaggedActor], ShouldLightBeOn := LightsState[ActorIndex]): Logger.Print("Adding Light at index {ActorIndex} with State:{if (ShouldLightBeOn?) then "On" else "Off"}") if (ShouldLightBeOn?) then LightDevice.TurnOn() else LightDevice.TurnOff() LightDevice
Should be rewritten as:
set Lights = for: ActorIndex -> TaggedActor : TaggedActors LightDevice := customizable_light_device[TaggedActor] ShouldLightBeOn := LightsState[ActorIndex] do: if (ShouldLightBeOn?) then LightDevice.TurnOn() else LightDevice.TurnOff() LightDevice
5.2 Group Dependent Failure Expressions together
When a condition in a failure context depends on a previous failure context succeeding, keep the two conditions together in the same failure context when possible, and follow guideline 5.1.
This improves code locality, which simplifies logical understanding and debugging.
Do
EliminatingCharacter := EliminationResult.EliminatingCharacter if (FortCharacter := EliminatingCharacter?, EliminatingAgent := FortCharacter.GetAgent[]): GrantNextWeapon(EliminatingAgent)
Do
if: FortCharacter := Player.GetFortCharacter[] set AgentMap[Player] = 1 FirstItemGranter:item_granter_device = ItemGranters[0] then: FortCharacter.EliminatedEvent().Subscribe(OnPlayerEliminated) FirstItemGranter.GrantItem(Player)
It’s acceptable to split failure contexts if you handle each potential failure (or failure groups) separately.
if (Player := FindPlayer[]): if (Player.IsVulnerable[]?): EliminatePlayer(Player) else: Print("Player is invulnerable, can’t eliminate.") else: Print("Can’t find player. This is a setup error.")
Was this helpful?