I was reading through the source code for the auto sipper in the HTML5 client to figure out how it works, and came across some of the match criteria in there:
/^Your mind feels stronger and more alert\.$/gm
I'm just wondering why the extra symbols are required for the string, since I've never dealt with regex before
.
Comments
\ are an escape in regex to tell the regex to ignore this character as regex code. In regex the period [.] is a wildcard that can match anything. So you have to escape it [\.] in order to tell the regex that this is a period, not a "match any one character".
I assume the initial / and /gm were your adding, because I don't recognize their importance in regex, nor see any reason why they'd be added.
When Canada rules the world,
things will be... nii~ice.
The g and m at the end (after the second /) are regular expression flags; in particular, they're the global and multi-line flags respectively. This page has a brief explanation of what they do at the bottom: http://www.javascriptkit.com/javatutors/redev.shtml
Results of disembowel testing | Knight limb counter | GMCP AB files
You eat an aurum flake.
The mineral has no effect.
Is there a way to match this all in entirety, or can you only match it line by line despite being part of the same message?
Although different clients may have a better way, or have certain quirks with multiline triggers. I'm not sure if this is recommended for the HTML5 client.
I've noticed for mudlet people use the matches[2] or matches[3] command to find stuff in the regex text. Does it only match things placed in brackets, or how does it work? For HTML5 it looks like we use args[2] and args[3] instead, but from the looks it follows the same matching principles.
Say you have something like:
/(\w+) sends strands of sticky web flying at you as (he|she) touches (\w+) web tattoo\./
Would matches[1] be the first (\w+), matches[2] be the (he|she) and matches[3] be the second (\w+)?
ETA: Can you show an example for the trigger not firing when you escape the period?
GMCP documentation: https://github.com/keneanung/GMCPAdditions
svof github site: https://github.com/svof/svof and documentation at https://svof.github.io/svof
Results of disembowel testing | Knight limb counter | GMCP AB files
This trigger works: ^(\w+)\'s aura of weapons rebounding disappears.$
This one does not: ^(\w+)\'s aura of weapons rebounding disappears\.$
And for an example of a "regular" one that works with the escape at the end: ^Your aim augments the flight of your arrow\.$
I really feel I've seen this before, and my guess/intuition is that it has something to do with capturing stuff right after the newline thing. It's the kind of thing that drives someone not immersed in coding absolutely nuts.
What does the trigger do? Unlikely to be the cause of the problem, but any details might help.
Results of disembowel testing | Knight limb counter | GMCP AB files
You can use this to check your regex by the way:
http://regexpal.com/
Just copy and paste ^(\w+)\'s aura of weapons rebounding disappears\.$ into the top box and "Tael's aura of weapons rebounding disappears." into the second box. If it highlights, you know your regex captures that pattern.
I'm a little suprised that nobody has linked a reference, which is usually the first and last thing you'll need when learning and working with regex (although of course feel free to ask here or the mudlet and/or HTML5 clans (assuming one exists by now)).
Here is the MSDN regex pattern matching standard which does have a few exceptions with both Mudlet and the HTML5 client, which I don't have a solid list of, but are either advanced to the point that you likely won't encounter them, or have simple and commonly used substitutions.
One of the major things to note is that both clients handle pattern matching one line at a time. Even for multi-line messages that are typically sent "together" - since MUDS use Telnet (a data transmission protocol) these lines are still in actuality sent as seperate lines (but are sent together from the game before a prompt is sent, creating the "illusion" that they are in fact a single message).
What this means is that while "actual" regex can match multiple lines, or in fact, full pages, of text, this isn't really possible in a MUD, since (in all clients I've ever heard of), regex pattern matching is executed on each line sent from the game server completely independently.
While it is actually possible to circumvent this via complex workaround, it is far from wise to actually do this (and nobody does) due to much more simple methods of handling multi-line triggers generally being built into MUD clients.
In Mudlet's case, there are actually quite a few simple methods, the most simple of which being a basic multi-line trigger (which executes a boolean AND or OR statement based on the result of the last X (a number you specify) lines sent from the game. AND or OR is simply specified by selecting "Multiline / AND Trigger" in Mudlet's editor, for example.
In no way is it possible to match two separate lines* from the game in a single regex pattern, since Mudlet never evaluates more than a single line from the game at a time against all of your triggers (unless of course, you specifically tell it to in a script, by combining the two or more lines into a single actual string, then comparing that single string to your regex pattern, which would be one of the aforementioned workarounds).
Another simple, built-in method (again, in mudlet, but similar in other clients) is use of Filters, which work in a similar, but slightly different way (see the manual or PM me for more detail).
Yet another method (which is actually frequently the best/only option) is simply using multiple different triggers that use "flags" (a boolean value, usually).
ex:
Trigger 1: You eat an aurum flake.
Trigger 2: The mineral has no effect.
Trigger 3: <any prompt>
In trigger 1, you set a "flag" to true. In trigger 2, if the flag is true, then execute your actual code you want to run. Trigger 3 (a prompt) would set the flag back to false, if you only wanted the code to run if both lines have been sequentially received. This is a less efficient, but far more flexible and powerful method (as more complicated examples can do much more tricky things, such as handling things that might be in the middle of a multi-line trigger, like a Parry or the third-person paralysis message between slashes when you DSL someone with Curare, etc). [ In actuality, this is exactly what Mudlet does behind the scences for Multiline and filter type triggers, and is markedly more efficient. However, in some cases, they simply won't get the job done, which is when you'd do something like this yourself. ]
Another good reference for triggers in general would be Mudlet's tutorial on them, even if you're using HTML5, because it covers the core concepts of creating triggers, filters, trigger chains, etc, which are essentially identical, but with slightly different syntax, and a different editor. There's a video, as well.
This is a good example of the common misconception that I was referring to above. This would actually not work, in any client that I am aware of, since at no point would Mudlet ever actually evaluate the entire pattern (both lines) together, as they are received as two completely independent messages from the game.
This makes sense if you think about it, because for a MUD client to actually catch multi-line messages in a single regex pattern, it would constantly have to evaluate every single possible combination of every line in the entire buffer.
If you wanted to match the multi-line trigger:
test
test
test
test
test
for example, that would require that your client check the current line for any regex matches, then also and independently compare the current line AND the previous line against all of your triggers, then check all three of the last lines against all of your triggers, and so on, until the sixth repetition. Theoretically, it would have to do this for every line received, all the way back to the top of your buffer (a setting that is virtually infinite if you choose). You can probably see how within even a few seconds, this gets exponentially more taxing, and thus slow, for your CPU.
Thus, it simply doesn't work that way.
However, one exception to this exception that's worth mentioning is word wrap. Both Achaea and most MUD clients (including Telnet client itself) perform word wrap. It is highly advisable to disable Achaea's word wrap setting (config screenwidth 0) so that it doesn't send arbitrary newlines ("\n") to your client. This can make multi-line patterns a nightmare.
Simply set your client's word wrap to whatever you wish, and it will not add in or evaluate any newlines in long patterns (such as a long sentence, attack, or paragraph, in Achaea), even if it does display them for readability.
It is vital and at first a bit tricky to understand the difference between word wrap and actual newlines, however.
Example:
Word wrap (in my client) inserted a newline between "of" and "Gerwulf", however since I have Achaea's word wrap disabled, the entire line was actually sent, received, and evaluated as a single line. The only actual "newline" in this text would be after "Gerwulf." before "You see".
Thus, you see three lines, but it is actually two distinct lines. You can tell when this is happening by resizing your window (in some clients) to see if it moves the "fake" newline around. Some clients also allow you to show special characters (such as newlines) for coding purposes.
If in doubt, you can also see the "real" lines received in debugger and log files. Typically, in these, each "line" received by your client will appear in a separate message.
If I overdid it, sorry, but multi-line triggers are a really common and particularly tricky obstacle for most people getting into MUD scripting, and I'm overshooting it a bit in hopes that it'll help others who run into it in the future. .. and of course, if you have any further questions, feel free to ask here or in game.
It did work in zMud, which was probably the most mind-shattering thing for me to come to realize when I switched to Mudlet. This never made the Mudlet: Migrating page, although is arguably the most important difference when switching over, aside from the actual scripting language.
This is from the zMud Manual regarding using newlines ($) in zMud triggers: (note: it was preceded by a paragraph describing two "better" methods of creating multi-line triggers - primarily the use of #COND
The reason this (this is pure conjecture) probably was allowed in zMud was that at the time, typical buffers were much smaller, and when it was developed, the fact that people would ultimately be generating hundreds, or even thousands, of regex patterns (triggers) that would need evaluated, was probably not fully anticipated (or at least, the impact of this kind of pattern matching was not foreseen).
(It's probably not a coincidence that zMUD's replacement began in the years immediately following the emergence/prevalence of complex systems like ACP & Acropolis - particularly since zuggsoft's clients (and Mudlet) are both specifically designed for use with IRE games.)
zMud was famous for getting really slow with big systems, which was why this method was depreciated, and ultimately, why it was replaced by cMUD (which also did not allow this syntax).
On the other side I have no good reference for PCRE on hand either
GMCP documentation: https://github.com/keneanung/GMCPAdditions
svof github site: https://github.com/svof/svof and documentation at https://svof.github.io/svof
Yeah, but you'll never really encounter any of the differences, because they aren't applicable to MUD triggers - for the most part. The exceptions that are noteworthy are relatively obvious.
It's also not that hard to simply learn it by sifting through the ample existing mudlet (or HTML5) systems floating around, and referencing things when you simply can't figure it out from context.
Another way to deal with multi-line stuff is to enable/disable triggers/groups (trigger for first line enables trigger for second line, trigger for second line disables itself*), which is effectively what a filter does - but it's useful to think about it that way if you ever use another client like the HTML5 client that doesn't have explicit filters.
In Mudlet, you can also dynamically generate the second trigger with a temp trigger defined in the script for the first trigger, which I've seen a lot of people do. Technically that's slower, but in practice it's unlikely to ever matter much unless you're generating a ton of them at once for something.
*This doesn't totally work if there's a delay between line 1 and line 2. In that case, you might end up with two line 1s, both enable the trigger, then the first line 2 disables it and nothing fires on the second line 2. You have to build in some sort of counter variable to get around that (so first trigger enables second trigger and increments the counter, second trigger fires and decrements the counter, disabling itself if the counter is 0).
http://codecombat.com/
http://www.gammon.com.au/mushclient/regexp.htm
http://mushclient.com/pcre/pcrepattern.html
Site: https://github.com/trevize-achaea/scripts/releases
Thread: http://forums.achaea.com/discussion/4064/trevizes-scripts
Latest update: 9/26/2015 better character name handling in GoldTracker, separation of script and settings, addition of gold report and gold distribute aliases.
Svof
Mudlet Discord join up