As with ordinary numbers, we can choose random units when this is useful:
"rBGH"
The Pharmaceutical Testing Facility is a room. "A [if the player is short]large [end if][if the player is tall]cramped [end if]white space with sterile counters and a[if the player is tall]n uncomfortable little[end if] stool. There is also a mirror, behind which someone must be watching you. But you can't see through to that."
A counter, a one-way mirror, and a stool are scenery in the Facility. The stool is an enterable supporter. The counter supports a plate.
Height is a kind of value. 5 feet 11 inches specifies a height. 5'11 specifies a height. A person has a height.
Definition: a person is tall if its height is 6 feet 0 inches or more.
Definition: a person is short if its height is 5 feet 4 inches or less.
When play begins:
now the height of the player is a random height between 5 feet 2 inches and 6 feet 4 inches;
now the right hand status line is "[height of player]".
Instead of examining the player:
say "You, Test Subject, are [height of the player] tall."
The growth pill is a kind of thing. A growth pill is always edible. The description is usually "It is leaf-green and has a reassuring logo of a curling vine on the side. Nothing to worry about, nothing at all." Two growth pills are on the plate.
After eating the growth pill:
increase the height of the player by 0 feet 6 inches;
say "Your spine does something frightening and painful, and you find yourself looking down on the room from a wholly new angle.";
try looking.
Test me with "examine me / eat pill / examine me / eat pill / examine me".
"Lethal Concentration"
A concentration is a kind of value. 200.9ppm specifies concentration. 200.9 ppm specifies concentration.
A room has a concentration called current concentration. A room has a concentration called former concentration.
Probability inverse is a number that varies. [This is expressed as an inverse of the actual probability of diffusion from one room to another, to avoid error.] Probability inverse is 20. [That is, any given molecule of gas has a 5% chance of leaving by a given doorway at any given minute. Probability inverse should never drop below 10, the maximum number of exits from the room.]
Every turn:
follow the diffusion rules.
The diffusion rules are a rulebook.
A diffusion rule (this is the gas movement rule):
repeat with space running through rooms:
let sum be 0.0 ppm;
repeat with way running through directions:
let second space be the room way from the space;
if second space is a room:
let difference be the former concentration of the second space minus the former concentration of the space;
increase sum by the difference;
let sum be sum divided by probability inverse;
now current concentration of the space is the former concentration of the space plus the sum.
A technical note: it would be possible to write "repeat with space running through rooms... repeat with second space running through rooms adjacent to the space" instead, but in practice this loops through all the rooms * all the rooms again * all the directions (to determine adjacency). Phrasing the loop this way omits the second multiplier. For a map of 25 rooms, this means that the loop runs 25 times faster than it would otherwise, and of course for a larger map the effect would be even more dramatic.
A diffusion rule (this is the resetting concentration rule):
repeat with space running through rooms:
now the former concentration of the space is the current concentration of the space.
The last diffusion rule (this is the lethal dosage rule):
if the current concentration of the location is greater than LC50:
say "The concentration in the air overpowers you...";
end the story;
otherwise:
if the current concentration of the location is greater than TLV-STEL:
say "You feel extremely uncomfortable in this environment."
Instead of doing something when the current concentration of the location is greater than TLV-STEL:
if going, continue the action;
say "You can't work in this environment: your eyes and nose sting and it hurts to breathe."
And, for testing purposes, a square grid of rooms:
Room 1A is west of Room 1B. Room 1B is west of Room 1C. Room 1C is west of Room 1D. Room 1D is west of Room 1E.
Room 2A is south of room 1A and west of Room 2B. Room 2B is west of Room 2C and south of Room 1B. Room 2C is west of Room 2D and south of Room 1C. Room 2D is west of Room 2E and south of Room 1D. Room 2E is south of Room 1E.
Room 3A is south of room 2A and west of Room 3B. Room 3B is west of Room 3C and south of Room 2B. Room 3C is west of Room 3D and south of Room 2C. Room 3D is west of Room 3E and south of Room 2D. Room 3E is south of Room 2E.
Room 4A is south of room 3A and west of Room 4B. Room 4B is west of Room 4C and south of Room 3B. Room 4C is west of Room 4D and south of Room 3C. Room 4D is west of Room 4E and south of Room 3D. Room 4E is south of Room 3E.
Room 5A is south of room 4A and west of Room 5B. Room 5B is west of Room 5C and south of Room 4B. Room 5C is west of Room 5D and south of Room 4C. Room 5D is west of Room 5E and south of Room 4D. Room 5E is south of Room 4E.
The former concentration of room 3C is 800.0 ppm.
For variety of testing, here is another room set-up, this time with some corridors and walls within; uncommenting it, and commenting out the connected grid, will let us explore what would happen in alternative cases, to prove to ourselves that the model works consistently.
[Room 1A is west of Room 1B. Room 1B is west of Room 1C. Room 1C is west of Room 1D. Room 1D is west of Room 1E.
Room 2A is west of Room 2B. Room 2B is west of Room 2C. Room 2C is west of Room 2D. Room 2D is west of Room 2E. Room 2E is south of Room 1E.
Room 3A is south of room 2A and west of Room 3B. Room 3B is west of Room 3C. Room 3C is west of Room 3D. Room 3D is west of Room 3E.
Room 4A is west of Room 4B. Room 4B is west of Room 4C. Room 4C is west of Room 4D. Room 4D is west of Room 4E. Room 4E is south of Room 3E.
Room 5A is south of room 4A and west of Room 5B. Room 5B is west of Room 5C and south of Room 4B. Room 5C is west of Room 5D and south of Room 4C. Room 5D is west of Room 5E and south of Room 4D. Room 5E is south of Room 4E.]
For the sake at least of seeing what's going on in the example, let's also provide the player with the means to view the gas diffusion graphically:
The status grid is a device carried by the player. The status grid is switched on.
Every turn:
try examining the grid.
Instead of examining the status grid:
say "[fixed letter spacing][bar][line break]";
say "|[state of room 1A]|[state of room 1B]|[state of room 1C]|[state of room 1D]|[state of room 1E]|[line break]";
say "[bar][line break]";
say "|[state of room 2A]|[state of room 2B]|[state of room 2C]|[state of room 2D]|[state of room 2E]|[line break]";
say "[bar][line break]";
say "|[state of room 3A]|[state of room 3B]|[state of room 3C]|[state of room 3D]|[state of room 3E]|[line break]";
say "[bar][line break]";
say "|[state of room 4A]|[state of room 4B]|[state of room 4C]|[state of room 4D]|[state of room 4E]|[line break]";
say "[bar][line break]";
say "|[state of room 5A]|[state of room 5B]|[state of room 5C]|[state of room 5D]|[state of room 5E]|[line break]";
say "[bar][variable letter spacing][line break]".
To say bar:
say "----------------------------------------------".
TLV is a concentration that varies. TLV is 30.0ppm. [Long-term exposure maximum, safe for 8 hours a day.]
TLV-STEL is a concentration that varies. TLV-STEL is 50.0ppm. [Short-term exposure maximum, safe for fifteen minutes max.]
TLV-C is a concentration that varies. TLV-C is 150.0ppm. [Absolute exposure ceiling.]
LC50 is a concentration that varies. LC50 is 300.0ppm. [Concentration at which 50 percent of test subjects die of exposure, usually expressed in terms of time and body weight; in our LC50 these are factored in for the player's weight for one minute.]
The values set for these would depend on the type of poisonous gas in question; we'd want to adjust appropriately.
To say state of (space - a room):
if the space is the location, say bold type;
if current concentration of space is less than 10.0ppm, say " ";
if current concentration of space is less than 100.0ppm, say " ";
say current concentration of space;
say roman type.
Now, in theory we might also want to account for sources and sinks, items that either inject poisonous gas into the environment or remove it again. For simplicity, we will assume that these contributions can also be calculated in ppm and that the total number of inert and poisonous gas molecules in a room never changes (so if poison gas molecules are added, an equal number of inert molecules are removed). If room pressure were able to change, our model would have to be improved, so let us assume for now that that never happens. We want this sink/source business to calculate before any other portion of the diffusion rulebook, so set it as a first diffusion rule.
A gas source is a kind of thing. A gas source has a concentration called the contribution. The contribution of a gas source is usually 30.0ppm.
Room 2B contains a gas source called a spigot. The contribution of the spigot is 50.0ppm. Room 5A contains a gas source.
A gas sink is a kind of thing. A gas sink has a concentration called the contribution. The contribution of a gas sink is usually 30.0ppm.
Room 5E contains a gas sink called a fan. The contribution of the fan is 80.0ppm.
The first diffusion rule (this is the sources and sinks rule):
follow the sources rule;
follow the sinks rule.
This is the sinks rule:
repeat with item running through gas sinks:
let space be the location of the item;
decrease the former concentration of the space by the contribution of the item;
if the former concentration of the space is less than 0.0ppm, now the former concentration of the space is 0.0ppm.
This is the sources rule:
repeat with second item running through gas sources:
let space be the location of the second item;
increase the former concentration of the space by the contribution of the second item;
if the former concentration of the space is less than 0.0ppm, now the former concentration of the space is 0.0ppm.
Test me with "z / z / z / z / z / z / z / z".
Suppose we have a landscape with a great deal of up and down variation, where GO UP and GO DOWN will be significant almost everywhere, and specifying them all individually a tremendous pain:
"Wonderland"
An altitude is a kind of value. 1000 feet specifies an altitude. A room has an altitude.
Definition: a room is low if its altitude is 3000 feet or less. Definition: a room is high if its altitude is 5000 feet or more.
Instead of going down:
if an adjacent room is lower than the location:
let the valley be the lowest adjacent room;
let the way be the best route from the location to the valley;
say "(that is, [way])[paragraph break]";
try going the way;
otherwise:
say "You're in a local valley: there's no down from here."
Instead of going up:
if an adjacent room is higher than the location:
let the peak be the highest adjacent room;
let the way be the best route from the location to the peak;
say "(that is, [way])[paragraph break]";
try going the way;
otherwise:
say "You're on a local peak."
Paradise is a room. Paradise has altitude 5400 feet. "A handsome parking lot, a picnic ground, and the Henry M. Jackson Memorial Visitor Center. The latter offers, for serious climbers, a hot shower; for nature enthusiasts, an interpretive museum; and for car-trippers, a gift shop selling canned slugs. All of which is a largely unsuccessful distraction from the peak of Mt. Rainier beyond."
Cougar Rock is southwest of Paradise. The altitude of Cougar Rock is 3180 feet. "Numerous individual campsites and (on the road inventively labeled 'F') a handful of larger campgrounds suitable for church groups and family reunions."
Longmire is southwest of Cougar Rock. It has altitude 2760 feet. "A tiny town: it has to offer a few groceries, a post office, and a lodge for people who do not care to camp, all built in a rustic Park Service way."
Panorama Point is north of Paradise. It has altitude 6800 feet. Camp Muir is north of Panorama Point. It has altitude 10188 feet. Columbia Crest is northwest of Camp Muir. It has altitude 14410 feet. St Andrews Rock is west of Columbia Crest. It has altitude 10992 feet. Camp Schuman is northeast of Columbia Crest. It has altitude 9510 feet.
Since Mount Rainier National Park runs to over 235,000 acres, we will omit the rest of the locations, but it does seem fair to give a little more credit to anyone who makes the summit:
Instead of going up in the highest room:
say "You're standing at the summit of Mt. Rainier, the highest point in the state of Washington. There is no up."
Test me with "up / up / up / down / down / up / up".
This is a slight variation on the previous gas diffusion example: the main difference is that gas preferentially moves towards lower rooms, and will gradually settle in the bottom floor. We do this by calculating the probability of movement separately for each pair of rooms.
"Lethal Concentration"
A concentration is a kind of value. 200.9ppm specifies concentration. 200.9 ppm specifies concentration.
A room has a concentration called current concentration. A room has a concentration called former concentration.
To decide what number is the probability inverse between (space - a room) and (second space - a room):
let guess be 20;
let way be the best route from space to second space;
if way is up, let guess be 50;
if way is down, let guess be 10;
if the guess is less than 10, decide on 10;
decide on guess.
If we wanted, we could introduce other concerns into the calculation here: open and closed doors, windows between rooms, rooms that are outdoors vs. those that are indoors, and so on. The possibilities are numerous, so we will stick with the simple principle that our poison gas sinks.
Every turn:
follow the diffusion rules.
The diffusion rules are a rulebook.
A diffusion rule (this is the gas movement rule):
repeat with space running through rooms:
let sum be 0.0 ppm;
repeat with way running through directions:
let second space be the room way from the space;
if second space is a room:
let incoming be the former concentration of the second space divided by the probability inverse between second space and space;
let outgoing be the former concentration of the space divided by the probability inverse between space and second space;
let difference be incoming minus outgoing;
increase sum by the difference;
now current concentration of the space is the former concentration of the space plus the sum.
A diffusion rule (this is the resetting concentration rule):
repeat with space running through rooms:
now the former concentration of the space is the current concentration of the space.
The last diffusion rule (this is the lethal dosage rule):
if the current concentration of the location is greater than LC50:
say "The concentration in the air overpowers you...";
end the story;
otherwise:
if the current concentration of the location is greater than TLV-STEL:
say "You feel extremely uncomfortable in this environment."
Instead of doing something when the current concentration of the location is greater than TLV-STEL:
if going, continue the action;
say "You can't work in this environment: your eyes and nose sting and it hurts to breathe."
Room 1A is west of Room 1B. Room 1B is west of Room 1C. Room 1C is west of Room 1D. Room 1D is west of Room 1E.
Room 2A is west of Room 2B and below room 1A. Room 2B is west of Room 2C and below Room 1B. Room 2C is west of Room 2D and below Room 1C. Room 2D is west of Room 2E and below Room 1D. Room 2E is south of Room 1E and below Room 1E.
The former concentration of Room 1C is 800.0 ppm.
The status grid is a device carried by the player. The status grid is switched on.
And just for fun, this time we'll make the grid prettier, too; but this will work only on the Z-machine setting, not Glulx.
Every turn:
try examining the grid.
Instead of examining the status grid:
say "[unicode box drawings light down and right][top bar][unicode box drawings light down and left][line break]";
say "[unicode box drawings light vertical]";
say "[state of room 1A][state of room 1B][state of room 1C][state of room 1D][state of room 1E] upstairs[line break]";
say "[unicode box drawings light vertical and right][middle bar][unicode box drawings light vertical and left][line break]";
say "[unicode box drawings light vertical]";
say "[state of room 2A][state of room 2B][state of room 2C][state of room 2D][state of room 2E] downstairs[line break]";
say "[unicode box drawings light up and right][bottom bar][unicode box drawings light up and left][variable letter spacing][line break]"
Include Unicode Character Names by Graham Nelson.
To say top bar:
repeat with N running from 1 to 9:
if the remainder after dividing N by 2 is 0, say "[unicode box drawings light down and horizontal]";
otherwise say "[unicode box drawings light horizontal]".
To say middle bar:
repeat with N running from 1 to 9:
if the remainder after dividing N by 2 is 0, say "[unicode box drawings light vertical and horizontal]";
otherwise say "[unicode box drawings light triple dash horizontal]".
To say bottom bar:
repeat with N running from 1 to 9:
if the remainder after dividing N by 2 is 0, say "[unicode box drawings light up and horizontal]";
otherwise say "[unicode box drawings light horizontal]".
TLV is a concentration that varies. TLV is 30.0ppm. [Long-term exposure maximum, safe for 8 hours a day.]
TLV-STEL is a concentration that varies. TLV-STEL is 50.0ppm. [Short-term exposure maximum, safe for fifteen minutes max.]
TLV-C is a concentration that varies. TLV-C is 150.0ppm. [Absolute exposure ceiling.]
LC50 is a concentration that varies. LC50 is 300.0ppm. [Concentration at which 50 percent of test subjects die of exposure, usually expressed in terms of time and body weight; in our LC50 these are factored in for the player's weight for one minute.]
Include Basic Screen Effects by Emily Short.
To say state of (space - a room):
if the current concentration of space is less than TLV, say blue letters;
if the current concentration of space is TLV, say blue letters;
if the current concentration of space is greater than TLV, say green letters;
if the current concentration of space is greater than TLV-STEL, say yellow letters;
if the current concentration of space is greater than TLV-C, say red letters;
say "[unicode square with diagonal crosshatch fill]";
say default letters;
say "[unicode box drawings light vertical]".
Test me with "z / z / z / z / z / z / z / z".