Toadstool Time Bomb

Hi there.

Instead of just saying “you die” after eating a toadstool, but not so far into the future as to be annoying, can I set a rule in a room the player will have to move through like:

Before going to the throne room:
	if the player has eaten the toadstool:
		say "you start to feel sick. That toadstool is not sitting right!".

Before entering the kings chambers:
	if the player has eaten the toadstool and the player has not vomited:
		say "You stumble to the ground and your vision fades to black. You are dead!";
                      end the story.

instead of vomiting:
       say "Retching and gagging, the horrible toadstool finally emerges onto the King's fine rug.";
       now the toadstool is nowhere.

I’ve put together a demo that does what you’re after. I will explain it in a second post.

-Wade

"Toadstool Legends"

Meadow is a room.
meadow is west of Throne Room.
Throne Room is west of King's Chamber.

player is in meadow.

a toadstool is an edible thing in meadow.
Understand "toad", "stool" as toadstool.

the eaten of toadstool is initially false.
the poisoned_you of toadstool is initially false.
the purged of toadstool is initially false.



After eating toadstool:
	now eaten of toadstool is true;
	now poisoned_you of toadstool is true;
	say "You eat it. It doesn't taste great.";



Report going east from meadow when poisoned_you of toadstool is true for the first time:
	say "You start to feel sick. That toadstool is not sitting right! This might be a good time to purge.";



vomiting is an action applying to nothing.
Understand "vomit", "puke", "purge", "throw up" as vomiting.

After vomiting when poisoned_you of toadstool is true:
	now purged of toadstool is true;
	now poisoned_you of toadstool is false;
	say "After much retching, you manage to vomit up what's left of the toadstool. Which isn't much.";
	now toadstool is nowhere;	

Report vomiting:
	say "You don't need to right now, so why bother?";
	


After going east from throne room when poisoned_you of toadstool is true:
	say "You stumble to the ground and your vision fades to black. You are dead!";
	end the story;


test me with "vomit/eat toad/e/w/e/vomit/e".

Great. I’ll look forward to it!

This is so great. And funny too!!!

Thanks! OK, here’s a fairly detailed explanation.

So I began by looking through your demo code.

‘eating’ is a built-in action in Inform, but Inform does not understand ‘has eaten’ or ‘has been eaten’ out of the box.

(I thought it might understand ‘has been eaten’, the way it understands ‘has been open’… see 9.13 in the documentation… but it doesn’t.)

I had to remind myself how Inform eating works. The way it works is that if you have made a thing ‘edible’, eating it will eat it and take it out of play. (Documentation 3.22) If the thing hasn’t been made edible, attempts to eat it will be rejected.

So in the source, I put a toadstool in the field, and made it edible. Information we need to track about it in the future includes:

  • has the player eaten it? (a cheap way to detect this might be to check whether the toadstool is now ‘out of play’ or ‘nowhere’, where it automatically goes when eaten, but to be a bit more rigorous, I’ll have a flag – a truth state – set to true when we eat it. Because what if we dropped it off a cliff elsewhere in the game? It would be ‘out of play’, but we would not have eaten it, so that would no longer be a valid way to check that we ate it.)

  • IS the player currently poisoned from eating it?

  • has the player vomited it up?

A good place to store information about the toadstool is right ‘in’ the toadstool itself. So I’ve made three truth states that record the three bits of information above, flags that can be set true or false, on the toadstool. Apologies, I forget what the name for this kind of variable is (local? object-specific?) and couldn’t find it quickly in the documentation:)

Since we want something non-standard to happen when the toadstool is eaten (poison the player and say that it tasted bad) I’m using an AFTER rule to get the job done.

‘After eating toadstool:’…’

An after rule will print its messages instead of the standard report message for the same action, and allows us to do extra things in code, too. In this case, set the ‘eaten’ and ‘poisoned_you’ toadstool flags to true.

The next thing you wanted was a message about feeling sick. I can already see a shortcoming in my program: If you pick up the toadstool, go east and then eat it, you’ll never get the warning about being sick, because I set the warning to only appear when going east from the meadow when already poisoned. So fixing that can be homework for you.

