Limiting numbers of active triggers

by Lendren

Back to Mechanic's Corner.

Lendren2008-01-10 17:51:27
My homebrew zMUD system is getting to where it misses things because I have too many triggers, and I still have lots of combat system triggers still to add. I've been aggressively pursuing ways to eliminate triggers or disable them when they're not needed, but I'm not sure if I'll get enough capacity out of that to cover all the combat system triggers I still have to add. And I'm not ready to make the cMUD transition just yet.

How do you make it so triggers for certain types of attacks or afflictions only are enabled when those attacks are possible? While still being ready to start curing immediately if someone ganks you, and being able to handle group fighting.

It seems like most attack lines that can cause afflictions that need curing can happen at any time. Very few are the triggers where you have a common introductory line and a bunch of varying following lines which actually tell you what happened, so those can be disabled except when they follow the single trigger of the first line. Usually the first line you see is already the one that tells your system something it needs to know -- so that line has to be active all the time, doesn't it?

I'm not looking for code, just for tips and overall approach methodologies. Thanks.
Unknown2008-01-10 17:56:45
A few things I've done and seen done:

Bashing - if you have triggers/aliases/attack lines that are bashing-specific, make them toggleable.

Class - Certain attack lines are limited by class. If you know your opponent's class and can disable the other attack line triggers, that can help. Make sure you include an "All" option for enabling.

Unknown2008-01-10 18:02:59
Sorry for the double post, but also, the performance hit comes from all active listeners, so that includes aliases, too. Streamlining your aliases and enabling/disabling them (such as bashing aliases, etc.) will also help your trigger performance.
Unknown2008-01-10 18:05:07
In my experience, the number of triggers isn't the major bottleneck in zMUD. The bigger problem is how much code you're executing on a regular basis. Many people have large healing aliases that are called quite often, whether on demand, on the prompt, or even on a timer. Limiting what gets evaluated each time they're called can get you a good deal of speed and reliability back. For example, skip the check for eating an herb unless you know you've been given an affliction that an herb could heal (i.e., set a variable flag and unset it when you check the herb healing queue).

Multi-state triggers can also make things more efficient, as only one state of the trigger is active at a time. They're sort of link mini finite state machines, if you do them right.
Lendren2008-01-10 20:02:00
The reason I suspect triggers is that everything was fine until I added about 20-30 new triggers for Ninjakari. But it's certainly worthwhile to look for aliases I can shed too.

I'm already doing a lot to limit the code executed, particularly in often-run things like the prompt trigger. It's a constant struggle between making it smarter and exceeding zMUD's capabilities. I could do another sweep for efficiencies, but short of removing functionality, I doubt there's really that much to be gotten.

Incidentally, how much of an improvement is to be had in cMUD in this regard, all other things being equal? I can see just having a few slightly smarter loop and conditional structures could make a huge difference, and I've heard cMUD is just generally more efficient across the board.
Unknown2008-01-11 13:53:21
CMUD is definitely faster overall because of several improvements made to the engine. It has a completely new script engine that now compiles scripts into more efficient byte code. It finally uses real array and hashtable data structures for storing string lists and data record variables now, too, which makes them 100 times more efficient than before (when they were all stored internally as strings). It's multithreaded now, too, and that has a pretty big impact, though it can make some of the more complex scripts even more complicated than they were previously.
Lendren2008-01-21 02:53:53
Though I have optimized my central loops before, I managed to dig through and find a few more optimizations that made a fair difference. It was surprising how much slower two #add commands are than one complicated nested %eval() with %if()s in it; it seems there's an overhead per line of code that's a bigger proportion of the processing time than you'd expect.

I'm still not sure how to really make effective use of multistate triggers, though. At first, I thought I could combine a number of triggers together like this. All the Music affliction lines, like "As the whispers enter your mind, a sinking feeling drops into the pit of your stomach." should only occur after a line in which someone plays an instrument at you. So I figured you make the first line in a multistate trigger be a general pattern of someone playing an instrument, then the following lines be the various Music afflictions, each a Within|Param=1. But if only one of them is active at a time, this won't work, will it? You'd still need one trigger per affliction line, and all you'd gain is a bit of illusion protection. And then most attacks you can't even use this for illusion protection because there isn't a previous line you can count on.

So while I can see uses for multistate triggers in lots of places, I am not seeing much use for them in the specific area of concern, affliction trigger lines. Am I missing something?