Need to Derail "answering it that"

Moving right along … I now have my sorcerer’s apprentice casting spells on command – as long as the command is phrased in its long form. The long form is, “cast at ”. But when the apprentice is ordered to cast a spell using the short form, “ ”, the command is interpreted as the answering it that action. The player can use the short form to get the PC to issue commands, but not to tell the NPC what to do:

What I seem to need to do is re-parse the topic understood as a command. Just extracting word 1 of the topic understood wouldn’t solve the problem (even if I knew how to do that), because the command might be “pip, nitfol the big green lizard”. We have to be able not only to transform “nitfol” from topic text back into the name of a magic-spell but also to grab the rest of the command and understand it as the noun.

I’d really like the player to be able to command the apprentice using all the same spell-casting grammar that the PC him/herself can use. But I don’t at all see how to do this. Suggestions welcome!

What is the grammar line for the short form?

Here’s the grammar for all three forms:

[code]Zapping is an action applying to two things. Understand “[magic-spell] [something]” as zapping.

Casting is an action applying to one thing. Understand “[magic-spell]” and “cast [something]” as casting.

Casting it at is an action applying to two things. Understand “cast [something] at [something]” as casting it at.[/code]
The casting action is vague – it would be invoked by the bare command “nitfol” (or “pip, nitfol”), which doesn’t work either for the NPC:

…and perhaps this is relevant:

Carry out an actor zapping: try the actor casting the noun at the second noun instead.
This transforms zapping (“nitfol the beach ball”) into casting it at (“cast nitfol at the beach ball”). Zapping has no other code, because it doesn’t need any.

The following code produces the desired output for each version of the spellcasting command. What I’m hoping to do is to not force the game author to write five new blocks of code for each and every spell.

[code]nitfol-casting is an action applying to one thing. Understand “nitfol [something]” as nitfol-casting.
nitfol-vague-casting is an action applying to nothing. Understand “nitfol” as nitfol-vague-casting.

Instead of an actor nitfol-casting something:
try the actor casting nitfol at the noun;
rule succeeds.

Instead of an actor nitfol-vague-casting:
try the actor casting nitfol;
rule succeeds.

Persuasion rule for asking an apprentice to try nitfol-casting something:
persuasion succeeds.

Persuasion rule for asking an apprentice to try nitfol-vague-casting:
persuasion succeeds.[/code]
Here’s the output:

This is the desired result – but if an author wants to implement a dozen new spells, it would be very nice if the author could simply define the spells, rather than having to write two individual verbs for each and every one. For reference, here’s the definition of the nitfol backdrop. (It’s a backdrop because that way it’s in scope everywhere.)

nitfol is a magic-spell. It is everywhere. The output of nitfol is "[The person asked] [cast] the nitfol spell. Briefly, everything goes dark, but then the light returns." The directed output of nitfol is "[The person asked] [cast] nitfol at [the second noun], and for a moment [they] [are] transformed into a shadow, but then the light returns." The description of nitfol is "The nitfol spell makes darkness."

That block should ideally be all that’s needed.

The essence of the problem seems to be that when the parser encounters a noun of address (“pip, …”), it looks for the next word to be a verb. If the next word is a verb, the parser says, “Aha – this is a command for the NPC to do something.” But if the next word is NOT a verb, the parser says, “Aha – this is a conversation. Let’s use the answering it that action.”

I’m guessing about this, but that’s sure what it looks like from the outside. What is needed, then, is a way to rejigger the parser so that answering it that is not the choice when the next word is a magic spell.

I think you may be hosed without some fairly substantive parser hacking. The way the parser distinguishes commands from answering it thats is by checking whether the first word after the comma is a verb. This means that you can’t ask NPCs to perform noun-only commands. See section 17.10 of the documentation.

(This has been the case for a while, probably forever; I’ve run up against something similar trying to get Inform to understand disambiguation commands with words that may be verbs.)

Thanks for the pointer to 17.10. At least I have the satisfaction that I guessed right about the cause.

I’m not going to try messing with the parser. I could try writing an “after reading a command” rule, but even that would be quite fiddly and prone to break. For one thing, if I tried to turn “bart, cast frobozz at the eunuch” into “cast frobozz at the eunuch bart” I’d have a command with three nouns.

Well, making the magic-spell objects nouns was arguably a kluge to begin with, since they’re essentially actions. Maybe there’s a straightforward way to store the results of actions in corresponding off-stage objects, or in a table, so as to streamline the author’s writing of new actions. I guess I’ll try that.

In “Scroll Thief” (based on the method used in RoTA) I made the spells an enumerated value, with the casting action applying to one spell and one thing. But I don’t think that will get around this problem. Infocom (in the Enchanter trilogy) just made a new verb for each spell, with the equivalent of a check rule to make it fail unless the corresponding spell object was contained in the spellbook object.

