[ZScript] Use Stats Wisely! Optimizing iterators!

Handy guides on how to do things, written by users for users.

Moderators: GZDoom Developers, Raze Developers

Forum rules
Please don't start threads here asking for help. This forum is not for requesting guides, only for posting them. If you need help, the Editing forum is for you.
Post Reply
User avatar
Major Cooke
Posts: 8170
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

[ZScript] Use Stats Wisely! Optimizing iterators!

Post by Major Cooke »

This assumes you're fairly intimate with ThinkerIterators at the very least.

Did you know that stat numbers are a handy way to change what iterator a thinker can be within?

It's easy! ChangeStatNum(int num);

Why?
Read up on thinkers here first to understand what it's all about. The above function will remove the thinker from the array it's currently within and place it in the one you specify -- meaning iterator searches are affected by it based on the stat number you pass it.

Because let's face it, there are going to be maps where there are a literal fuckton of actors/thinkers. Effects-heavy mods that often do a lot of actor searching are going to be a liability for causing slowdowns because, you guessed it, they're doing a lot of their searching in every array.

Think about it for a moment, every search is going through a GIANT LIST OF THINKERS whenever one creates a ThinkerIterator with the default parameters. In ZScript, this compounds the amount of code executions and comparisons of certain properties the modder has specified for every single thinker in that list.

Now, what if you want to search for thinkers on different stat numbers? Easy, just change the ThinkerIterator's stat number and presto! By default, ThinkerIterator defaults to searching through what looks like every single thinker array (uses 128 by default, which I assume means check them all -- it would explain why inventory sometimes crops up).

WARNING
Do not use ranges below 32 unless the actors are meant to be purely static, because they will not operate by themselves. Their tick functions don't operate normally, but this can be useful for saving pointless tick processing that you normally wouldn't need otherwise.

If you need more stat thinkers, the only thing I can recommend is suggesting it.

I hope this alleviates ailments some mods may suffer through. Any and all information here is, of course, subject to Graf's corrrections and will be changed according to his specifications.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49056
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: [ZScript] Use Stats Wisely! Optimizing iterators!

Post by Graf Zahl »

What's impoprtant here: Do NOT use this if you do not know what changing these numbers implies! Stat numbers are primarily for prioritizing thinker execution order, not for optimizing iterators! That is merely a side effect of how they work.
Right now there is no guaranteed range of user-reserved numbers so you may be shooting yourself in the foot by arbitrarily assigning a free number to your thinker.
User avatar
Major Cooke
Posts: 8170
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: [ZScript] Use Stats Wisely! Optimizing iterators!

Post by Major Cooke »

Code: Select all

class ThinkerIterator : Object native
{
	native static ThinkerIterator Create(class<Object> type = "Actor", int statnum=Thinker.MAX_STATNUM+1);
	native Thinker Next(bool exact = false);
	native void Reinit();
}
Graf, I've looked over the Next() code found within here, and on the source side, it's designed not to advance through the list of other stat numbers if the iterator is created with a listed stat number, thus cutting down on time spent going through it. I fail to see how this is not an optimization. Though I probably should've been a little more thorough, I admit.

Code: Select all

ThinkerIterator it = ThinkerIterator.Create("Actor", STAT_SPECIALFX);
Granted there is that user range problem, but that's a different problem altogether.

Also for everyone else:
Spoiler: A note on constants
User avatar
Major Cooke
Posts: 8170
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: [ZScript] Use Stats Wisely! Optimizing iterators!

Post by Major Cooke »

Ah, there is yet another way to optimize iterators for normal situations.

By default, the iterators are set to search through all thinking stat numbers. Here's a tip for everyone:

If you just want to get regular actors and you don't need anything special, set your iterators' statnum to search at STAT_DEFAULT. Otherwise, it'll default to searching every single one of them, such as inventory items you own, ACS thinkers, quakes, and more. This can definitely save time especially if monsters/players have a lot of owned inventory.

Any item that is successfully picked up will automatically change its stat number to STAT_INVENTORY, while items that are dropped/spawned will revert back to STAT_DEFAULT.

This explains why the CustomInventory's states take precedence. Nice!
User avatar
Major Cooke
Posts: 8170
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: [ZScript] Use Stats Wisely! Optimizing iterators!

Post by Major Cooke »

Oh and one last thing to note: You can only change the stat number in BeginPlay. If you try to do it in PostBeginPlay or in states, the game will abort stating the actor's already ticked more than once.
Post Reply

Return to “Tutorials”