Control Flow
Quest (if / else if / else)
Section titled “Quest (if / else if / else)”The Quest is RuneLang’s conditional branching construct.
Quest begins when (health > 50) Chant("Still standing strong!");elsewise when (health > 0) Chant("Wounded but fighting!");elsewise Chant("Fallen in battle...");end of QuestEach branch is guarded by when (condition). The elsewise branch at the end catches everything else. Both elsewise when and the final elsewise are optional.
// minimal quest - just one branchQuest begins when (is_poisoned) Chant("You feel the venom spreading...");end of QuestNested quests
Section titled “Nested quests”Quests can be nested freely:
Quest begins when (player.isAlive()) Quest begins when (enemy.isAlive()) Chant("The battle continues!"); elsewise Chant("Enemy defeated!"); end of Questelsewise Chant("Game over.");end of QuestOdyssey (for loop)
Section titled “Odyssey (for loop)”The Odyssey is a counted loop, iterating from a start value to an end value (exclusive).
Range-based
Section titled “Range-based”// prints 0, 1, 2, 3, 4Odyssey for i from 0 to 5 is Chant(i);end of OdysseyThe end value is exclusive — from 0 to 5 runs for 0, 1, 2, 3, 4.
With step
Section titled “With step”Use by to set the step size:
// prints 0, 2, 4, 6, 8Odyssey for i from 0 to 10 by 2 is Chant(i);end of Odyssey
// counting backwardsOdyssey for i from 10 to 0 by -1 is Chant(i);end of OdysseyFor-each
Section titled “For-each”Iterate over a collection with in:
Scroll party is ["Gandalf", "Frodo", "Aragorn"];
Odyssey for hero in party is Chant(" " + hero + " joins the quest!");end of OdysseyWorks with strings (iterates over characters), Scrolls (arrays), and Tomes (iterates over [key, value] pairs):
// iterate over charactersOdyssey for ch in "hello" is Chant(ch);end of Odyssey
// iterate over tome entriesTome stats is {"str": 18, "dex": 14};Odyssey for entry in stats is Chant(entry); // prints ["str", 18] then ["dex", 14]end of OdysseyVigil (while loop)
Section titled “Vigil (while loop)”The Vigil loops while a condition remains true.
Mutable Countstone arrows is 5;
Vigil whilst arrows > 0 is Chant("*fires arrow* (" + arrows + " remaining)"); arrows is written as arrows - 1;end of VigilOracle (pattern matching)
Section titled “Oracle (pattern matching)”The Oracle is RuneLang’s pattern matching construct, similar to switch/case or match.
Countstone roll is Roll(1, 20);
Oracle reveals (roll) fate 1: Chant("Critical failure!"); fate 20: Chant("CRITICAL HIT!"); fate 10: Chant("Solid hit."); elsewise: Chant("You rolled a " + roll);end of OracleEach fate matches a specific value. The elsewise clause handles any unmatched values.
Multiple statements can follow a fate:
Oracle reveals (player_class) fate "warrior": Chant("You draw your sword."); damage is written as damage + 5; fate "mage": Chant("You prepare a spell."); damage is written as damage + 10; fate "rogue": Chant("You strike from the shadows."); damage is written as damage + 7; elsewise: Chant("Unknown class.");end of OracleFlee and Persist
Section titled “Flee and Persist”Flee breaks out of a loop. Persist skips to the next iteration.
Odyssey for i from 0 to 100 is Quest begins when (i % 2 matches 0) Persist; // skip even numbers end of Quest
Quest begins when (i > 10) Flee; // stop after 10 end of Quest
Chant(i); // prints 1, 3, 5, 7, 9end of OdysseyBoth work inside Odyssey and Vigil loops.