Going from zMud 6.62 to Mushclient...

Posted by Ledneh on Sun 08 Feb 2004 07:50 PM — 20 posts, 79,427 views.

USA #0
Well, in zMud, I have what can only be described as a metric ****ton of triggers, aliases, variables, and whatnot. None of them use any particularly specific functionality--the only two I can think of are classes and triggering on the contents of a variable.

I'd like to try Mushclient, see if it's faster and/or easier to maintain on my machine than zMud, but in order to do a proper test, I'd have to move every setting from zMud to Mushclient--all the triggers, aliases, variables, everything. That would be pure murder manually, so I ask: is there any sort of conversion routine out there?
Australia Forum Administrator #1

There isn't yet, there is a forum post about doing it manually - see ex-zmud user needs trigger conversion. The problem with automating the process it that the syntaxes are somewhat different, and the commands.

However, the question is, do you have lots of (completely) different triggers, aliases, etc. or are they all rather similar, but with different stuff in them? If they follow a general format it might be possible to automate the bulk of it. Then, the remaining harder ones could be done manually (if any).

For one thing, a useful tool would be a regular expression converter. zMUD's regular expression matching is different from MUSHclient's - MUSHclient uses a standard library PCRE (Perl-Compatible Regular Expressions) which also happen to be completely compatible with the regular expression object available in VBscript (and other script languages).

However the zMUD regular expressions look different, here is a sample from their documentation:

zMUD

* match any number of characters or white space
? match a single character
%d match any number of digits (0-9)
%n match a number that starts with a + or - sign
%w match any number of alpha characters (a-z) (a word)
%a match any number of alphanumeric characters (a-z,0-9)
%s match any amount of white space (spaces, tabs)
%x match any amount of non-white space

Now to look at the same things in MUSHclient (and PCRE/VBscript):

MUSHclient

.* match any number of characters or white space
. match a single character
\d* match any number of digits (0-9)
[+-]\d* match a number that starts with a + or - sign
[[:alpha:]]* match any number of alpha characters (a-z) (a word)
[[:alnum:]]* match any number of alphanumeric characters (a-z,0-9)
\s* match any amount of white space (spaces, tabs)
\S* match any amount of non-white space

The above examples assume "any number" means "zero or more". However if "any number" means "any non-zero number" then you would change the "*" to a "+". (eg, one or more spaces would be "\s+").

The Perl-Compatible regular expression syntax allows other ways of doing things, so the above table is not the only way. For example, you can express numbers as "[0-9]" and letters as "[a-zA-Z]". You also have more control over the concept of "any number". For instance, you could look for a 1 to 3-digit number like this: "[0-9]{1,3}", or a number that is exactly 4 digits like this: "[0-9]{4}".

If you like, post here, or email me, some example triggers/aliases etc. and I can see how easy it would be to do a converter for them.

Amended on Sun 08 Feb 2004 09:13 PM by Nick Gammon
USA #2
Thanks, Nick, I appreciate the support.

Sadly, not all of the triggers do the same sort of thing. There are certain identifiable groups of triggers that all do the same thing for different messages, but those don't make the majority of my settings, unfortunately.

As soon as I get to my computer, I'll post some samples that I think are representative (I won't post the whole thing--a friend wrote much of it for me, and he'd rather not see his work distributed). In the meantime, though, here's the gist.

It's a combat system for (the seemingly omni-present) Achaea. Generally speaking, most triggers simply set a flag for something to be done in the near future (specifically, when it becomes possible for my character to react); a once-per-second tick timer checks some of these flags and acts upon them, but most things are done "when I'm able." I'm sure you've at least heard of how Achaea works, so I won't go on.

In summary, none of the triggers, aliases, etc. are actually very complex; it's more that there's a lot of them, and they all work in tandem.

I'll post some examples ASAP.
USA #3
Okay, here's a good one.

TRIGGER:
"Don't get trapped now...", the bubonis entity whispers to you.

VALUE:
#CW White
CureAdd set_claustrophobia
#IF (@enemy_class <> Occultist) {preact "order @bubonis passive"}

peact and CureAdd are aliases. CureAdd causes the argument (in this case, set_claustrophobia) to be executed in a certain order (dependent on game mechanics). set_claustrophobia is a simple alias to set a single variable. preact sets up the argument to be executed first as soon as it's possible for the character to act.

That's an example of a defensive trigger. Here's one of the offense macros.

SoulSleep kick @kick_target
lust

Where SoulSleep checks a single variable and sends one of two commands to the MUD, and lust is an alias to place a set of commands to do an attack as soon as the character can.

So like I said, nothing particularly complicated syntax-wise, it all just fits together in a rather extreme way.

