Trigger on Last Received Prompt

Posted by Dk on Tue 02 Dec 2003 12:31 PM — 5 posts, 17,298 views.

#0
I'm curious if this is specific to the MUD I've been playing or not, but it seems as though after an action (ie, look), the prompt -following- the look command is not triggered on until after another command is entered.

I decided to create an info-based health bar (which turns out to be awfully similar to the one I later found here as a plug-in!), but the problem is that the trigger matching the prompt doesn't execute until something happens after the prompt, whether it's a new line sent from me or to me (or, curiously, a world.note is sent).

This issue of the notes causing it to recognize the trigger tend to make me thing it's a client-side issue, but if anyone has any insight on this matter/workarounds you've come up with, please let me know!

Thanks,
dk
Amended on Tue 02 Dec 2003 12:33 PM by Dk
USA #1
Nope, its not clientside. The Mud doesnt send a newline after the prompt, and therefore triggers arent evaluated.

There are a few workarounds provided in the forums, ranging from changing your prompt to include a newline, to running a timer to get the info without the newline (youll see what Im talking about).

Do some searching in the forums, youll get a million posts about it.
USA #2
Actually it is both a client issue and a mud issue, but mostly a telnet issue. Since there is no way to identify a prompt (i.e. no special code or the like) the client has no way of knowing that one has arrived. It can therefor handle lines in one of two ways. 1) process each character as it arrives until it hits a newline or matches something OR 2) process only after a newline has been found.

Now the problem with solution 2, as you noticed, is that prompts that don't include a newline are ignored until something happens. This can be a major pain, but is imho better than the alternative.

Solution one would work like this:

Triggers:
abc
abcf
abcg
abcq
123*

If the line recieved = "1234", then the first attempt to match "1" will fail on all but the fifth trigger and it would continure to test each character against that one until it hit the *, then trigger. This is 9 total tests before a match. If the line is something like "abcj" then it will only ignore the last trigger after the first pass, but retest all 4 others, until it fails. This is a total of 16 tests, nearly twice as much time wasted just ot find out it failed. Now, worst case senario, you have 100 triggers that 'could' match either on of off the prompt, so you make all the triggers like:

*abc
*abcf
*abcg
*abcq
*123*

Now it 'must' test every line against all 100 triggers, until it literally runs out of character to test, though you could subtract the length of 'real' characters in the trigger to make it smaller (4 in this case). I have no idea what the result would be, but the number would be big enough to create major lag. This obviously isn't a good idea, so mushclient takes the other option and simply delays until it is sure it has an entire line to test against.

Of course since lines arrive in packets, the above is unlikely to ever happen, instead what most clients probably use is testing each packet as it arrives, so if the packet includes a complete line, then great, if not some triggers can still match, but others will only match when the newline arrives. Ironically, the way mushclient allows you to sequence triggers means that this probably wouldn't work, since you can create a triggers like:

* says: Hi! -> sequence 10
* says: * -> sequence 20

this means that if the first one matched, then the second one will be ignored, unless you specifically allow other triggers to match it. Most client would either attempt to match both or automatically exclude the second trigger, the line having already matched. If mushclient used this method, then it is possible that by pure chance the line would arrive in two packets like:

Packet 1 -> "Fred says: "
Packet 2 -> "Hi!"

This would match the first time through on the second trigger, since it uses *, but the *intended* result would have been for the first trigger to catch it and the second trigger to be ignored. Ooops!

I am not sure actually that this shouldn't be how it is done. Using Regular Expressions and the $ character or even adding a setting for "Only match with newline" to the triggers would allow you to avoid this trap, while still allowing partial lines to match for triggers that don't explicitly require a newline. The only issue being that this would change the default behavior, so the setting would need to be "Match without newline" and a $ in a regular expression would automatically override it. That way the default behaviour would still be the way it currently works. This means that at most, some triggers may be tested both when a packet is decoded and when the newline it recieved, but most would still only be tested once at the newline. This doesn't correct the artificial newline effect from world.note and the like, which is a pain in the rear, but it rarely causes a problem and the best advice I can give is to avoid to many timers that dump notes into the middle of stuff that you need to trigger on.

Frankly I need to take my own advice, but coding the gadget to displace the problem outside of Mushclient is only one of a half dozen projects I have sitting on the back burner... :(

In any case, as Flannel said, the possible solutions are there on the forums someplace. ;)
Amended on Tue 02 Dec 2003 09:16 PM by Shadowfyr
#3
Ah, thank you.. I ended up using with a mud-side carriage return upon your suggestion..for the life of me, I couldn't seem to come up with that, lol!
However, I did try something similar with timers, but I didn't think I really wanted a timer running every second.

Thanks again!
dk
Australia Forum Administrator #4
The timer every second wouldn't use much resource, however changing the MUD prompt is the simple solution.