Am I making rules wrong?

What am I missing? SHOWME tells me that Cove of Plunder is being watched, but the shop employee isn’t in the store and all the items are free. I also tried a slightly worse method (imo) where the prices are created before you enter Cove of Plunder, but this also didn’t work.

Cove of Plunder is a room. Cove of Plunder can be watched or unwatched. Cove of Plunder is watched. The description of Cove of Plunder is "The local general store. The inside is crammed wall-to-wall with all sorts of pirating goods.".
	
The shop employee is a woman.

Oarinator 3000 is an object in Cove of Plunder. "BETA NOTE- PURLOIN THE [oarinator 3000] IF YOU WANT TO SEE THE ENDING. I'M NOT DONE WITH THIS PART". The description of the Oarinator 3000 is "The latest model of oar with a snazzy stripe design.".

The fishing pole is an object in Cove of Plunder. "THE [FISHING POLE] DOESN'T DO ANYTHING ATM"

The shovel is an object in Cove of Plunder. "A [shovel]." The description is "A little spade. You can use it to DIG."

The adhesive is an object in Cove of Plunder. "A little tube of liquid [adhesive]." The description is "An all-in-one adhesive for ATTACHing any one material to any other."

This is the security rule:
	if Cove of Plunder is watched:
		now the price of the Oarinator 3000 is $100;
		now the price of the fishing pole is $10;
		now the price of the shovel is $10;
		now the price of the adhesive is $1;
		now the shop employee is in Cove of Plunder;
	if Cove of Plunder is unwatched:
		now the price of the Oarinator is $0;
		now the price of the fishing pole is $0;
		now the price of the shovel is $0;
		now the price of adhesive is $0;
		now the shop employee is nowhere.

Also, here’s what I’ve got for my money system. I’m pretty happy with it; I’m including it because you need it for the above code to run.

Price is a kind of value. $1000 specifies a price. A thing has a price. The price of a thing is usually $0.

Definition: a thing is free if the price of it is $0.
Definition: a thing is for sale if it is not free.

After examining something for sale, say "It can be yours for [the price of the noun]."

Check taking something for sale:
	if the noun is a doubloon:
		continue the action;
	otherwise:
		say "You'll have to BUY that.";
		stop the action.

Before buying something for sale when the money is not in the purse:
	say "You're broke." instead.

Before buying something for sale when the money is free:
	say "You're broke." instead.

Before buying something for sale when the price of the money is less than the price of the noun:
	say "Your funds do not run to the price of [the noun]." instead.

Instead of buying something:
	decrease the price of the money by the price of the noun;
	say "You fork over [the price of the noun] for [the noun], leaving yourself with [the price of the money].";
	now the price of the noun is $0;
	now the player is carrying the noun.
	
The player carries a purse. The purse contains money. The price of the money is $0. The printed name of the money is "[price of the money]". The description of the purse is "A simple black drawstring coin purse."

Instead of taking the money:
	say "Best to leave it alone until you need to buy something."

Instead of buying the money:
	say "The money belongs to you; you buy things with it."
	
Instead of dropping the money:
	say "You open your coin purse before you think better of the action."
	
A doubloon is a kind of thing. The price of a doubloon is $1. 

Instead of taking a doubloon:
	increase the price of the money by the price of the noun;
	say "Taken.";
	now the noun is nowhere.

Budding is an action applying to nothing. Understand "rosebud" and "kaching" as budding. 

Carry out budding:
	increase the price of the money by $1000;
	say "Your purse suddenly becomes far heavier.".
	
Loding is an action applying to nothing. Understand "motherlode" as loding. 

Carry out loding:
	increase the price of the money by $5000;
	say "You stagger under the weight of the coins that materialized at your hip.".
	

A thing can be examined or unexamined. A thing is usually unexamined.

Carry out examining something:
	now the noun is examined;
3 Likes

It’s hard to say without having my laptop here. But I don’t see where you have a line that expressly puts the woman in the shop.

I’m not understanding why you want to create the prices here except at the beginning of the story, ‘when play begins’. You might find it easier and that it works better.

Just my thoughts. Thanks!

3 Likes

I think I saw Zed starting to reply to this, so you may be getting a better answer to these questions soon, but in the meantime I figured I’d take a crack at things.

First off, yes, you are making rules wrong, but don’t panic! You’re not too far off and it’s hopefully an easy adjustment to make.