There are a couple of fiddly things about the sick message as is.

First, it’s often difficult to recall and use the right phrasing to get Inform to act on players going to/from rooms.

I found that ‘going east from meadow’ worked.

‘going east in meadow’, which I tried first, compiled, but did not actually work to print the message. ‘going’ in general is the action to use for this sort of thing, however. ‘entering’, like you tried, is generally more for containers and supporters and non-room things in Inform.

The line that dispenses the sick message is not one that reads logically to humans, but it makes Inform sense:

‘Report going east from meadow when poisoned_you of toadstool is true for the first time:’

This line first looks for these circumstances: You’re going east in the meadow, and poisoned_you of toadstool is true. Let’s call that clause A.

It then looks for this additional circumstance, clause B, which is… you’re satisfying clause A for the first time. Therefore, the second time you satisfy clause A, this report will NOT happen. (See documentation 9.14 ‘How many times?’)

The icing on the cake of this demo is the creation of vomiting. This is not a built-in action, so we have to make it from scratch, and set the words that will lead to it.

I’ve created the default response to vomiting with the line ‘Report vomiting:’

To create the specific response for vomiting when you’re poisoned, I again use an ‘after’ rule, recalling that it lets you print a non-standard message for the action, overrides the report message, and runs some code.

-Wade

Thank you for taking the time to write all that. I appreciate it.

I’ve tried to incorporate it in my game but I’m having trouble with it not being in a certain location to trigger the shenanigans. I changed it to going a direction, which you identified as being problematic and I’m happy to put it on the ground, but I’m in it now and I wanted to know if it is possible. The scenario is they may walk around with it and eat it later.


After going a direction when poisoned_you of toadstool is true:
	say "You stumble to the ground and your vision fades to black. You are dead!";
	end the story;

You’ll need to specify the exact circumstances that lead to death in order for us to be able to decide how to program it.

i.e. Do you want it so that -

  • they eat it and drop dead?
  • they eat it, then if they leave the current room, they drop dead?
  • they eat it, and when they enter a specific pre-determined room, they drop dead?
  • they eat it and die X turns later?
  • something else?

It now sounds like you want the second one, though in that case, the player should probably receive a ‘you oughta purge’ warning as soon as they eat the mushroom.

-Wade

What you programmed was great.

I do like the idea that it can countdown but that’s not what’s programmed and I’d rather follow the configuration you’ve already worked on.

The whole thing started when I was learning about triggering things in two ways: location and having eaten the toadstool. I didn’t want to just say “you’re dead” like the games of my childhood. I like what you have and it taught me a lot. When I was implementing it though, it occurred to me that they might take the toadstool but eat it elsewhere invalidating a location specific trigger.

In truth, the toadstool is incidental to the main plot. I’m trying to learn by exploring every wrinkle that occurs to me along the way and I learn best when I follow flights of fancy I can use later.

Good to hear you’re just exploring whatever turns up.

Yes, as you’ve recognised, in my demo the poison warning only happens in one location, and the death only happens in one other location.

To check for things that can happen anywhere in response to some prior condition, the typical way is to use an Every Turn rule. Just like they sound like, they run once each turn.

So for instance, you could replace this one-off location-specific code –

Report going east from meadow when poisoned_you of toadstool is true for the first time:
	say "You start to feel sick. That toadstool is not sitting right! This might be a good time to purge.";

– with something much more general that will print every turn so long as the player is poisoned:

Every turn when poisoned_you of toadstool is true:
	say "You feel sick.";

Or, below is a fancier version of the every turn rule that will dish out a different message about being sick (and what the player should do about it) for four turns, then just keeps repeating ‘You feel sick’ each turn after that (until they’re cured or dead, presumably!). Documentation 5.7 has more examples of making text alternatives like the following. These are great because you can often cover a lot of programming ground in one line/rule:

Every turn when poisoned_you of toadstool is true:
	say "[one of]You feel sick. Must have been that toadstool you ate[or]You still feel sick. Might not be a bad time to purge[or]You feel very poorly[or]You really need to purge[or]You feel sick[stopping].";

So now the illness alerts would be detached from specific locations or movement. You could use the same kind of every turn rule to eventually kill the player from the poisoning if you wanted, using some kind of counter.

