Combining commands

What I’m trying (not very successfully) to do here is combine (via the ‘meld’ command) one object with another – in this example, the small stone with the toothpick, and make a third object out of them – but I can’t seem to phrase it so that it works.

[code]“Meld” by David Whyld

An Abandoned Warehouse is a room.

A piece of glass is held by player. A ring is worn. A small stone is held by player. A toothpick is held by player. A hammer is an object.

Understand “meld [something] with [something]” as melding. Melding is an action applying to two visible things.

Carry out melding small stone with toothpick:
remove small stone from play;
remove toothpick from play;
move hammer to player;
say “Done.”[/code]

But this produces the following error message:

I’m guessing the problem is with the way I’ve worded the ‘understand’ part as Inform is trying to ‘meld [something] with [something] with something else’, but I’ve hit a blank wall in my attempts to word it better.

Does anyone know how to get my code working?

Try “Melding it with is an action applying to two visible things.”

Do you mean

Understand "meld [something] with [something]" as melding. Melding is an action applying to two visible things. Melding it with is an action applying to two visible things.

I tried it and it compiled without an error message (so it’s definitely a step in the right direction), but when I type “meld stone with toothpick”, it just produces a blank line.

For a start, the sentence Zarf gave you should replace your other “Melding is an action” sentence.

-Kevin

This is somewhat buried in section 12.7 of the documentation, but the word “it” in “Melding it with is an action applying to two visible things” tells Inform where the first noun should go. It’s how it knows that the action is “Melding the small stone with the toothpick” rather than “Melding the small stone the toothpick.”

If you leave both lines in, it looks like you’ve defined a “melding X Y” action as well as a “melding X with Y” action. Inform is parsing the command the player’s typed as the action of melding small stone toothpick rather than the action of melding the small stone with the toothpick, and since your rule applies to melding it with the rule isn’t getting called on. Zap your original sentence (as Kevin suggested) and Inform won’t get confused on that count.

Ah, I wondered if I doing it wrong (and figured I must be seeing as it didn’t work). I’ve now changed it to

[code]“Meld” by David Whyld

An Abandoned Warehouse is a room.

A piece of glass is held by player. A ring is worn. A small stone is held by player. A toothpick is held by player. A hammer is an object.

Understand “meld [something] with [something]” as melding. Melding it with is an action applying to two visible things.

Carry out melding small stone with toothpick:
remove small stone from play;
remove toothpick from play;
move hammer to player;
say “Done.”[/code]

but this hits me with the following error message

I think you need:

Understand "meld [something] with [something]" as melding it with.

Instead of just “…as melding”.

Yes, that works! Thanks.

I’d like to think I’ve have figured it out on my own eventually, but we’d probably be well into Inform 8 before that happened.

:laughing:

Shocking, I know, but I’ve run into another problem. If I attempt to meld one item with another that can’t be melded (like a paperclip with a warehouse) {only items you can carry can be melded}, nothing happens and Inform just prints a blank line.

I tried adding

Understand "meld [something] with [something]" as melding it with. Melding it with is an action applying to two visible things. Carry out melding [something]: say "Your head buzzes but nothing happens. At least one of the items you're trying to meld isn't carried by you and, as such, can't be used in this way."

but this has the added problem of printing the part in speech marks every time something is successfully melded, like so

Does anyone know how I get rid of the final line when it isn’t needed? I’m guessing some kind of rule is required, but I’m a bit stumped as to how to word it.

Shouldn’t the fail line be in a ‘report melding’ rule, rather than a ‘carry out’? I’m not at my PC to make sure, but I’m pretty sure that’s right.

So:

Report melding it with: Say "Your nothing happens message."

Don’t just copy/paste that code, it was written on iPad so the tabbing won’t work (probably).

One way to do it would be to change all your “carry out” rules to “instead” rules. When an “instead” rule runs it stops the action (unless you include the line “continue the action”), so you won’t get the double message effect.

There are some disadvantages to using “instead” rules (climbingstars hates them), for instance officially when an “instead” rule runs the action counts as having failed, but this may not come up in your game.

Section 12.21 of the documentation has some handy tips about when to use which kind of rulebook, though people have different styles. In your case, it seems like your rules are particular cases – you have a rule for melding a string with the paperclip specifically – so “instead” rules might be appropriate. As mostly useless says, you usually don’t want “Carry Out” rules to print things; though I think just changing the failure message to a “Report” won’t do anything, because “Report” rules still run after “Carry Out” rules unless an “After” rule intervenes or the action is stopped some other way.

Another thing you could do is set up a more generic framework for melding, perhaps by defining a relation that obtains between two objects when they can be melded together. Then you could use the more generic Check/Carry Out/Report framework – use the Check rules to check whether the two objects are meldable (and print a failure message if they aren’t), use Carry Out to substitute the new object in, and use Report to write a general message for melding (“Your head buzzes and you attach [the noun] to [the second noun]. They stretch out and out and out… When the buzzing passes, you are carrying [need some way of generally specifying the new object] in your hands.”) Then you could use an After rule to write any special-case messages you want, since that’ll stop the generic Report rules from running.

This might be easier if your game gets complex enough that there will be lots of melding possibilities; for instance, it makes it easier to force it that “Meld X with Y” works whenever “Meld Y with X” is. With your current approach, you have to write a rule for “Instead of melding the small stone with the toothpick” whenever you have a rule for “Instead of melding the toothpick with the small stone,” and it’s easier to forget something.