The main issue you’re running into is that your “security rule” never actually runs, at least in the code excerpt you’ve posted. The way Inform’s rule engine works, individual rules need to be included in rulebooks and then either called manually (you can write something like “follow the turn sequence rules”, where “turn sequence rules” is the name of a rulebook) or get called automatically by the standard rules (the before, check, carry out, etc. rulebooks all get consulted based on the player’s input, and then things like every turn rules fire as part of the upkeep performed after an action is taken). So just writing up a rule and naming it doesn’t do anything; Inform doesn’t know when it should run it.

The ways to solve this issue are straightforward – you can either manually place the rule into an existing rulebook, like “the security rule is listed first in the every turn rulebook”, or just mark where it should go in the rule preamble:

Every turn (this is the security rule):

So that’s the main thing. Beyond that, I will say that this reads oddly to me as an every turn rule, since it’s overcomplicating and adding a separate step to what I’d think should just be part of the buying / taking action (I also don’t think you need to manually set each price to zero since they all become free when the shop isn’t watched, right?) I’d probably just set the full price of each object via an assertion when it’s created (i.e., “The shovel is an object in the cove. The price is $10.”) and then do something like:

Before taking something for sale:
	If the Cove of Plunder is unwatched, now the price of the noun is $0;
	[Maybe add a say statement here about checking to make sure no-one is watching...]

You’d need to do something different to move around the employee, it seems like, but without knowing what triggers the watched/unwatched condition, it’s hard to suggest anything.

Hope this is helpful!

6 Likes

Thank you so much for your detailed response!! That’s really helpful. And that makes sense – just because I’ve established the rule doesn’t mean that Inform knows to run it, and when. I agree that it shouldn’t be an every turn rule since the time spent in the Cove should be relatively minimal. It might work as

Every turn when the location is Cove of Plunder (this is the security rule):

but again, it really only needs to run when the watchedness state changes. The ‘before taking something for sale’ I think might work as long as I specify the product since there are multiple vendors in my game, so I’ll give that a shot! I can probably tie the employee presence to whatever I’ll decide triggers if the Cove is being watched.

1 Like

I have fixed prices for the food and drink vendors in the game, but since you can visit the store when it’s being watched (when employees won’t let you steal) and you can break in during their lunch break to steal plot-important items, I don’t think I can establish those prices at the beginning. That being said, I might be able to do that and then have an instead clause to make the products free – maybe using a scene? (I feel like I’ve been really underutilizing scenes, but a Lunch Break scene might make that work.)

Thank you!

Another note–it seems unusual to make these “objects” rather than “things.” To Inform, objects and things are not the same. I’m not sure if this is actually a problem–I just thought I’d mention it in case it leads to unexpected problems down the road.

4.1. New kinds (ganelson.github.io)

2 Likes

It doesn’t look like you’re ever told Inform when it should follow the security rule.

But I think what you want to arrange is:

If the shop employee is in the Cave of Plunder, the player can’t take something without buying it. If the employee is gone, the player can steal everything. And that can be done a little more simply. This does most of what you had in mind:

a doubloon is a kind of thing.

Cove of Plunder is a room. "The local general store. The inside is crammed wall-to-wall with all sorts of pirating goods.".
	
The shop employee is a woman in the Cove of Plunder.

The block buying rule does nothing when the player is in the Cove of Plunder.

Oarinator 3000 is in Cove of Plunder. "BETA NOTE- PURLOIN THE [oarinator 3000] IF YOU WANT TO SEE THE ENDING. I'M NOT DONE WITH THIS PART". The description of the Oarinator 3000 is "The latest model of oar with a snazzy stripe design.". price is $100.

The fishing pole is in Cove of Plunder. "THE [FISHING POLE] DOESN'T DO ANYTHING ATM". price is $10.

The shovel is in Cove of Plunder. "A [shovel]." The description is "A little spade. You can use it to DIG.". price is $10.

The adhesive is in Cove of Plunder. "A little tube of liquid [adhesive]." The description is "An all-in-one adhesive for ATTACHing any one material to any other.". price is $1.

Definition: a thing is free rather than for sale if it is a doubloon or its price is $0.

check taking something for sale in the Cove of Plunder when the shop employee is in the Cove of Plunder:
instead say "You'll have to buy that.".

The player carries a purse. The description of the purse is "A simple black drawstring coin purse[if the price of the purse > $0] containing [price of the purse][else]. It is empty[end if].".

to decide what price is the bankroll:
  if the player holds the purse, decide on the price of the purse;
  decide on $0.

to decide if broke: decide on whether or not the bankroll is $0.