-Wade

That’s good. I wrote a piece about falling snow that returned different descriptions depending on a random “roll” now I see how I could put these two together. I’ll do that.

Thank you again.

Another option, if you want to use I7’s built-in timer features:

After eating the toadstool:
    the poison takes effect in five turns from now;
    continue the action.

At the time when the poison takes effect:
    say "Oh no! Poison!";
    end the story saying "You have died".

That’s because the phrases “going <some direction> in <some location>” and “going <some direction> from <some location>” are intended to be used in different circumstances.

The first: Going some direction in a location is used when that particular direction is not a valid connection. The attempt at going fails, so you’re still in the location. Useful especially for implementing “soft boundaries” to the map, or silently redirecting travel. (e.g. “The passage slopes down to the west” suggests that both down and west are valid commands in this situation. You could simply make both down and west link to the same destination, but in practice this leads all too easily to bugs, where “down” sets off the Rolling Ball of Death scene, but west gets overlooked. So best practice is to silently redirect one direction. If we’ve made “down” the genuine map connection, then: “Instead of going west in Sloping passage, try going down.” will ensure that no matter which command the player uses, the same code gets run.)

The second: Going some direction from a location is for when that direction is valid for travel – furthermore it only fires when such travel has succeeded. So if, say, a guard prevents the player from traveling in a particular direction, the phrase will not fire until the problem of the guard has been dealt with and the travel is then successful.

1 Like

Hi again. Do I need to add an extension for the program to keep track of this syntax? I don’t seem to be able to get the player to die, no matter how many turns I spend walking about.

the poisoned_you of toadstool is initially false.
the purged of toadstool is initially false.


After eating toadstool:
	now eaten of toadstool is true;
	now poisoned_you of toadstool is true;
	say "It tastes awful but you muscle it down.";

Every turn when poisoned_you of toadstool is true:
	say "Hmm. Something's not right.";

After eating the toadstool:
	the poison takes effect in five turns from now;
	continue the action.

At the time when the poison takes effect:
	say "Oh no! Poison!";
	end the story saying "You have died".

vomiting is an action applying to nothing.
Understand "vomit", "puke", "purge", "throw up" as vomiting.

After vomiting when poisoned_you of toadstool is true:
	now purged of toadstool is true;
	now poisoned_you of toadstool is false;
	say "After much retching, you manage to vomit up what's left of the toadstool. Which isn't much.";
	now toadstool is nowhere;	

Report vomiting:
	say "You don't need to right now, so why bother?";```

Hi there @hzdgmg

The problem is that you have several “after eating the toadstool rules.” After rules default to stopping the action: they’re not “cumulative”. So what’s happening is that the first rule is being run (“It tastes awful…”) but the second after rule (the poison takes effect…) is not being reached.

If you put everything together into a single After rule:

After eating toadstool:
	now eaten of toadstool is true;
	now poisoned_you of toadstool is true;
	the poison takes effect in five turns from now;
	say "You eat it. It doesn't taste great.";

Then the code works as intended, and after five turns the PC dies.

I don’t know how you managed to get the code to compile with two identical “After eating toadstool” rules – I couldn’t, and as I understand it, that’s intentional.

Note, mind you that:

After eating the toadstool:

and

After eating the toadstool for the first time;

and

After eating the toadstool when the player is frisky:" (or whatever other condition you’ve set up) are legitimate, and will/should compile because those “After Eating” rules are not identical.

By the way, I notice in the “After vomiting” rule, you say “now the toadstool is nowhere” – that’s not necessary unless you’ve altered the eating action: by default Items eaten are moved off-stage by eating them.

Thanks for looking that over and for clearing some things up. I’me grateful you took the time to do that

I’m not sure how I managed to duplicate line and compile correctly either. Perhaps there’s something else elsewhere that’s doing it.

I think Wade @severedhand might have included the “now the toadstool is nowhere” line for instructive purposes.

1 Like

I’d like to stretch the example a little further as a means to investigate if it’s possible to create a chain of timed events.

For example, just as I can use the “poisoned_you is true” condition to kill the player after five turns, can I change the code to something like this (which I know doesn’t work):

the illness-you of toadstool is initially false.
the poisoned_you of toadstool is initially false.
the purged of toadstool is initially false.


After eating toadstool:
	now eaten of toadstool is true;
	now illness_you of toadstool is true;
    the illness takes effect in three turns from now;
    say "It tastes awful but you muscle it down.";

Every turn when illness_you of toadstool is true:
	say "Hmm. Something's not right.";
	
At the time when the illness takes effect:
	say "That toadstool has poisoned you!";
    the poison takes effect in five turns from now;

At the time when the poison takes effect:
	say "Oh no! Poison!";
	end the story saying "You have died".


vomiting is an action applying to nothing.
Understand "vomit", "puke", "purge", "throw up" as vomiting.

After vomiting when poisoned_you of toadstool is true:
	now purged of toadstool is true;
	now poisoned_you of toadstool is false;
	say "After much retching, you manage to vomit up what's left of the toadstool. Which isn't much.";
	now toadstool is nowhere;	

Report vomiting:
	say "You don't need to right now, so why bother?";```

