Inform 7 Home Page / Documentation
§15.19. Arithmetic with units
The example equations in the previous section carried out quite a lot of arithmetic, but they may have given the impression that Inform always allows arithmetic - which is not true.
This is actually a good thing, because it keeps us from error. For instance, Inform will not allow:
Equation - Newton's Totally Bogus Law
F = m^2
where F is a force, m is a mass.
because whatever you get when you square a mass, you don't get a force - in the same way that a length times another length makes an area, not another length. Physicists call this "dimensional analysis", and it often provides clues about which equations are right. Just after the Second World War, someone correctly worked out the explosive power of an atomic bomb without any classified information simply by guessing what values would appear in the formula, and then finding the simplest equation they could appear in.
In general, Inform will not allow numerical kinds of value to be multiplied or divided by each other (or square or cube rooted) unless we give it instructions that this would make sense.
Of course, there's plenty we can still do without any need for such instructions. For instance, going back to weight,
The Weighbridge is a room. "A sign declares that the maximum load is [100kg multiplied by 3]."
...will produce the text "A sign declares that the maximum load is 300kg." Here Inform knows that it makes sense to multiply a weight by 3, and that the result will be a weight. Similarly, Inform allows us to add and subtract weights, and several different forms of division are allowed:
The blackboard is in the Weighbridge. "A blackboard propped against one wall reads: '122 / 10 is [122 divided by 10] remainder [remainder after dividing 122 by 10]; but 122kg / 10kg is [122kg divided by 10kg] remainder [remainder after dividing 122kg by 10kg]; and 122kg / 10 is [122kg divided by 10] remainder [remainder after dividing 122kg by 10].'"
When we visit the Weighbridge, we find:
A blackboard propped against one wall reads: "122 / 10 is 12 remainder 2; but 122kg / 10kg is 12 remainder 2kg; and 122kg / 10 is 12kg remainder 2kg."
Whereas we are not allowed to divide 122 by 10kg: that would make no sense, since 122 is a number and not made up of kilograms. Inform will produce a problem message if we try. Similarly, Inform won't normally allow us to multiply two weights together - but see the next section.
Start of Chapter 15: Numbers and Equations | |
Back to §15.18. Equations | |
Onward to §15.20. Multiplication of units |
ExampleFrozen Assets |
In our brave new world, everything will have a price, so we had better spell this out.
Price is a kind of value. $10.99 specifies a price. A thing has a price. The price of a thing is usually $0.00. After examining something for sale, say "It can be yours for [the price of the noun]."
Now we assume a simple shopping model in which the player can't take anything without paying for it.
Definition: a thing is free if the price of it is $0.00.
Definition: a thing is for sale if it is not free.
Instead of taking something for sale:
say "You'll have to pay for that."
Before buying something for sale when the money is not in the wallet:
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].";
if the money is free:
now the money is nowhere;
now the price of the noun is $0.00;
now the player is carrying the noun.
The player's money object is going to be a bit unusual, because it has value but cannot itself be bought.
The player carries a wallet. The wallet contains money. The price of the money is $4.50. The printed name of the money is "[price of the money] in cash". Understand "cash" as the money.
Instead of taking the money:
say "Best to leave it alone until you need to buy something."
Instead of buying something free:
say "[The noun] is yours already."
Instead of buying the money:
say "The money belongs to you; you buy things with it."
Now we just need something to buy.
The Dessert Parlor is a room. "An underlit, over-crowded room campily furnished with a lot of gilt-frame mirrors and twinkle lights: it is essentially a brothel of food. The service is slow at best, and on Saturday nights glacial. However. The wares on display more than make up for these trivial inconveniences."
The vanilla ice cream is an edible thing in the Parlor. The price of the ice cream is $2.45. The description is "In the scale of ice creams, you recognize this as a very inferior vanilla because it has no adjectives in the title."
The raspberry tart is an edible thing in the Parlor. The price of the tart is $4.50. The description is "An almond-laced shell packed with raspberries-under-glaze."
The syllabub is an edible thing in the Parlor. The price of the syllabub is $4.25. The description is "Whipped cream, alcohol, and lime juice, a substance without any redeeming food value whatever."
The espresso cake is an edible thing in the Parlor. The price of the espresso cake is $5.50. The description is "A lethal wedge of purest blackness."
Test me with "inventory / examine syllabub / get syllabub / buy syllabub / drop it / get it / buy raspberry tart".
Implementing caloric units for this scenario is left as an exercise for the reader.
ExampleMoney for Nothing |
Price is a kind of value. $10.99 specifies a price with parts dollars and cents (optional, preamble optional).
A person has a price called wealth. The wealth of the player is $15.
A thing has a price called minimum value. The minimum value of a thing is usually $0.50.
A thing has a price called desired value. The desired value of a thing is usually $5.00.
Offering it for is an action applying to one price and one visible thing.
Understand "offer [price] for [something]" as offering it for.
After taking inventory, say "You have [the wealth of the player]."
Check offering it for:
if the price understood is greater than the wealth of the player, say "You don't have that kind of cash." instead;
if the second noun is not carried by someone, say "There's no one in a position to sell you [the second noun]." instead;
if the second noun is carried by the player, say "[The second noun] is already yours." instead;
if the minimum value of the second noun is greater than the price understood, say "[The holder of the second noun] cackles disdainfully. 'If yer just here to insult me you can take your business elsewhere!' he says." instead;
if the desired value of the second noun is greater than the price understood:
let difference be the desired value of the second noun minus the price understood;
let difference be difference divided by two;
decrease the desired value of the second noun by difference;
now the last object offered is the second noun;
say "'How about [desired value of the second noun]?' suggests [the holder of the second noun]." instead;
otherwise:
unless the desired value of the second noun is the price understood:
say "From the avaricious gleam in the eye of [the holder of the second noun], you guess you could've gotten this purchase for less..."
Carry out offering it for:
increase the wealth of the holder of the second noun by the price understood;
decrease the wealth of the player by the price understood;
move the second noun to the player.
Report offering it for:
say "You spend [the price understood], and now you possess [the second noun]."
When play begins: now right hand status line is "Your funds: [wealth of the player]".
Now, since the man does make counter-offers, it would be reasonable to let the player accept or reject those, as well:
Instead of saying yes when the last object offered is carried by a person (called seller) who is not the player:
if the seller is not visible:
continue the action;
otherwise:
now the price understood is the desired value of the last object offered;
try offering the desired value of the last object offered for the last object offered.
Instead of saying no when the last object offered is carried by a person (called seller) who is not the player:
if the seller is not visible:
continue the action;
otherwise:
now the last object offered is the player;
say "You reject the offer firmly."
And we borrow just a line or two from a later chapter to take care of some alternate syntax the player might try:
Understand "offer [price] to [someone]" as a mistake ("You'll need to specify what you want to buy -- try OFFER $1000.00 FOR BROOKLYN BRIDGE."). Understand "offer [someone] [price]" as a mistake ("You'll need to specify what you want to buy -- try OFFER $1000.00 FOR BROOKLYN BRIDGE.").
Understand "buy [something]" as a mistake ("You'll have to name your price: try OFFER $1000.00 FOR BROOKLYN BRIDGE.").
The Flea Market is a room. The crotchety man is a man in the Market. "A crotchety man here is selling [the list of things carried by the crotchety man]." The crotchety man carries a broken television set, a Victorian rhinestone brooch, and a cracked shaving mug.
Test me with "offer $0.50 for mug / offer $0.50 to man / offer $6.00 for mug / offer $50.00 for brooch / offer $1.50 for brooch / offer $4.50 for brooch / no / offer $4.50 for brooch / yes".
ExampleLemonade |
Liquids, and all substances that can be mixed or broken off in partial amounts, pose a challenge to model in interactive fiction. The following example is a simple one, but adequate for many scenarios.
We start by assuming that all liquids in the game will always appear in containers. The player can pour liquids from one container to another, and the containers keep track of how full they are and describe themselves appropriately. The player can also refer to containers by content.
Mixture, however, is not allowed, nor is it possible to put liquids on other objects, pour them out on the ground, etc. These ideas would require a more complicated set-up.
A volume is a kind of value. 15.9 fl oz specifies a volume with parts ounces and tenths (optional, preamble optional).
A fluid container is a kind of container. A fluid container has a volume called a fluid capacity. A fluid container has a volume called current volume.
The fluid capacity of a fluid container is usually 12.0 fl oz. The current volume of a fluid container is usually 0.0 fl oz.
Liquid is a kind of value. The liquids are water, milk, lemonade, and iced tea. A fluid container has a liquid.
Instead of examining a fluid container:
if the noun is empty,
say "You catch just a hint of [the liquid of the noun] at the bottom.";
otherwise
say "[The noun] contains [current volume of the noun in rough terms] of [liquid of the noun]."
To say (amount - a volume) in rough terms:
if the amount is less than 0.5 fl oz:
say "a swallow or two";
otherwise if tenths part of amount is greater than 3 and tenths part of amount is less than 7:
let estimate be ounces part of amount;
say "[estimate in words] or [estimate plus 1 in words] fluid ounces";
otherwise:
if tenths part of amount is greater than 6, increase amount by 1.0 fl oz;
say "about [ounces part of amount in words] fluid ounce[s]".
Before printing the name of a fluid container (called the target) while not drinking:
if the target is empty:
say "empty ";
otherwise:
do nothing.
After printing the name of a fluid container (called the target) while not examining:
unless the target is empty:
say " of [liquid of the target]";
omit contents in listing.
Instead of inserting something into a fluid container:
say "[The second noun] has too narrow a mouth to accept anything but liquids."
Definition: a fluid container is empty if the current volume of it is 0.0 fl oz. Definition: a fluid container is full if the current volume of it is the fluid capacity of it.
Instead of drinking a fluid container:
if the noun is empty:
say "There is no more [liquid of the noun] within." instead;
otherwise:
decrease the current volume of the noun by 0.2 fl oz;
if the current volume of the noun is less than 0.0 fl oz, now the current volume of the noun is 0.0 fl oz;
say "You take a sip of [the liquid of the noun][if the noun is empty], leaving [the noun] empty[end if]."
We have allowed all liquids to be drunk, but it would be possible also to add checking, if we had a game where some liquids were beverages and others were, say, motor oil.
Understand "pour [fluid container] in/into/on/onto [fluid container]" as pouring it into. Understand "empty [fluid container] into [fluid container]" as pouring it into. Understand "fill [fluid container] with/from [fluid container]" as pouring it into (with nouns reversed).
Understand "pour [something] in/into/on/onto [something]" as pouring it into. Understand "empty [something] into [something]" as pouring it into. Understand "fill [something] with/from [something]" as pouring it into (with nouns reversed).
Check pouring it into:
if the noun is not a fluid container, say "You can't pour [the noun]." instead;
if the second noun is not a fluid container, say "You can't pour liquids into [the second noun]." instead;
if the noun is the second noun, say "You can hardly pour [the noun] into itself." instead;
if the liquid of the noun is not the liquid of the second noun:
if the second noun is empty, now the liquid of the second noun is the liquid of the noun;
otherwise say "Mixing [the liquid of the noun] with [the liquid of the second noun] would give unsavory results." instead;
if the noun is empty, say "No more [liquid of the noun] remains in [the noun]." instead;
if the second noun is full, say "[The second noun] cannot contain any more than it already holds." instead.
Carry out pouring it into:
let available capacity be the fluid capacity of the second noun minus the current volume of the second noun;
if the available capacity is greater than the current volume of the noun, now the available capacity is the current volume of the noun;
increase the current volume of the second noun by available capacity;
decrease the current volume of the noun by available capacity.
Report pouring it into:
say "[if the noun is empty][The noun] is now empty;[otherwise][The noun] now contains [current volume of the noun in rough terms] of [liquid of the noun]; [end if]";
say "[the second noun] contains [current volume of the second noun in rough terms] of [liquid of the second noun][if the second noun is full], and is now full[end if]."
This is probably a drier description than we would actually want in our story, but it does allow us to see that the mechanics of the system are working, so we'll stick with this for the example.
Now we need a trick from a later chapter, which allows something to be described in terms of a property it has. This way, the story will understand not only "pitcher" and "glass" but also "pitcher of lemonade" and "glass of milk" -- and, indeed, "glass of lemonade", if we empty the glass and refill it with another substance:
Understand the liquid property as describing a fluid container. Understand "of" as a fluid container.
And now the scenario itself:
The Porch is a room. The porch swing is an enterable supporter in the Porch. "An inviting swing hangs here at the end of the porch, allowing you to enjoy the summer with a cool beverage, and watch your neighbor Ted mowing his lawn with the very last manual powerless lawnmower on the block."
The glass is a fluid container carried by the player. The liquid of the glass is milk. The current volume of the glass is 0.8 fl oz.
The pitcher is a fluid container in the Porch. The fluid capacity of the pitcher is 32.0 fl oz. The current volume of the pitcher is 20.0 fl oz. The liquid of the pitcher is lemonade.
Ted's Lawn is outside from the Porch. Ted is a man in Ted's Lawn. "Ted has taken off his shirt, but still seems a bit oppressed by the sun." The description of Ted is "He looks hot. In all senses."
Instead of doing something to Ted when the player is in the Porch: say "You can't really interact with Ted from this distance, except in the sense of eyeing him surreptitiously."
Instead of giving an empty fluid container to Ted: say "Yes, taunt the poor man, why don't you?"
Instead of giving a fluid container to Ted when the liquid of the noun is milk: say "Ted looks ruefully at the milk. 'Thanks, but I'm lactose-intolerant,' he says."
The block giving rule is not listed in the check giving it to rules.
Every turn:
if Ted is in the location:
if Ted carries a fluid container (called refreshment):
try Ted drinking the refreshment;
otherwise if a random chance of 1 in 3 succeeds:
say "Ted pushes the ineffective mower over some dandelions."
Instead of someone drinking a fluid container:
if the noun is empty:
try the person asked giving the noun to the player;
otherwise:
decrease the current volume of the noun by 2.0 fl oz;
if the current volume of the noun is less than 0.0 fl oz, now the current volume of the noun is 0.0 fl oz;
say "[The person asked] gulps down some [liquid of the noun]."
After someone giving something to the player:
say "'Here,' says [the person asked], handing [the noun] back to you. 'Thanks, I owe you one.'";
end the story finally.
Test me with "x milk / x lemonade / drink lemonade / drink milk / pour lemonade into glass / drink milk / x milk / drink milk / g / i / fill glass with lemonade / drink lemonade / drop glass / drink lemonade / pitcher".
Test Ted with "out / give milk to ted / drink milk / g / g / g / give glass to ted / in / fill glass with lemonade / out / give lemonade to ted / wait / z / z / z ".
ExampleSavannah |
Here we build very slightly on the existing liquid implementation to add a puzzle where the player puts out a fire with a bucket of water. Most of the liquid implementation remains the same as before, but now we understand the names of containers according to the liquids they contain.
The new material, pertaining to extinguishing fires, is at the bottom in section 2.
A volume is a kind of value. 15.9 fl oz specifies a volume with parts ounces and tenths (optional, preamble optional).
A fluid container is a kind of container. A fluid container has a volume called a fluid capacity. A fluid container has a volume called current volume.
The fluid capacity of a fluid container is usually 12.0 fl oz. The current volume of a fluid container is usually 0.0 fl oz.
Instead of examining a fluid container:
if the noun is empty,
say "You catch just a hint of [the liquid of the noun] at the bottom.";
otherwise
say "[The noun] contains [current volume of the noun in rough terms] of [liquid of the noun]."
To say (amount - a volume) in rough terms:
if the amount is less than 0.5 fl oz:
say "a swallow or two";
otherwise if tenths part of amount is greater than 3 and tenths part of amount is less than 7:
let estimate be ounces part of amount;
say "[estimate in words] or [estimate plus 1 in words] fluid ounces";
otherwise:
if tenths part of amount is greater than 6, increase amount by 1.0 fl oz;
say "about [ounces part of amount in words] fluid ounce[s]".
Before printing the name of a fluid container (called the target) while not drinking:
if the target is empty:
say "empty ";
otherwise:
do nothing.
After printing the name of a fluid container (called the target) while not examining:
unless the target is empty:
say " of [liquid of the target]";
omit contents in listing.
Instead of inserting something into a fluid container:
say "[The second noun] has too narrow a mouth to accept anything but liquids."
Definition: a fluid container is empty if the current volume of it is 0.0 fl oz. Definition: a fluid container is full if the current volume of it is the fluid capacity of it.
Instead of drinking a fluid container:
if the noun is empty:
say "There is no more [liquid of the noun] within." instead;
otherwise:
decrease the current volume of the noun by 0.2 fl oz;
if the current volume of the noun is less than 0.0 fl oz, now the current volume of the noun is 0.0 fl oz;
say "You take a sip of [the liquid of the noun][if the noun is empty], leaving [the noun] empty[end if]."
Understand "pour [fluid container] in/into/on/onto [fluid container]" as pouring it into. Understand "empty [fluid container] into [fluid container]" as pouring it into. Understand "fill [fluid container] with/from [fluid container]" as pouring it into (with nouns reversed).
Understand "pour [something] in/into/on/onto [something]" as pouring it into. Understand "empty [something] into [something]" as pouring it into. Understand "fill [something] with/from [something]" as pouring it into (with nouns reversed).
Check pouring it into:
if the noun is not a fluid container, say "You can't pour [the noun]." instead;
if the second noun is not a fluid container, say "You can't pour liquids into [the second noun]." instead;
if the noun is the second noun, say "You can hardly pour [the noun] into itself." instead;
if the liquid of the noun is not the liquid of the second noun:
if the second noun is empty, now the liquid of the second noun is the liquid of the noun;
otherwise say "Mixing [the liquid of the noun] with [the liquid of the second noun] would give unsavory results." instead;
if the noun is empty, say "No more [liquid of the noun] remains in [the noun]." instead;
if the second noun is full, say "[The second noun] cannot contain any more than it already holds." instead.
Carry out pouring it into:
let available capacity be the fluid capacity of the second noun minus the current volume of the second noun;
if the available capacity is greater than the current volume of the noun, now the available capacity is the current volume of the noun;
increase the current volume of the second noun by available capacity;
decrease the current volume of the noun by available capacity.
Report pouring it into:
say "[if the noun is empty][The noun] is now empty;[otherwise][The noun] now contains [current volume of the noun in rough terms] of [liquid of the noun]; [end if]";
say "[the second noun] contains [current volume of the second noun in rough terms] of [liquid of the second noun][if the second noun is full], and is now full[end if]."
Understand the liquid property as describing a fluid container. Understand "of" as a fluid container.
The Beach is a room. "The Atlantic stretches east to the horizon, though it is at low tide at the moment. It is dawn: time to pack up and go home."
We will skip implementing the Pacific ocean itself, though the example Lakeside Living shows how to incorporate large bodies of water into our liquid simulation.
The liquids are seawater. [We could include others, but for the moment...]
Instead of drinking a fluid container when the liquid of the noun is seawater:
say "Blech!"
The bucket is a fluid container carried by the player. The liquid of the bucket is seawater. The current volume of the bucket is 64.0 fl oz.
The fire is a fixed in place thing in the beach. "A low fire crackles here, left over from an attempt at s'mores much earlier in the evening."
Instead of touching or rubbing or taking the fire, say "You're not such a glutton for punishment."
Instead of pouring something into the fire:
now the fire is nowhere;
now the current volume of the noun is 0.0 fl oz;
say "[The second noun] goes out in a great hiss."
Test me with "drink seawater / pour seawater on fire / x bucket / i".
This is still a specific implementation: if we wanted to weave liquids together with a full-scale burning model (as in "In Fire or in Flood"), where pretty much any object in the game can be flaming (currently on fire) or damp (extinguished), we might generalize our rule to
Instead of pouring something into a flaming thing:
now the second noun is damp;
now the current volume of the noun is 0.0 fl oz;
say "[The second noun] goes out in a great hiss."
Of course, the merging of fire and liquids also raises the possibility of gasoline and explosives, of heating and boiling liquids, etc.: as always, it's wise to incorporate a simulation that is only as detailed as the game's interactions really justify.