check buying something when broke: instead say "You're broke.".

check buying something when the price of the noun > the bankroll:
	say "Your funds do not run to the price of [the noun]." instead.

carry out buying something:
decrease the price of the purse by the price of the noun;
	say "You fork over [the price of the noun] for [the noun], leaving yourself with [if the price of the purse > $0][the price of the purse][else]nothing[end if].";
	now the price of the noun is $0;
	now the player is carrying the noun.

before buying something in the Cove of Plunder when the noun is free or the employee is not in the Cove of Plunder: say "[We] [can] just take [regarding the noun][those].";
instead try taking the noun;

after taking something:
now the price of the noun is $0;
continue the action.

conjuring is an action applying to one price.
understand "conjure [price]" as conjuring.
carry out conjuring: increase the price of the purse by the price understood.
report conjuring: say "[We] now [have] [price of the purse].".

banishing is an action applying to one thing. [this will be built-in in the next version]
understand "banish [thing]" as banishing.
carry out banishing: now the noun is nowhere.

test me with "take adhesive / buy adhesive / conjure $1 / x purse / buy shovel / buy adhesive / x purse / banish employee / buy shovel."

Rather than changing anything upon whether the Cove is watched or not, we just have prices; if we try to take something with a non-zero price when the employee is in the Cove, we fail.

It’s probably overcomplicated to represent the money as a separate object. It may be overcomplicated to even have a purse as an in-game thing. But I kept the existence of the purse but just gave it its own price to represent its contents.

Before rules run before the basic accessibility rule so you usually want “you can’t do that” rules to be Instead or Check rules, unless you’re sure accessibility is irrelevant. Before rules are good, though, when you want to replace the current action with an attempt to perform a different action, which is why I used it for the before buying rule. (The accessibility rules will get followed for the action you’re switching to.)

You may have used an Instead rule to effect buying 'cause the default block buying rule was preventing getting to the carrying out rules. So I blocked the block buying rule within the Cove. In general, if an action was conceptually successful, put the meat of the change in world state in a carry out rule.

3 Likes

They end up being things anyway. I7 won’t let you create items whose kind is purely object. And Inform assumes anything you’re creating is a thing if it doesn’t have a specific reason to think it’s anything else, so: things.

3 Likes

That was my impression as well - that the hierarchy went thing > object and if something is an object, it’s also a thing

Wow – thank you so much for this!! I’ll have to take some time to understand it, but I love how concise that makes both the money system and purchasing! And yeah - the purse isn’t the most elegant solution to how I set up money, but I needed to give something a price since I have the doubloons disappear once you pick them up and their value simply added to the purse’s price so there aren’t a million identical objects scattered about.

Also, that’s a really useful tip about the order rules run in. I wasn’t sure of the hierarchy there so I just kind of used before and check fairly interchangeably. That’s really good to know

1 Like

No, the hierarchy really is object > thing. All things are objects, but not all objects are things. It’s just that you can say X is an object all you like. (Literally! this compiles:

X is an object.
X is an object.
X is an object.

) but like I said, I7 won’t actually let you create something that is purely of kind object, only things that are subkinds of object (or subkinds of subkinds, etc.) So this:

lab is a room.
X is an object.
X is an object.
X is an object.
when play begins: 
if x is an object, say "X is objective.";
if x is a thing, say "X is thingalicious.";

outputs:

X is objective.
X is thingalicious.
2 Likes

Oh! Gotcha - I had it backwards, then. In that case, I probably should go back and clean some of that up. I guess that explains why Inform didn’t like when I tried to sort objects into categories of thing.

Thanks! Appreciate it - I had the hierarchy backwards :sweat_smile:

Inform can be a little deceptive in how simple it seems. The code I wrote above is pretty easy to read and fairly straightforward. But what one can’t see in the code is how much time I spent to understand the World Model and the Standard Rules.

Inform does a whole lot of useful things by default. A big part of the craft of Inform is making choices that work with the default behavior rather than (inadvertently) making choices that work against them. So we all end up doing a lot of swimming upstream when starting out with Inform 'cause we haven’t had a chance yet to learn which way the stream flows.

The References section of the I7 Docs and Resources post links to several previous threads discussing where to put what kind of rules.

3 Likes

Whoa!! That references section is incredible. I was wondering where to see a list of default actions and responses (I found by accident that POLISHing a cutlass had a pre-written response) and that’s just the first item on the list, so this is amazing. Now I know how I’m spending the rest of the day :smiley: :smiley:

1 Like