Yes, you certainly can create a chain of events. I’ve omitted all the vomiting and other stuff to make the code clearer, so in this game there’s no way to avoid dying after eating the toadstool. :

The trouble with toadstools
"The trouble with toadstools" by "Testa"


The sunny meadow is a room. "Bright, emerald sward shimmers in the sunlight, sloping downhill towards a cavelike entrance to the east."


The throne room is east of the sunny meadow. "A vaulted and lofty dome, it's not easy to tell if this place is natural or has been fashioned by deliberate intent."


A toadstool is an edible thing in the sunny meadow. "Glistening blue and green amidst the grass, a fine specimen of Royal Deathcap is growing here."

Understand "mushroom", "fungus/fungi", "deathcap" or "royal deathcap" as the toadstool.


After eating the toadstool:
	feeling bad begins in two turns from now;
	say "You gulp the slimy thing down, too nauseated to chew it.";
	
	
At the time when feeling bad begins:
	if the toadstool is nowhere:
		slow poisoning begins in three turns from now;
		say "You begin to feel ill. Perhaps eating that [toadstool] was a bad idea.";
		
At the time when slow poisoning begins:
	say "The world is darkening before your eyes.";
	end the story saying "You have been poisoned.";
	
test me with "eat mushroom / z / z/z/z/z/z".
		

But this is really only to show that it could be done. If you want to have a chain of events in your story, then it’s better to use scenes. Not only are scenes designed for this purpose, but there’s a special index devoted to them which will automatically show which scene is triggered by what.

Compare the code:

Scenes with mushrooms
"Scenes with toadstools" by "Testa"


The sunny meadow is a room. "Bright, emerald sward shimmers in the sunlight, sloping downhill towards a cavelike entrance to the east."


The throne room is east of the sunny meadow. "A vaulted and lofty dome, it's not easy to tell if this place is natural or has been fashioned by deliberate intent."


A toadstool is an edible thing in the sunny meadow. "Glistening blue and green amidst the grass, a fine specimen of Royal Deathcap is growing here."

Understand "mushroom", "fungus/fungi", "deathcap" or "royal deathcap" as the toadstool.

