I’m despairing of the verb extension definition. I need to parse three kinds of commands:
drop X => normal
throw Y off the table => VerbMyThrow1Sub
throw Z at someone => VerbMyThrow2Sub
No matter how I fiddle with extend (only) ‘throw’ (first/replace), one of the three commands always yields an unwanted result because one of the other two is parsed first. What do I need to do?
Which library version are you using? At least in the current version, ‘drop’ and ‘throw’ are not synonyms, so changing the grammar of one should not affect the other. And ‘drop’ has no grammar containing ‘at’.
Drop and throw hasn’t been synonym for a long time. I think there’s a forgotten redefinition there somewhere that causes the confusion between the two.
In 6/11, where “drop” and “throw” are synonyms, you do this:
Extend only 'throw' first * noun 'at' noun -> Verb_Throw;
Extend 'throw' * noun 'off' noun -> Verb_Umhauen;
The first code line has “only”, which splits “throw” off into a separate grammar table (but keeps the existing grammar lines for it). Then it defines “throw X at Y”, tagged “first”, so that line takes precedence over the existing “throw X at Y → ThrowAt”.
The second code line doesn’t need “only”, because “throw” is already de-synonymed. It just adds a new “throw X off Y” grammar line.
Note that this solution interprets “throw rock” as “throw rock (at something)” and tries to guess a second noun. If you want to retain the original handling of “throw rock” as a synonym for “drop rock”, you’d have to add another line.
Thanks for pointing out my library is outdated, Fredrik! Game’s almost finished, so I’ll go with my shabby one, and then never return to Inform 6 again.
Don’t say that. Inform 6 is great. Steep learning curve, but still great.
Further to what the others have already said:
Nothing needs to be done.
‘throw Y off table’ is bad English and I doubt that anyone would even think to try it. To throw something, it must first be in your possession and if it’s on the table, then it’s not in your possession. Therefore, this definition can be deleted.
In the 6/11 library, throw object at something is already defined in the library’s grammar, specifically * held 'at'/'against'/'on'/'onto' noun -> ThrowAt; Therefore, you can delete this one, too. Just use ThrowAt in your before and after routines.
Nah. I do prefer I6 over I7 (part from I7’s great IDE…), but viewed from my LPC/C++ background the concept of storing everything in a “dictionary” and represent it through numbers is obscure and antediluvian. I’m pretty sure that when I’m done with this game (2031, if I keep up my speed) I’ll find most of what I want in TADS.
(and “throw X off table” is just a synonym for “knock X off table”)
Works well for “mix obj1 with obj2” and “mix obj1 into obj2”, but “mix obj1 and obj2” results in “You can’t use multiple objects with that verb.”. Why is that so, and how can I get around that? I suspect it’s got something to do with “and” having multiple purposes when parsing, but I can’t make head or tail of it.
‘and’ is a reserved word that is used when you want to refer to multiple objects. For example GET PEPPER AND SALT or DROP CUP AND SAUCER AND PLATE. I think you’ll have to omit that pattern in your grammar, unless those wiser than me know a workaround.
Incidentally, you can make the grammar definition more concise by using:
Come to think of it, you may be able to get around this by using one of the multi tokens. For example:
Verb 'mix'
* multi -> Verb_Mischen;
but your Verb_MischenSub would have to cater for the mixing of a single ingredient, as the command MIX SALT AND PEPPER would effectively be converted to MIX SALT. MIX PEPPER. Otherwise, you can have a separate action handler for this case, even if it’s just a message to tell the player the correct syntax to use.
I’ll just live with “mix X and Y” not working. One question on “* multi” though - It sequentially goes through both objects provided. How can I stop the parser after object 1, any idea?
The I6 library is set up to break the sequence if you die or change location. (There’s some additional logic about an NPC failing to understand a command, but that’s not relevant here.)
You could tweak the library by adding code to the play() function in parser.h. Look at the loop that starts:
for (k=1 : k<=j : k++) {
if (deadflag) break;
if (location ~= i) {
L__M(##Miscellany, 51);
break;
}
! ....
You could add a global variable there and break the loop if it ever becomes true. I did this in some of my I6 games.
Well, I don’t think I ever tried implementing a single action to handle “VERB X AND Y”. (Bureaucracy had a puzzle like this, didn’t it?)
The strategy would be to add code before the loop I mentioned above. If the action is compatible with multiple objects, fire it off (one call to self.begin_action()) and have the action routine look at the multiple_object array.
I thought there was an example for this case in the DM4, but I haven’t found it.