For

From EDukeWiki
Jump to navigation Jump to search

for <gamevar> <iterator> { [...] }
for <gamevar> <iterator> <value> { [...] }

Executes the code in the curly braces for every instance of the iterator specified. The <gamevar> specified will be set to the index (sprite/sector/wall/etc) for that iteration of execution. (In math, this is called the induction variable.)

For example, specifying <iterator> as allsprites will run the code for every sprite in the game world, and <gamevar> will be set to the ID number of one particular sprite when it gets its turn.

Iterators

allsprites All actors/sprites in-game.
allsectors All sectors in the map.
allwalls All walls in the map.
activelights
lights
All active Polymer lights.
drawnsprites Only the sprites currently being drawn.
spritesofsector <sectnum>
sprofsec <sectnum>
All sprites in the given sector.
spritesofstatus <statnum>
sprofstat <statnum>
All sprites with the given statnum.
wallsofsector <sectnum>
walofsec <sectnum>
The walls of the given sector.
loopofwall <wallnum> All walls in the same loop of the given wall.
range <num> Every integer starting at 0, up to but not including the number specified.

Notes

Unlike other loop forms, the implementation keeps its own internal copy of the induction variable, so if <gamevar> is modified in the loop body, the next iteration will take place as if it had not been changed. Similarly, the conditional statement is not re-evaluated each iteration. For example, the following loop will log 1 through 10:

var i
var j 10

for i range j
{
    add i 1 // interpret value as 1..10 instead of 0..9
    al i // write value to the log file

    set j 99999 // useless but harmless operation for demonstration purposes
}

These factors combined make for loops safer than whilevarn to use in CON, because it avoids accidentally clobbering the gamevars in states that are called, or events that run during operations performed (such as EVENT_SPAWN during spawn).

For loops are also strongly preferable for performance reasons. Most users only need to remember that fact, but the technical explanation for those interested is that the loop is implemented as an actual for loop in EDuke32's C++ code, where the induction variable and iteration condition are ordinary local variables on the call stack. In contrast, whilevarn takes place on the level of commands in the CON interpreter, jumping around locations in the compiled bytecode and operating naively on gamevars. The former paradigm is faster because does not have to load and store the gamevar's value to/from memory for every iteration, which places stress on the data cache and could stall due to RAM access delays, and also because CPU branch prediction will be more effective when the meaning of the loop is more plainly stated to the compiler and in the resulting machine code.