Checking the result of a previous action

I’m trying to stop an action based on the results of a tried action. I feel like there’s something basic I’m missing. Consider the following:

Lab is a room.

A thing can be blue.

The box is in the lab. The box is blue.

Frotzing is an action applying to one thing. Understand "frotz [something]" as frotzing.
Blorbing is an action applying to one thing. Understand "blorb [something]" as blorbing.

check frotzing something blue:
	say "You can't frotz something blue.";
	stop the action;

Carry out blorbing something:
	try frotzing the noun;
	say "Ta da!";

 test me with "blorb box".

I would like to stop blorbing if frotzing fails, but I’m not aware of any mechanism to do this. If rule succeeds does not work.

Any ideas?

This is, weirdly enough, not something that’s easy to check in out-of-the-box Inform.

Which version are you using? I built a way to do this for Scroll Thief back in the 6G days but it is unequivocably a hack, which means it’s very likely to have broken in new versions. (It relies on the fact that a stored action expands to a routine call with a specific name in Inform 6, and uses that to trick it into calling a routine with a prefixed name instead.)

Quick and dirty way is to set a global flag in the “Carry out frotzing” rule, and clear the flag in an “Every turn” rule.

The way the standard rules do it (for things like implicit takes), by the way, is looking at the results in the world. If you try implicitly taking something, and then you’re carrying that thing, the taking must have in some sense succeeded (and conversely if you’re not carrying it then it in some sense failed). So if frotzing changes some state in the world, you can check that state.

1 Like
Lab is a room.

A thing can be blue.
A thing can be frotzed.

The box is in the lab. The box is blue.
The spam is in the lab.


Frotzing is an action applying to one thing. Understand "frotz [something]" as frotzing.
Blorbing is an action applying to one thing. Understand "blorb [something]" as blorbing.

check frotzing something when the noun is blue:
  if the action is not silent, say "You can't frotz something blue.";
  stop the action;

carry out frotzing something (called the frotzee): now the frotzee is frotzed.

check blorbing something (called the blorbee):
silently try frotzing the blorbee;
unless the blorbee is frotzed, instead say "Can't do it."  

Carry out blorbing something:
	say "Ta da!";

 test me with "blorb box".

this is just a few lines different from yours, carrying out the tactic @Draconis described.

The interesting thing here is that there is an absolute state that can be checked (is the item now in the player’s possession). In my case, the state to be checked is relative; in other words I need to know the state before and after trying the action in order to know if it succeeded. Specifically, I’d need to check if a value decreased by one. That’s not so hard, but it feels icky.

Thanks everyone!

1 Like

An action variable could make it not particularly icky. Untested:

To decide what number is the special sauce: [whatever]

The blorbing action has a number called the foo.
Before blorbing, now the foo is the special sauce.
Check blorbing:
  silently try frotzing the noun;
  if the special sauce is foo - 1 [...]
1 Like

In that case, why not use

Check blorbing:
    let foo be the special sauce of the noun;
    try frotzing the noun; 
    if the special sauce of the noun is foo - 1:
        [...]

I don’t see that the action variable gets us anything.

The reason I say it’s “icky” is that it relies on state beyond its control. For instance:

A gun is a kind of thing. 
A pistol is a kind of gun. A pistol has a number called ammo count.
A laser rifle is a kind of gun. A laser rifle has a number called battery charge.

Firing is an action applying to one thing. Understand "fire [something]" as firing. [this might be firing into the air]
Shooting it at is an action applying to two things. Understand "shoot [something] at [something]" as shooting it at.

Check firing a pistol: 
    if ammo count is 0:
        stop the action;

[...]

Check shooting a target with a gun:
    try firing the second noun;
    [no way to tell what to compare here, instead we need to break this check rule into subcases.]
    [also, maybe a pistol can randomly jam. how do we test that?]

It’s been noted before: Inform 7 is bad at supporting polymorphism.

1 Like

I had assumed it was something more complicated than something discretely affected by the frotzing… it wouldn’t have occurred to me that the other version is icky, so I hadn’t thought that was it.

This particular example doesn’t really seem to me to demonstrate a weakness of I7. You’d want two or more check rules.

Check shooting a target with a pistol: [...]
Check shooting a target with a laser rifle: [...]

and, sure, they might have a line in common, but that would hardly be unusual in OOP either.

I have spilled a lot of virtual ink noting things I find to be particular shortcomings in I7. I’m not an automatic apologist. But in this case it seems to me like you want to approach things with a paradigm that I7 knowingly doesn’t attempt to support, and that it’s actually not terrible at accomplishing these particulars within its own paradigm.

1 Like

You might also like to check out Implicit Actions by Eric Eve (for v10) (or Implicit Actions for 9.3/6M62) which provides a very nice way to establish preconditions for actions and which facilitates chaining actions.