RegEx Help on a magic spell
XanMag
22 Apr 2020, 17:12So... I want to cast a spell ON something specific instead of the player just saying it in random rooms to see what happens.
In a RegEx I have typed this:
^(cast|say|speak) (transform|transform spell) (on|at|to|toward|towards) (?<object>.*)$
and that will account for JUST ABOUT everything I want. "Cast transform on cat" for example.
I have the following code to account for spell stuff. Don't worry... it's a little more in the actual game itself =)
if (GetBoolean(Heavy Spell Book, "TransformLearned")) {
if (object = cat2) {
if (ListContains(ScopeVisible(), cat2)) {
msg ("You say \"transform\" in the direction of the cat and... POOF! It has magically turned into a dog!")
MakeObjectInvisible (cat2)
MakeObjectVisible (dog1)
}
else {
msg ("I don't see a cat here.")
}
}
else if (object = dog1) {
msg ("You say \"transform\" in the direction of the dog and... POOF! It has magically turned into a cat!")
MakeObjectInvisible (dog1)
MakeObjectVisible (cat2)
}
else {
msg ("You cast transform in that direction and it does nothing.")
}
}
else {
msg ("It doesn't appear you know that spell.")
}
Now... my question is this. What if the player wants to type transform cat
?
Seems reasonable. How would I alter this RegEx to account for that? Or would I have to create another RegEx to deal with that verbage?
Oh... and this... does my RegEx account for capitalization? I think it does, but...?
Dang... SORRY. Also, how could I handle a player input like: cast transform but not followed by a prep and noun.
Thanks in advance!
Phadion
22 Apr 2020, 19:55I'm extremely new to quest, so I'm sorry if this seems like a dumb question, but why are you using a RegEx if you're only implementing one object in it? You could make verbs on the different objects instead. If you're using a RegEx to avoid having to account for the many ways a player could input the command, I guess I can understand that, but if you used verbs, you would only have to input the different ways the player could say it once, and then copy and paste them for other objects. What I mean is, for example, you could make a verb under the object "cat2" called "cast transform on; cast transform spell on; say transform spell on" ... Etc., one of which you could make simply "transform". In my very limited experience with RegEx (literally just experimenting with it today after reading your post) I've found it more trouble than it's worth, and if I was trying what you are, this is what I would do. Hope this Helps, and I'm sorry if it doesn't make sense, some times I have trouble articulating my thoughts.
mrangel
22 Apr 2020, 20:34I would have tried ^(cast|say|speak|use|) ?transform( spell)? (on |at |to |towards? |)(?<object>.+)$
. You don't really lose anything like that. The pattern matches non-gramatical phrases like "transform at cat" and "cast transform cat"; but I think that shouldn't be a problem because a player typing those phrases is unlikely to mean any other command.
@Phadion: Why does it make any difference if it's a verb? The pattern works the same anyway.
It's perfectly permissible to have a verb with a pattern like cast transform on;cast transform at;cast transform to;cast transform toward;cast transform towards;cast transform spell on;cast transform spell at;cast transform spell to;cast transform spell toward;cast transform spell towards;say transform on;say transform at;say transform to;say transform toward;say transform towards;say transform spell on;say transform spell at;say transform spell to;say transform spell toward;say transform spell towards;speak transform on;speak transform at;speak transform to;speak transform toward;speak transform towards;speak transform spell on;speak transform spell at;speak transform spell to;speak transform spell toward;speak transform spell towards
(which is exactly the same as XanMag's original regex).
But what's the benefit of doing it that way? If you think of another word to put in later – like you realise players are going to try "use transform spell on cat" – then it'll take you at least a few minutes to update it. The power of using a regex in that case is that you can mix and match the different elements, and you don't need to think of every possible combination someone might use them in. And it's also easier to make changes to.
But really, you're talking about the difference between simple pattern and regexp pattern. Verbs vs regular commands is a separate issue. (I likely would use a verb in this case; but I'd still keep the regex pattern)
If you're really curious, click here to see the non-regex version of the line I put at the beginning of this post
cast transform on;cast transform at;cast transform to;cast transform toward;cast transform towards;cast transform;cast transform spell on;cast transform spell at;cast transform spell to;cast transform spell toward;cast transform spell towards;cast transform spell;say transform on;say transform at;say transform to;say transform toward;say transform towards;say transform;say transform spell on;say transform spell at;say transform spell to;say transform spell toward;say transform spell towards;say transform spell;speak transform on;speak transform at;speak transform to;speak transform toward;speak transform towards;speak transform;speak transform spell on;speak transform spell at;speak transform spell to;speak transform spell toward;speak transform spell towards;speak transform spell;use transform on;use transform at;use transform to;use transform toward;use transform towards;use transform;use transform spell on;use transform spell at;use transform spell to;use transform spell toward;use transform spell towards;use transform spell;transform on;transform at;transform to;transform toward;transform towards;transform;transform spell on;transform spell at;transform spell to;transform spell toward;transform spell towards;transform spell
Phadion
22 Apr 2020, 20:50Like I said, I'm new to quest, and today was the first time I have ever tried to implement RegEx, and I personally found too many errors come up then I wanted to deal with. I was simply saying what I would have done in the situation with my limited understanding of quest. Perhaps I should not have responded to this before having full understanding of regex, so I'm sorry.
XanMag
22 Apr 2020, 21:16@Phadion - no problem. I used to do that in the past and I ended up running into errors. Either I would leave out an option(s) (which forces the player to guess the verbage), duplicate a verb option, or I'd run into errors with pre-formatted verbs. All of which threw up some error messages. Using RegEx, even though the writing of it is more difficult, I did run into fewer issues. Continue offering suggestions here though even if you are not confident. I've been around FOREVER and I offer suggestions that are way more...different... than what most people suggest. There are a LOT of different ways to skin a cat with code so your way may work for some and not others.
@mrangel - I have never seen that used before - ?transform( spell)? . I think I may just copy-paste what you suggested and use that. That will account for transform cat and all the other reasonable options mentioned above? And then all I would have to do is to use an If expression object = [object name] then run scripts for any object I want a specific response to. Also, what would happen if the player just typed cast transform in any random room?
EDIT: I think I will make a global cast transform command with a generic response (that is, unless I hear back about a better idea.) Or will that interrupt the RegEx?
Thanks again!
mrangel
22 Apr 2020, 22:10I have never seen that used before - ?transform( spell)?
Question marks make the previous character optional. As the first set of brackets (cast|say|speak|use|)
has a 'nothing' option at the end, I put a ?
after the space that follows it - because a player typing "transform cat" won't have a space before "transform", but a player typing "cast transform cat" will have a space. It would have been equivalent to write (cast|say|speak|use|) ?transform
or (cast |say |speak |use |)transform
- but the former seems more natural to me.
In the case of summon( spell)?
, the question mark makes the part in parentheses optional, so it matches either "summon" or "summon spell"; and later on I did the same with towards?
, making the 's' optional so it matches either "towards" or "toward",
Also, what would happen if the player just typed cast transform in any random room?
It wouldn't match. There's a non-optional space in the pattern (the one after ( spell)?
) - so there has to be something after that.
If you wanted "cast transform" to work, you could use: ^(cast|say|speak|use|) ?transform( spell)?( (on |at |to |towards? |)(?<object>.+))?$
- making the space, preposition, and object all optional. In that case, you would have to check if (IsDefined ("object")) {
in your function first. If a variable pattern is inside an optional part, it will be completely undefined so comparing it to anything (even null
) is a fatal error.
Hope I'm making sense here.
XanMag
22 Apr 2020, 23:22So... lol... what I'm hearing is "Make a global command to handle the lazy adventurer who wants to type cast transform in random places just to see what happens".
Print message "Just walking around willy-nillying spells is apt to lead to failure or your death. Why don't you trying casting that spell ON something?

Forgewright
23 Apr 2020, 13:59Mrangel, how do you know to do these things in Quest? Is it JavaScript or HTML that you have experimented with in Quest? Perhaps you have dissected the Quest core? I'm sure there is no Quest tutorial like this. Or is there?
Either way, it is sure nice when code like this is shared.
mrangel
23 Apr 2020, 15:43For most of the Quest stuff, I skimmed over the core code when trying to answer people's questions on here. I find the source easier to understand than the documentation in a lot of cases.
In the case of regular expressions, they're used in a lot of languages. My preferred programming language, Perl, uses them everywhere; as does Javascript.
I actually have a book somewhere titled Mastering Regular Expressions; 544 pages in paperback. The things you use them for in Quest barely scratch the surface (and Quest sadly doesn't support all of their capabilities).