A recipe for a potion with multiple correct orders

I have to put some ingredients into a container and perform actions like stirring inbetween.
However, there are some variations allowed and since there are multiple recipes that have to work this way, I can’t just use if statements.

The logical thing to do would be using tables and check each turn which if the ingredient corresponds with the order from the list.
However, I have no idea how to phrase this in the inform7 language.

Does anybody have experience with this?

Maybe the Stone Soup example from the Inform 7 Manual/Cookbook can help: inform7.com/learn/man/WI_19_3.html#e361

It also mentions creating a “Food effects rulebook” which might be something to try out: inform7.com/learn/man/WI_19_2.html

Thanks for the reply, but as far as I understand the Stone Soup doesn’t require one or more specific orders to get a recipe right.

How much flexibility is allowed in the order? Could you give an example recipe?

Ingredient A: before B
Ingredient B: not first and not last, after A and before F
Ingredient C: doesn’t matter, has to be stirred afterwards
Ingredient D: doesn’t matter, has to be stirred afterwards
Ingredient E: before F
Ingredient F: after B and E

Hadean Lands was an extreme example of this. There were many recipes, some of which branched. (That is, A-B-C-D gave one result, but A-B-E-F gave a different result.) This is not easily representable as a table.

I thought of the problem as a state machine, if that helps. Roughly like this:

A ritual-state is a kind of value. The ritual-states are start, did-A, did-AB, did-ABC, did-ABCD, did-ABE, did-ABEF, failure.
Curstate is a ritual-state that varies.

Ritual is a rulebook.
Ritual rule when curstate is start and the noun is thing-A:
	now curstate is did-A;
	stop.
Ritual rule when curstate is did-A and the noun is thing-B:
	now curstate is did-AB;
	stop.
Last ritual rule:
	now curstate is failure;
	stop.

(This is a very rough sketch. It compiles, but it’s just the start of a usable system.)

The idea is that your add-ingredient action does “follow the ritual rules”, and this advances curstate. If no rule matches, the last rule fires and marks the outcome as ruined.

HL was more complicated because it had to deal with many possible actions as well as many possible nouns. (You could add an item, say a word, ring a bell, etc.) Left as an exercise. :slight_smile:

Cross-threading… Okay, your set of rules is not a simple state machine either.

Really, what I’d do is write them literally as a set of rules. After adding B, fail if the add-count is 0 or 5; also fail if F is added or A is not added. You can phrase that in Inform pretty simply, once you define add-count and a way to say that particular items are added or not.

In my mind a table was the logic things to do, but the state machine makes more sense. I will try it at first with the ingredients only and then I will see how I can integrate actions. Thanks so far!

–not that you shouldn’t listen to zarf, who made about the biggest game ever entirely about following magical recipes…

But it seems to me that if you were doing ingredients only, you could do it by having a list of what ingredients had been put in the cauldron, and then you could do a check on that list, like this:

[code]The Witches’ Cave is a room. A cauldron is a container in the cave.

An ingredient is a kind of thing. Allspice is an ingredient. Balm is an ingredient. Cardamom is an ingredient. Dimity is an ingredient. Ectoplasm is an ingredient. Fluorine is an ingredient. [don’t actually use fluorine] Red herring is an ingredient.

A potion is a thing.

The cauldron has a list of ingredients called the ingredient list.

When play begins: now the player carries every ingredient.

Check inserting into the cauldron when the noun is not an ingredient: say “Ingredients only in the cauldron!” instead.

Carry out inserting an ingredient into the cauldron: add the noun to the ingredient list of the cauldron.

After inserting an ingredient into the cauldron: say “You have now added [ingredient list of the cauldron] to your bubbling brew.”

Every turn when the number of entries in the ingredient list of the cauldron is at least six:
say “The recipe should be done now!”;
if the ingredient list of the cauldron is a valid recipe:
say “Success!”;
now every ingredient in the cauldron is nowhere;
now a potion is in the cauldron;
truncate the ingredient list of the cauldron to zero entries;
otherwise:
say “The brew is a green sludge. The wrong kind. You dump it out and retrieve more ingredients from your store.”;
truncate the ingredient list of the cauldron to zero entries;
now every ingredient in the cauldron is carried by the player.

To decide whether (first ingredient - ingredient) is listed before (second ingredient - ingredient) in (recipe - list of ingredients):
unless first ingredient is listed in recipe and second ingredient is listed in recipe, no;
repeat with item running through recipe:
if item is first ingredient, yes; [They’re both there, and first ingredient was first]
if item is second ingredient, no. [second ingredient was first]
[this could have weird results if there’s more than one instance of the ingredients, or if the ingredients can be the same, but you can avoid it]

To decide whether (components - list of ingredients) is a valid recipe:
unless allspice is listed before balm in components, no;
if balm is entry 1 of components or balm is entry 6 of components, no;
unless balm is listed before fluorine in components, no;
unless ectoplasm is listed before fluorine in components, no;
if cardamom is listed in components and dimity is listed in components, yes.[/code]

(There are issues here–you can mix it up by putting in more than one ingredient at once, and I didn’t make any provision to prevent you from taking ingredients out.)

As for stirring… hmm, unfortunately you can’t make a list of ingredients and stored actions, but maybe you could give ingredients a “stirred” property that represents whether or not the pot was stirred after the ingredient was added? If the ingredient can come back out of the pot then you’d need to make sure to reset the property when that happened. If there is more than one thing that can be done to the pot perhaps you could make that a multivalued property, like this:

An ingredient can be untouched, stirred, or shaken (this is its processing property).

with the last ingredient on the list getting changed to stirred or shaken when the player does that to the pot.

In case you’re curious, HL had just over 100 ritual states. The big simplifying assumption is that we go straight to “failure” as soon as the player makes a mistake – that is, makes a move which is not part of a valid recipe. But we don’t just announce this to the player. They can keep adding stuff and saying words, and the spell continues to react in generic (but perhaps off-key) ways. So it feels like a much denser possibility space.

This is really elegant. You should see my old wall of if statements…

Could I save the order with something along the lines of Robo 2 ( inform7.com/learn/man/WI_21_9.html )
and use the list it creates in another recipe?