After eating the toadstool:
	now the printed name of the toadstool is "partially chewed toadstool";
	now the toadstool is in your stomach; [I didn't want to mess around with the default eating action]
	now the toadstool is handled;
	say "You gulp the slimy thing down, too nauseated to chew it thoroughly.";

Your stomach is a container.
Vomiting is an action applying to nothing.

Understand "vomit", "puke", "purge", "throw up" as vomiting.

Report vomiting when nothing is in your stomach:
	say "You retch, fruitlessly.";
	[default message]
	
After vomiting:
	say "You heave up [the list of things in your stomach].";
	now everything in your stomach is in the location.

	
Feeling bad is a scene. Feeling bad begins when the toadstool is in your stomach.

When feeling bad begins:
	say "You begin to feel ill. Perhaps eating that toadstool was a bad idea.";
	
[It's really easy to have things happen only during a scene --]
Every turn when feeling bad is happening:
	say "[one of]Ooo, you do feel strange[or]Your stomach aches[or]Spots shimmer before your eyes[stopping].";
	
Feeling bad ends happily when the time since feeling bad began is three minutes and the toadstool is on-stage.

When feeling bad ends happily, say "You feel considerably better." 

Feeling bad ends miserably when the time since feeling bad began is three minutes and the toadstool is in your stomach.
	

Slow poisoning is a scene. Slow poisoning begins when feeling bad ends miserably.

When slow poisoning begins:
	say "Spots dance before your eyes, and your lips feel numb. There's no hope for you now.";
	
[or PROHIBIT certain actions during a scene]
Instead of going when slow poisoning is happening, say "You feel too weak to travel.";
	
Slow poisoning ends when the time since slow poisoning began is two minutes.

When slow poisoning ends:
	end the story saying "You have been poisoned.";

If you click on the “Index” tab (down the side of the IDE) and then select the “Scenes” tab, you’ll find a summary list of the scenes and what happens when each begins/ends, together with a schematic showing which scene begins when. This sort of help is really needed when you start writing anything larger or more complex.

Ooooh. That’s really good. I hadn’t thought to use scenes like that.

Let me digest this.

1 Like

Those scenes are great. Also, dealing with the eaten toadstool by using the stomach as a container is genius.

Do I need to add the modified time include for this to work (if so what’s the exact syntax, I’m having trouble finding the author)? Something’s not right as I don’t seem to be able to get to the slow poisoning scene to start, dying after four actions.

Odd. It works for me. You’re clicking on the little whatsit top-left of the code window to copy it to your clipboard, and then pasting (ctrl-v) into a blank inform page, right?

With the code I posted, I get the following playthrough:

With no vomiting

Scenes with toadstools
An Interactive Fiction by Testa
Release 1 / Serial number 191117 / Inform 7 build 6L38 (I6/v6.33 lib 6/12N) SD

sunny meadow
Bright, emerald sward shimmers in the sunlight, sloping downhill towards a cavelike entrance to the east.

Glistening blue and green amidst the grass, a fine specimen of Royal Deathcap is growing here.

eat mushroom
(first taking the toadstool)
You gulp the slimy thing down, too nauseated to chew it.

You begin to feel ill. Perhaps eating that toadstool was a bad idea.

Ooo, you do feel strange.

z
Time passes.

Your stomach aches.

z
Time passes.

Spots shimmer before your eyes.

Spots dance before your eyes, and your lips feel numb. There’s no hope for you now.

z
Time passes.

z
Time passes.

*** You have been poisoned. ***

Would you like to RESTART, RESTORE a saved game, QUIT or UNDO the last command?
>

or If I vomit up the mushroom (there’s not much time, have to do it next move, I think. Obviously unfair for a game, but I didn’t want you getting numb thumb hitting “z” over and over.)

with vomiting

Scenes with toadstools
An Interactive Fiction by Testa
Release 1 / Serial number 191117 / Inform 7 build 6L38 (I6/v6.33 lib 6/12N) SD

sunny meadow
Bright, emerald sward shimmers in the sunlight, sloping downhill towards a cavelike entrance to the east.

Glistening blue and green amidst the grass, a fine specimen of Royal Deathcap is growing here.

eat mushroom
(first taking the toadstool)
You gulp the slimy thing down, too nauseated to chew it.

You begin to feel ill. Perhaps eating that toadstool was a bad idea.

Ooo, you do feel strange.

vomit
You heave up the partially chewed toadstool.

Your stomach aches.

z
Time passes.

Spots shimmer before your eyes.

You feel considerably better.

z
Time passes.

z
Time passes.

If you want to change the length of a scene, then the instruction controlling its length is

Feeling bad ends happily when the time since feeling bad began is three minutes and the toadstool is on-stage.

The general form is –

<scene name> ends <optional qualifier> when the time since <some event> is [number] minutes <optional extra condition(s)>.

minutes = turns

By the way, the when (whatever) scene begins and when (whatever) scene ends can do more than just print messages – they can do anything you can do in a rule; bringing stuff on stage, moving it around, whatever you like.