That's the best I can do, I'm afraid, without sending you the whole script, and A) my friend doesn't want that happening, and B) learning how it all works is a real nightmare. ^_^

Thanks again for your help, though!
USA #4
Hmm. Some of us could convert the entire mess fairly easilly, if we could get the entire thing. It is going to be a nightmare trying to convert it, believe me. lol

Take as an example:

#CW White

This command doesn't exist in Mushclient as a command. What I mean by that is you can't use the script to change the color of the line, but you can change the color in the trigger itself:

<triggers>
  <trigger
    custom_colour="17"
    match="""Don't get trapped now..."", the bubonis entity whispers to you."
    enabled="y"
    send_to="12"
    other_text_colour="white"
    other_back_colour="black"
  >
  <send>execute "CureAdd set_claustrophobia"
if getvariable("enemy_class") <> "Occultist" then
  execute "preact " & chr(34) & "order " & getvariable("bubonis") & "passive" & chr(34)
end if</send>
  </trigger>
</triggers>

Notice the custom_colour="17" (other) and other_text_colour="white". This will do the same thing as #CW.

Now, I also use send_to="12" (send to script). This allows you to do like zmud does and enter script code directly into the trigger. To make things a 'little' easier, I also use 'execute', which will send the text through the command and alias parser, just like if you typed it on the command line. This way you can simply convert the existing aliases and have it work.

If I was doing it myself, I would take the time to use true subs and functions in a .vbs file. However, doing so would require rewrites of a lot of the zmud script, but imho the end result would tend to be easier to change and debug. In generally, having related stuff in a plugin instead of the main world is useful and it is a lot easier to read true code in the main world script or <SCRIPT> block of a plugin than to try to read it in the aliases and triggers. But you can definitely do things the same way as zMud if you know what you are doing.

Your SoulSleep one would also use 'execute':

execute "SoulSleep kick " & getvariable("kick_target")
execute "lust"

However.. I am using getvariable here, which means it is an internal variable to mushclient. These are completely seperate from the variables used by the script. This is so that variables you want to save are saved, but the script engines values are lost when the script is shut down or reloaded. You can set internal variables using either the option of 'send to variable', which can only set one variable at a time:

<triggers>
  <trigger
   enabled="y"
   match="Fred says: *"
   send_to="9"
   variable="Fred"
  >
  <send>%1</send>
  </trigger>
</triggers>

or more than one by using the 'send to script' option like the others and doing:

<triggers>
  <trigger
   enabled="y"
   match="Fred says: *"
   send_to="12"
  >
  <send>setvariable "Fred","%1"</send>
  </trigger>
</triggers>

When using this second method, remember that 'send to script' does direct substitution. If the wild card contains something like 'hello' and you forget to place "" around the wildcard, then you end up with:

setvariable "Fred", hello

Since 'hello' is not a command or a number, the script engine will assume it is a variable and return either 0 or and empty string. VB likes to *guess* if you intended a string or a number and depending on how you code things can give exactly the opposite of what you intended. The above line 'should' end up being a string though, but had you done something like setvariable '"Fred", "Fred said" + hello', I would give it a 50-50 chance that the VB script engine would see the + and assume the very next thing must be a number. However, since I haven't tried something like that, I can't say for certain.

Anyway.. Good luck. Anything zMud can do should be possible in Mushclient. The only real issue is figuring out how and sometimes zMud can unintentionally obfuscate things. One thing I know for certain. It is a heck of a lot easier to convert 'to' Mushclient than the other direction. I found several glaring bugs in zMud trying that and finally had to ask Zugg himself what the heck was wrong. It was the last time I ever did a zMud user the favor of trying to convert one of my scripts to zMud. lol
Amended on Mon 09 Feb 2004 06:19 PM by Shadowfyr
Australia Forum Administrator #5
Shadowfyr, the command "execute" is one of the few that needs to be done as "world.execute" because "execute" is a VBscript command.

The trigger:

SoulSleep kick @kick_target
lust


is easy enough to convert, because you can execute other aliases in MUSHclient by sending it to "execute".

eg. the MUSHclient equivalent would be:

Match: SoulSleep kick @kick_target
Send: lust
Expand variables: checked
Send to: execute


Basically the same.
USA #6
Ah.. Didn't realize VBScript had such a command. Yeah. In that case you do have to use 'world.execute'...

However, from his description the for the SoulSleep macro does 'both' commands he showed, not just one of them. Both of them are completely seperate aliases executes by 'one' trigger.
USA #7
Actually, it's a macro--bound to F10. Those are both aliases, that one's not a trigger at all. Heh, sorry, shoulda made that clearer.

Looking around, though, it looks like this is going to be an extremely painful cut 'n' paste job, and little else. :(
Amended on Tue 10 Feb 2004 05:21 AM by Ledneh
Australia Forum Administrator #8
There is a break-even point for this sort of stuff.

With 10 or 20 it is quicker to cut and paste.

If you had 1000, and 900 were similar to the alias:

---
SoulSleep kick @kick_target
lust
---

I would be spending an hour writing something that converted from one to the other. Remember MUSHclient can take XML-style input, so it could be done in C, Perl, or whatever you are comfortable with.

For instance, you could convert that to:


<aliases>
  <alias
   match="SoulSleep"
   enabled="y"
   expand_variables="y"
   send_to="10"
   sequence="100"
  >
  <send>kick @kick_target
lust

</send>
  </alias>
</aliases>


The part that varies is in bold, which was the same as the original, so it is just "fill in the blanks" in your conversion script (up to a point anyway). Then, import the resulting text file into MUSHclient.

#9
hmmm on the topic of converting, how about simple speedwalk aliases? in my zumd clien i have an alias for about every area in aardwolf, which is a ton, would there be an easier way to move theses to mush client besides doing them one by one, or is it the same situation as above?

Thank you,

Skieze
#10
Skieze,

I would recommend rehauling your aliases if you use one for each sw in Aardwolf. I have an input file of speedwalks in this format:

keyword<tab>name of area<tab>start location<tab>speedwalk

Then write three functions in whichever scripting language you use (I have them in perl).

swget function searches the name of area field for whatever string you pass to it, and displays a list of the names of areas and their keyword.

swshow function outputs the speedwalk without sending it to the mud when you pass it a keyword.

swrun function executes a speedwalk when you pass it a keyword.

Ex file line:
bard<tab>Bard Clan Hall<tab>recall<tab>run 3sws|open s|s

I'll post code for this if I ever upgrade. I'm using a year and a half old version of Mushclient atm. But writing these functions is very easy, and then you can always just add a new line to the file instead of having to add a whole new alias.

As an aside, I was able to implement this in Zmud also, but I ended up using ActiveX with jscript, which was a PITA. Mush is just a hell of a lot faster than zmud.

HTH,
Dub
Australia Forum Administrator #11
MUSHclient supports speedwalk aliases, the format is similar to the above, here is a simple example:


<aliases>
  <alias
   match="shop"
   enabled="y"
   send_to="11"
   sequence="100"
  >
  <send>4n3w</send>
  </alias>
</aliases>


The internal syntax of the speedwalk is probably the same (eg. 4n 3w ) so converting them would be a simple case of reading the old ones, pulling out the relevant parts, and plugging into the alias (parts in bold) above.

Amended on Tue 10 Feb 2004 08:17 PM by Nick Gammon
#12
Aye, that would work too as long as the mushclient supported speedwalks can do things like open door, buy foo, enter thingie and so on. I much prefer a custom setup though, just because if you have an input file or database table for your speedwalks you can search their descriptions (from an alias) for whatever you need. I haven't looked at the inbuilt speedwalks though, so I can't speak to whether you can do that with them.
#13
Just to clarify btw...I am speaking specifically about Aardwolf, which I spend way too much time playing.
Australia Forum Administrator #14
MUSHclient speedwalks can do practically anything. eg.

3n 2w (open door) (eat cake) 4s
USA #15
New Question!

Can Mushclient trigger off variable contents (internal OR script)? Ala...

MATCH: @tar
EXEC : (color it orange)

I know this is perfectly doable in zMud, but I can't seem to figure out how to do it here.

Also, to state the obvious, @tar is a variable. ;)
Amended on Fri 13 Feb 2004 02:11 AM by Ledneh
Russia #16
Never tried doing that myself, but I believe it is possible. Try using the variable in the trigger match text like:

@tar jumps you from around the corner.

and setting the 'Expand variables' option in the Trigger dialogue
USA #17
Yeah, I already tried that--didn't work, hence, I'm here. :)
USA #18
Did you try it with a script variable or a Mushclient variable? You can only use the variables set using world.setvariable or the option 'send to variable' in aliases and triggers.

Basically, because Mushclient uses external engines to run its scripts, the scripts be any language you have an engine for and do things an inbuilt system could not. *However*, Mushclient's built in features like triggers are not aware of or able to access the variables used by those engines directly. This means you have to use Mushclient's internal variables for this.

Now, why it won't work for you with an internal variable I have no idea. It could be anything from not having you trigger text quite right to the name you store being upper case and the line you want to match using lower case.
Australia Forum Administrator #19
Yep, matching variables works fine. The variable has to be a MUSHclient variable (ie. appear in the variables configuration screen), but this works:


<triggers>
  <trigger
   custom_colour="9"
   enabled="y"
   expand_variables="y"
   match="@tar"
   regexp="y"
   sequence="100"
  >
  </trigger>
</triggers>