You should write check rules that stop the action for the different cases when things can’t be melded:

Check melding it with when the noun is not carried or the second noun is not carried: say "Your head buzzes but nothing happens. At least one of the items you're trying to meld isn't carried by you and, as such, can't be used in this way."; stop the action.
Check rules run before carry out rules, and so they can stop the action before it is carried out.

Unless everything that can be picked up can be melded with something, perhaps you should define a “meldable” property that only meldable things have. Then you can have a check rule for the case where the noun or second noun is not meldable.

And I suppose you’d also want a generic answer for the cases when the player tries to meld two things that are meldable but not with each other.

EDIT: I keep forgetting about relations. As Matt W suggests, defining a reciprocal relation between things meldable with each other and then check whether the noun and the second noun are indeed meldable is surely the right way to go. Certainly, it’s much better than defining a one-place property to do the job!!!

Yes, got it working!

Did a quick change of “carry out” to “instead of” and things are melding nicely :slight_smile: Thanks, everyone.

The meldable property sounds like a good idea. At the moment, I only have 6 items in the game but 30 separate “instead of” sets of code for handling melding them together. In the finished version, there might be a couple of hundred items which would require enough “instead of” sets of code to put War & Peace to shame.

A couple of hundred items, strewth! Yeah, you definitely don’t want to special-case each one of those.

That seems like something that you probably want to handle with a table somehow. (Since you can’t have three-way relations like “X is meldable with Y to make Z.”) One column for the first item that gets melded, one column for the second, one for the item you get, and another one for any special text you might want to print as the result of the melding. Then instead of setting a “meldable” property by hand you can just check to see if your objects are in the table.

One big advantage of this approach compared to writing a bunch of rules or having a lot of relations you set by hand is that it’s easier to keep everything in sync. If you have to separately set objects as meldable and write the rules for melding them, it’d be easy to write a rule for melding something without setting it as meldable, and then you’ll get failures.

Here’s a little demo I wrote for it:

[code]“Meldability Demo”

The Lab is a room. The small stone, the toothpick, the paper clip, the string, and the useless lump of clay are in the Lab.

There is a rope ladder. There is a hammer. There is a fishing pole. [This creates them off-stage.]

Table of Meldability
first component second component result special message
small stone toothpick hammer –
paper clip string rope ladder –
toothpick string fishing pole “The toothpick and string combine to form a fishing pole. Cool!”

Melding it with is an action applying to two things. Understand “meld [something] with [something]” as melding it with.

Definition: A thing is meldable if it is a first component listed in the Table of Meldability or it is a second component listed in the Table of Meldability

Check melding it with when the noun is not held or the second noun is not held: say “You need to be holding something to meld it.” instead.

Check melding it with when the noun is not meldable: say “You feel a buzzing but [the noun] stays inert. That doesn’t seem to be susceptible to your melding powers.” instead.

Check melding it with when the second noun is not meldable: say “You feel a buzzing but [the second noun] stays inert. That doesn’t seem to be susceptible to your melding powers.” instead.

Carry out melding it with:
repeat through the Table of Meldability:
if (the noun is the first component entry and the second noun is the second component entry) or (the noun is the second component entry and the second noun is the first component entry):
remove the noun from play;
remove the second noun from play;
now the player holds the result entry;
if there is a special message entry:
say the special message entry;
otherwise:
say “You feel a buzzing. [The noun] and [the second noun] stretch out. When the buzzing subsides you are holding [the result entry].”;
rule succeeds; [this ends the whole rulebook with a success, which means we don’t keep repeating; but other carry out melding with rules won’t fire]
say “You feel a buzzing. [The noun] and [the second noun] stretch slightly but then subside. They seem to be things you can meld, but not with each other.” instead. [You’ll only get to this line if you’ve gone through the whole table without finding anything.]

Last carry out melding it with: say “Let’s see what this will do.”

Test first with “meld stone with toothpick/take all/meld stone with lump/meld lump with stone/meld toothpick with stone/i”.
Test second with “take all/meld toothpick with string/i”.
Test third with “take all/meld stone with paper clip”.
[/code]

Remember how I said “don’t print text in carry out rules”? Yeah, well… in this case it might seem better to use a check rule to see if the two objects are meldable, a carry out rule to move the objects around, an after rule to print the special message if there is one, and a report rule to print the generic melding message. But (I think) you would keep losing your place in the Table of Meldability every time you went to a new rulebook. So I wanted to stick everything in a rule, and “Instead” rules run before “Check” rules (see section 12.2), so I used a “Carry Out.”

One disadvantage is that the action counts as a “success” if both nouns are meldable even if they don’t meld with each other, because an action is a success whenever it reaches the “Carry out” rules. But it’s pretty likely that that won’t cause a problem (I think).

Anyway, hope this helps. If you have a lot of stuff to meld, it’s good to have a uniform way of doing it (that you can break if you need to – for instance, you could write an “Instead” rule for two special objects that would bypass all this machinery) and a way of keeping all the stuff you need for it in one place.

[EDIT: Snipped some debug code.]

Thanks. That worked brilliantly!

My code has gone from a horribly confusing (and long!) mess to something that’s a lot more concise and compact.