Well, “bart, cast frobozz at the eunuch” should be fine–if “cast” is a verb then Inform will process this as a command. So if you could stick “cast” after the comma when you need it you’d be fine. But even doing that would be fiddly and prone to break, or at least more than I’d want to try.

Maybe you could try something like this?

Before answering someone that:
    repeat with spell running through the list of magic-spells:
        if the topic understood matches the printed name of the spell:
            try the noun casting the spell instead.

(My syntax is a little rusty, so you might need to tweak it a little, or possibly put it in a different main rule type.)

As written this will probably only work for one-word spells with no targets, but once that’s working you should be able to expand it, in theory.

Can you go at this another way? You have asked Pip to nitfol, but pip knows two things to do with nitfol - learn it or cast it.

If the parser has decided that Pip is entering into conversation at this time, go with it and move to a conversation. That way you are teaching the player the “correct” way to deal with spells IE the way that you have coded it.

In modern video games, the player is shown how to do something, made to do it in a safe environment, then thrown into the game with this new skill to hand. EG the original Half Life and it’s HEV suit - you are made to go through a training sim to learn long jumping and other features, before the game really starts.

So,

gets the response “I have already learned that spell/do you want me to learn that spell?/You are being unclear what you want me to do master - I can only cast or learn spells, help me by being specific/Do you want me to cast nitfol at the beach ball?” as appropriate.

Pip is an apprentice, yes? Apprentices are idiots, that’s why they have masters, in this case the player. If the master is being unclear, that’s their fault and the apprentice ought respond by asking for help.

Also, that way you are working with Inform not against it :sunglasses:

I considered that idea, but rejected it. It works fine for “pip, nitfol” – but it fails drastically with a more realistic command – “pip, nitfol the dragon.” This might be typed by the player as “pip, nitfol dragon”, “pip, nitfol the dragon”, “pip, nitfol the big dragon”, “pip, nitfol the big green dragon”, “pip, nitfol green lizard”, “pip, nitfol the lizard” … you get the idea. As far as I7 is concerned, those are all different texts. The Answering It That action makes no attempt to parse them; everything after “pip,” is considered just a plain old dumb string of characters.

As a result, I would have to reinvent the entire parser to figure out what object Pipsqueak was being ordered to nitfol. No, that won’t work at all.

Making the spells verbs is the obvious solution to the immediate problem. An author can do that in their own game – it works like a charm. But at that point, there’s no need for a Spellcasting extension. The rationale for writing an extension is that it streamlines the process for the author. The author just writes a few sentences about a magic-spell object (which has a name – it’s a noun), and the extension takes care of the mechanics of casting the spell. That’s what the original version of my extension did.

If magic-spells are actions, the extension can’t handle the mechanics of casting the spells, because the extension doesn’t know what spells the author is implementing. It could do so if I7 allowed the creation of kinds of action – but it doesn’t. I’ve fired off an email to Emily suggesting that she might want to drop a hint to Graham about allowing kinds of action in a future update. If the sentence “Spellcasting is a kind of action” were allowed, an extension could implement default handling for a whole class of actions, and the author would only have to write a little code giving the grammar and the output text for the spell.

Secondarily, an action would have to be allowed to have truth states and other properties attached to it, and lists of actions (not currently possible, I believe) would have to be allowed.

This would be, of course, an enormous, basic change in I7. I’m pretty sure that if it were possible to create kinds of action, some other cool stuff would become possible, or easier to implement.

In the absence of kinds of action, the author who wants to create magic-spells has to manage both the action (nitfoling) and an object that keeps track of stuff to do with nitfol (such as whether it has been learned). It would be up to the author to keep nitfoling in sync with the nitfol object – an extension couldn’t handle the housekeeping, because the extension wouldn’t know what new spells the author was implementing.

I suppose I could write an extension that created a dozen magic-spells, which should be plenty for most games, and direct the author to write stuff like this:

Understand “krgbz [something]” and “cast krgbz at [something]” as nitfoling. The printed name of nitfol is “krgbz”. The default-output of nitfol is “You krgbz [the noun], and it explodes!”

Now that I think of it, that might actually work… As soon as I get over my fit of pique, I’ll give it a try.

I think you can make lists of action names.

…and kinds of action are allowed, of a sort. You could say “Nitfolling is spellcasting. Frotzing is spellcasting” etc. Then it’s possible to do Before, Instead, and After rule that refer to the kind of action, but not Check, Carry Out, and Report. I’m not sure of the syntax for getting this to work for NPCs though.

Truth states and other properties wouldn’t work, I don’t think, and I don’t know if there’s any nice integration with listing action names that would allow you to easily print a list of spells.

Probable user error … ignore while I test.

You’re right. This does work.