let's play: Inform 10's Basic Inform and Standard Rules (SR: Variables and Rulebooks 7)

Would you say this dichotomy applies to “After not” as well? As I recall, this extension rulebook runs after an action was attempted but failed for some reason.

Ooh, what extension is that? I don’t think I’m familiar with that one.

After Not Doing Something by Ron Newcomb.

1 Like

Wow, yeah, that makes a lot of sense.

Edit: Actually, isn’t the carry out rule essentially the “only one can trigger” kind of “after” rule that we would need to have the two different kinds of rules?

I’m using Conversation Framework by Eric Eve, which uses “after” rules to print what the player says when talking to someone, but it seemed curious to me that it didn’t use a carry out rule for that.

I just realized I think I misunderstood carry out rules. I thought that only the most specific carry out rule was executed, but it doesn’t look like that’s the case. Just found a bug in my story because of it. :grin:

OK, yeah, actually I need to start a new topic for this…

Let’s keep going. Lots of commentary from GN, which is great, because we won’t necessarily be engaging with a lot of these rules, which operate at the Inter level. Many also function outside of the game proper in any case. There are some exceptions, of course.

Just to keep things tidy, we’ll stop just before action processing.

Variables and Rulebooks 3

§21. Rules. At run-time, the value of a rule is the (packed) address of an I6 routine. In the case of rules created in I7 source text, the body of the rule definition is compiled by Inform to a new I6 routine which carries it out. But there are also primitive rules which are implemented in the template I6 layer, and these need no I7 source text definitions: instead we simply tell Inform the name of the I6 routine which will be handling this rule, and that it need not bother to create one for itself.

As indicated earlier, a lot of these primitives have no real natural language substance to them beyond their names. We will have a hard time debugging anything that occurs before the virtual machine starts, which is fine. At such an early point, we would be debugging the interpreter rather than the game.

An example of this is provided by the first rule we shall create: the “little-used do nothing rule”. This is aptly named on both counts. We never follow it, we never put it into any rulebook. It exists only so that variables and properties with the kind of value “rule” can be initialised automatically to a safely neutral default value. It makes no decision.

Section 2 - The Standard Rules

The little-used do nothing rule translates into Inter as "LITTLE_USED_DO_NOTHING_R".

This is the starting point, since it makes it possible for other rules to initialize. We can safely invoke it:

last report jumping:
	follow the little-used do nothing rule

but, as promised, it does nothing.


§22. Startup. Every rulebook contains a (possibly empty) run of “first” rules, then a (possibly empty) run of miscellaneous rules, then a (possibly empty) run of “last” rules. It’s unusual to have more than one rule anchored to either end as “first” or “last”, but entirely legal, and we make use of that ability here.

The “first” rules here are the ones which get the basic machinery working to the point where it is safe to run arbitrary I7 source text. They necessarily do very low-level things, and it is not guaranteed that I7 phrases will behave to specification if executed before these early rules have finished. So it is hazardous to obstruct or alter them.

Lots of commentary here. I’ll try to feel my way through it.

This indicates an organization strategy. As we’ll see below, rules are listed in a specific order (which matters) but are additionally specified as first and last (which matters a bit more).

  • (a) The “initialise memory rule” starts up the memory allocation heap, if there is one, and sets some essential I6 variables. If there is any rule not to meddle with, this is it.

If there is any rule not to meddle with, this is it. Seems like good advice when it comes to something called the “initialise memory rule”!


  • (b) The “virtual machine startup rule” carries out necessary steps to begin execution on the virtual machine in use: this entails relatively little on the Z-machine versions 5 or 8, but can involve extensive work to get the screen display working on Glulx or Z6. Before anything else happens, however, the “starting the virtual machine” activity (see below) is carried out.

The typical natural language author is probably not thinking about, say, version 5 of the Z-machine, but I think this is the second indication of something operating differently between Z-machine and Glulx (the other had to do with memory, I believe).

However. However! There is no further mention of the starting the virtual machineactivity in this section, nor is there one in the activities section of the Standard Rules! Instead, we’ll have to look back at Basic Inform to find the activity and its corresponding rulebook.

Why belabor this point? Diagnosing the startup of an Inform program (rather than an iterpreter) will likely begin after starting the virtual machine. I got this code from @Zed; I use it all the time!

debug-verbosity is a kind of value.
The debug-verbosities are rules off, rules on, rules all.
To debug (dv - a debug-verbosity): (- debug_rules = ({dv} - 1); -)

after starting the virtual machine:
	debug rules on;

on is usually enough for me, though I’ve looked at all output a few times.

  • (c) The “seed random number generator rule” seeds the RNG to a fixed value if Inform has requested this (which it does in response to the -rng command line switch, which is in turn used by the intest testing utility: it’s a way to make deterministic tests of programs which use random values).

In the typical case, authors won’t be compiling Inform programs at the command line. I imagine this is the equivalent of setting the “Make random outcomes predictable when testing” option within the Inform 10 IDE.


If we manually seed the RNG during runtime, it doesn’t visibly trigger this rule, or any other. This code:

before jumping:
	say line break;
	say "yes!";
	seed the random-number generator with 11;
	say "yes!!!!!";

generates this debug output (partial)

[Rule "before jumping" applies.]

yes!
yes!!!!!

[Rule "basic visibility rule" applies.]

So while these might seem like comparable cases, this is likely a distinction between seeding at compile vs seeding during runtime.

  • (d) The “update chronological records rule” is described in further detail below, since it appears both here and also in the turn sequence rulebook. Here it’s providing us with a baseline of initial truths from which we can later assess conditions such as “the marble door has been open”. A subtle and questionable point of the design is that this rule is placed at a time when the object representing the player is not present in the model world. This is done to avoid regarding the initial situation as one of the turns for purposes of a rule preamble like “… when the player has been in the Dining Room for three turns”. It’s as if the player teleports into an already-existing world, like some Star Trek crewman, just in time for the first command.

This is interesting stuff! An Inform feature I really enjoy is its ability to consider previous world states. Judging from conversations I’ve seen, I’m not sure how often authors take advantage of these options. There are limitations, of course. We can also verify whether or not an actor has performed a specific action. Inform can’t handle past-tense phrases about actions with multiple nouns, which is a shame.

The invocation of this rule, here, captures the current state of the world model. Later, it updates after the Advance Time rule: authors should be finished with world state in the current turn by then.


  • (e) All items begin unmentioned, as might be expected.

Yet another default-setting rule.

  • (f) And the “position player in model world rule” completes the initial construction of the spatial model world.

If we explicitly state that the player is [a person in a declaration, this presumably situates them (and perhaps moves yourself off-stage? I’m not certain about this)

e: there’s a lot more to it than this! see below.

  • (g) The “start in the correct scenes rule” ensures that we start out in the correct scenes. (This can’t wait, because it’s just conceivable that somebody has written a rule with a preamble like “When play begins during the Hunting Season…”: it’s also where the scene Entire Game begins.) That completes the necessary preliminaries before ordinary I7 rules can be run.

A last bit of scene-setting (heh) to make sure things start correctly. It’s fairly common to start a game with something like

the opening act begins when the entire game begins

…and scene changes occur outside of action processing, right (I had a hard time wrapping my head around this)? By the time play begins, it may be too late.

The start in the correct scenes rule is listed first in the startup rulebook. th.
The position player in model world rule is listed first in the startup rulebook. th.
This is the declare everything initially unmentioned rule:
    repeat with item running through things:
        now the item is not mentioned.
The declare everything initially unmentioned rule is listed first in the startup rulebook. th
The update chronological records rule is listed first in the startup rulebook. th.
The seed random number generator rule is listed first in the startup rulebook. rd.
The virtual machine startup rule is listed first in the startup rulebook. nd.
The initialise memory rule is listed first in the startup rulebook. st.

The virtual machine startup rule translates into Inter as "VIRTUAL_MACHINE_STARTUP_R".
The initialise memory rule translates into Inter as "INITIALISE_MEMORY_R".
The seed random number generator rule translates into Inter as "SEED_RANDOM_NUMBER_GENERATOR_R".
The update chronological records rule translates into Inter as "UPDATE_CHRONOLOGICAL_RECORDS_R".
The position player in model world rule translates into Inter as "POSITION_PLAYER_IN_MODEL_R".

This is the start in the correct scenes rule: follow the scene changing rules.

§23. The remaining rules, though, are fair game for alteration, and as if to prove the point they are all written in standard I7 source text. Note that the baseline score is set only after the when play begins rulebook has finished, because games starting with a non-zero score normally do this by changing the score in a when play begins rule: and we don’t want such a change to be notified to the player as if it has happened through some action.

Now that there is a there from which the program operates, there are at last some rules that authors might engage with at the natural language level.

the when play begins stage rule fires off the when play begins rules. I haven’t take a survey, but I think a lot of authors make their own when play begins rules. It’s a good place for an opening crawl, for instance, or for manipulating objects or values.

The fix baseline scoring rule prevents scoring notifications when the game begins with a score greater than zero. For instance:

when play begins:
	now the score is 350;

It isn’t desirable for the game to start with a message, “Your score has gone up by 350 points,” so this heads that off.

I have never printed the banner text when it displays by default. I always delay it by a bit. This isn’t hard. We can delist it, for instance

the display banner rule is not listed in any rulebook.

Then launch it when we like:

when the opening scene ends:
	follow the display banner rule

for example.

The initial room description rule triggers the looking action, so we can do something after this “first look” if we want

report looking in lab for the first time:
	say "Wow, what a lab!"

As promised, these are “safe” rules for authorial intervention. At least, that’s been my experience.

The when play begins stage rule is listed in the startup rulebook.
The fix baseline scoring rule is listed in the startup rulebook.
The display banner rule is listed in the startup rulebook.
The initial room description rule is listed in the startup rulebook.

This is the when play begins stage rule: follow the when play begins rulebook.

This is the fix baseline scoring rule: now the last notified score is the score.

This is the display banner rule: say "[banner text]".

This is the initial room description rule: try looking

I think I’ll stop for today, as this feels like a manageable chunk. Next up: the turn sequence.

3 Likes

That will improve in Inform 11, for the very few situations where it matters!

Does Inform support Z5 any more? I thought that stopped when text was unified with indexed text, which means every non-trivial project needs a memory heap.

I’d say it’s the other way around: this rule calls “seed the random-number generator with 1234” or the like. The rule is just a way of inserting that phrase into the appropriate place in the rulebook.

What this rule does is:

  • let the player-to-be be the player
  • now the player is yourself
  • now the location-to-be is the location of the player-to-be
  • if the location-to-be is nothing, move the player-to-be to the first room defined
  • otherwise move the player-to-be to the location-to-be
  • if the player is not the player-to-be: now yourself is nowhere, now the player is the player-to-be
  • initialize various other variables, like the location, the presence of light, the actor, and the positions of backdrops

Indeed! Scene changes are processed at a few different points during the turn, and the intended effect to the author is that scenes start/end exactly when their conditions become true, rather than waiting for the player to do something.

1 Like

There are some substantial changes to these rules in Inform 11, though they’ll be more relevant for extension authors. See the evolution proposal.

I don’t know if Z5 is supported, but Z5 and Z8 have the same amount of RAM, Z8 just lets you have more code. From the memory requirements of the memory heap they’re the same. I just don’t know if there’s so much default code now that it won’t fit in Z5.

2 Likes

Your basic one-room no-code I7 game blew past the z5 code limit way back in Inform 7 release 6M62. (Inform 9.3, that is.)

% ./inform +code_path=build -E0 -v8 ‘$OMIT_UNUSED_ROUTINES=1’ -w src/i7-min-6M62-z.inf

Resulting file is 304128 bytes.

3 Likes

That makes sense! Thanks.

A lot more than I had guessed! I’ll add a link to this post.

Let’s keep moving! I have a work in progress that has become my new obsession, so it’s hard to tear myself away, but I’m ready to get back to this.

I am not sure about a few things today, but hopefully some forum members can offer guidance.

Standard Rules: Variables and Rulebooks 4

§24. The turn sequence. In each turn, a command is read and parsed from the keyboard, and any action(s) that requested is or are processed. (And may in turn cause other actions, which must also be processed.) There is then a fair amount of business needed to end one turn and get ready for another.

The turn sequences rulebook terminates early if deadflag becomes set at any point, so the last turn of play will be incomplete. Besides that consideration, it can also end early if the command for the turn was for an out-of-world action such as saving the game: in such cases, the “generate action rule” stops the rulebook once the action has been fully processed. All the same, play basically consists of running down this list of rules over and over again.

OK! Now that the rulebooks have been declared, we can have a look at what happens, at a high level, between command prompts. We see a lot of these rules print during rules debugging. A lot of that information is rather opaque for newer authors–including me–but maybe we can figure some of that out.

As the documentation indicates, end the story sets deadflag, so there is a natural language option for accessing this.

§25. The “first” rules in the turn sequence cover us up to the end of the events which take place in the model world during this turn’s action(s).

Lots happening here! Let’s take things in bites.

  • (a) The “parse command rule” prints up the prompt, reads a command from the keyboard, parses it into dictionary words, deals with niceties such as UNDO or OOPS, and then runs it through the traditional I6 parser to turn it into a request for an action or list of actions. But see note below.

This isn’t something I’d intervene with, but it makes sense as a thing to come first! We might actually perceive it as last, because it prints before the command prompt, but that isn’t so.

  • (b) The “mentioned” property records whether something’s name has been printed since the last command.

Next, the mentioned property, which the printing the locale description uses, is reset.

  • (c) The “generate action rule” then either sends a single action to the action-processing rules, or else runs through the list, printing the noun up with a colon each time and then sending the action to the action-processing rules. But see note below.

I’m not certain what running through the list means.

E: it’s the multple object list! See below.

  • (d) We then run the scene changing rulebook, because people often write every turn rules which are predicated on particular scenes (“Every turn during the Grand Waltz: …”), and such rules will fail if we haven’t kept up with possible scene changes arising from something done in the action(s) just completed.

An item of recurring interest in this let’s play has been Inform’s scenes feature. Once again calling attention to Emily Short’s rules chart, a visual aid might help authors visualize where and when scene changes occur.

  • (e) The “every turn stage rule” follows the every turn rulebook. This earns its place among the “first” rules in order for it to have priority over all the other book-keeping rules at the end of a turn — including any which the user, or an extension included by the user, chooses to add to the turn sequence rules.

Does this mean priority by default? I can see that it’s easy to wedge something between scene-changing and every turn…

lab is a room.

the unending torment is a scene.
the unending torment begins when play begins.
the unending torment ends when we have jumped.

when the unending torment ends:
	say "I thought that would never end!";

this is the pointless rule:
	say "Frob!";
	
the pointless rule is listed before the every turn stage rule in the turn sequence rulebook.

every turn:
	say "Guncho!"

…so I perceive this as typical rulebook ordering business. Someone please tell me what I’m missing!

An unusual point here is that the “parse command rule” and the “generate action rule” are written such that they do nothing unless the turn sequence rulebook is being followed at the top level (by Main, that is). This prevents them from being used recursively, which would not work properly, and enables a popular trick from the time before the 2008 reform to keep working: we can simulate six turns going by in which the player does nothing by running “follow the turn sequence rules” six times in a row. Everything happens exactly as it should — the turn count, the time of day, timed events, and so on — except that no commands are read and no consequent actions generated.

I have seen the follow the turn sequence rules maneuver mentioned here on the forum, though I haven’t used it. However, I have needed to end the turn sequence early. This tactic is documented in the Timeless example from the documentation.

A first turn sequence rule (this is the every turn stage rule): follow the every turn rules. th.
A first turn sequence rule: follow the scene changing rules. th.
The generate action rule is listed first in the turn sequence rulebook. rd.
The declare everything initially unmentioned rule is listed first in the turn sequence rulebook. nd.
The parse command rule is listed first in the turn sequence rulebook. st

This has been a hard thing to search for online: what do the appending texts (th., rd., etc) mean? Is this a STEM thing? Apologies if I’ve missed an explanation somewhere.

ETA: it’s a bug in the way the html generation process! see below.


§26. Three miscellaneous things then happen, all implemented by primitives in the template I6 layer:

Onward! Even though these are implemented in I6, I think understanding their functions and timing is useful for natural language authors.

  • (e) The “timed events rule” is the one which causes other rules, keyed to particular times of day, to fire.

times of day is comingled with turn count at least once in the documentation, so this rule may cover future events generally rather than specifically clock times. I’m not certain.

  • (f) The “advance time rule” then causes the “time of day” global variable to advance by the duration of a single turn, which by default is 1 minute.

Here, minutes and turns are unambiguously handled by the same rule.

  • (g) The “update chronological records rule” tells the chronology machine that a slice of time has been completed. Inform can only decide past tense conditions like “the black door has been open” by continuously measuring the present to see if the black door is open now, and making a note for future reference if it is. But of course it’s impossible for any computer to continuously do anything, and besides, Inform has other calls on it. What in fact happens is that Inform performs these measurements at “chronology points”, which are strategic moments during play, and this is one of them.

I’ve referenced the documentation’s section on the past tense already, but it’s worth linking again. I confess that I’m a bit of an impatient reader, and I stopped reading the chapter on Time before the five sections about time of day, calculating times, and the like were over. I really missed out, as Inform’s tracking of world state beyond the now was entirely lost on me.

I believe this is one consideration with theacting fast technique: Inform isn’t going to update its historical records for property changes until a not-fast action is performed. I believe action successes get updated at time of success, so that’s a different matter.

This may have few practical implications, but I think it’s an important distinction nevertheless.

The timed events rule is listed in the turn sequence rulebook.
The advance time rule is listed in the turn sequence rulebook.
The update chronological records rule is listed in the turn sequence rulebook.

§27. We now come to the rules anchored at the end, using “last”. This part of the rulebook is reserved for book-keeping which has to happen positively at the end of the turn.

Let’s take a look at the far end of the rulebook.

  • (h) First, we check for scene changes again. We did this only a short while ago, but scene changes might well have arisen as a result of rules which fired during the every turn rulebook, or from timed events, or in some other way, and it’s important to start the next turn in the correct scene — so we check again to make sure.

This stage management makes sense. Scene changes serve as bookends to make sure things are in place.

  • (i) Then we run the “adjust light rule”. Keeping track of light and darkness is quite difficult, and potentially also quite slow: it’s not unlike a sort of discretised version of ray-tracing, with many light sources and barriers to think about (some transparent, some opaque). So we do this as little as possible: once per turn we calculate whether the player is in light or not, and act accordingly if so.

It might surprise authors—I am myself surprised—to learn of the demanding nature of light implementation in Inform games. Not because it doesn’t make sense, but because light so rarely comes up nowadays. Still, because players can be moved around at will, it tracks that this needs to be understood at a global level. Because lit can change during action processing, I am guessing that this is a bit like the chronological record, in that the property changes get moved into some larger body of data at turn’s end. Is that right?

I have no practical sense of light and darkness in Inform, though I have read the documentation regarding it. There isn’t a lot there.

  • (j) The “note object acquisitions rule” does two things:
  • (i) Gives the “handled” property to everything carried or worn by the player.
  • (ii) Changes the current player’s holdall in use, if necessary. (That’s to say: if the player has dropped his previous player’s holdall, we try to find a new one to use from his remaining possessions.)

(i) Is surprising. Without jumping ahead, I know that the taking action sets the handled property. I always associated it with an action rather than with other properties. This misunderstanding is on me; the documentation is unambiguous.

(ii) Must be an unusual case. Perhaps the player has both a makeup bag and a book bag, or otherwise can select from an assortment of containers. There must be other uses for this machinery. Or perhaps it is only there to prevent rare yet undesirable problems.

  • (k) The “notify score changes rule” tells the player if the score has changed during the turn, or rather, since the last time either this rule or the startup “fix baseline scoring rule” ran. (If the score were to change in the course of an out-of-world action, it would be notified a turn late, but of course out-of-world actions are not supposed to do that sort of thing.)

Like scene changing and light adjustment this rule is a way either respond to or record to changes across the turn. While I wouldn’t advise it, score can be updated in an instead rule. It could likewise update during every turn. It would be odd, but it could even update during scene changes. So this is in place to handle both usual and strange cases in a consistent way.

We can write our own score notification if we like; it’s in natural language.

A last turn sequence rule: follow the scene changing rules. rd from last.
The adjust light rule is listed last in the turn sequence rulebook. nd from last.
The note object acquisitions rule is listed last in the turn sequence rulebook. enultimate.
The notify score changes rule is listed last in the turn sequence rulebook. ast.

This is the notify score changes rule:
    if the score is not the last notified score:
        issue score notification message;
        now the last notified score is the score;

§28. That’s it, but we need to map these I7 rule names onto the names of their I6 primitives in the template layer.

Natural language authors won’t find much to do here. Inform 6 programmers might not, either. Here are the primitives for reference’s sake:

The adjust light rule translates into Inter as "ADJUST_LIGHT_R" with
    "[It] [are] [if story tense is present tense]now [end if]pitch dark in
    [if story tense is present tense]here[else]there[end if]!" (A).
The advance time rule translates into Inter as "ADVANCE_TIME_R".
The generate action rule translates into Inter as "GENERATE_ACTION_R" with
    "(considering the first sixteen objects only)[command clarification break]" (A),
    "Nothing to do!" (B).

The note object acquisitions rule translates into Inter as "NOTE_OBJECT_ACQUISITIONS_R".
The parse command rule translates into Inter as "PARSE_COMMAND_R".
The timed events rule translates into Inter as "TIMED_EVENTS_R"

That’s enough ground for today. But before closing. Let’s look at some debug information.

This project:

lab is a room.
	
use scoring.

apple is a thing.

after waiting:
	now the player carries the apple;
	continue the action;

generates this output (printed as table):

Rule Information Comment
>wait Command
[Rule declare everything initially unmentioned rule applies.] Discussed
[Rule generate action rule applies.] Discussed
[Rule announce items from multiple object lists rule applies.]
[Rule set pronouns from items from multiple object lists rule applies.]
[Rule before stage rule applies.]
[Rule basic visibility rule applies.]
[Rule basic accessibility rule applies.]
[Rule carrying requirements rule applies.]
[Rule instead stage rule applies.]
[Rule requested actions require persuasion rule applies.]
[Rule carry out requested actions rule applies.]
[Rule descend to specific action-processing rule applies.]
[Rule work out details of specific action rule applies.]
[Rule investigate player’s awareness before action rule applies.]
[Rule player aware of his own actions rule applies.]
[Rule check stage rule applies.]
[Rule carry out stage rule applies.]
[Rule after stage rule applies.]
[Rule after waiting applies.] our rule
[Rule investigate player’s awareness after action rule applies.]
[Rule report stage rule applies.]
[Rule standard report waiting rule applies.] our action
Time passes.
[Rule last specific action-processing rule applies.]
[Rule A first turn sequence rule applies.] discussed
[Rule scene change machinery rule applies.] discussed
[Rule every turn stage rule applies.] discussed
[Rule timed events rule applies.] discussed
[Rule advance time rule applies.] discussed
[Rule update chronological records rule applies.] discussed
[Rule A last turn sequence rule applies.] discussed
[Rule scene change machinery rule applies.] discussed
[Rule adjust light rule applies.] discussed
[Rule note object acquisitions rule applies.] discussed
[Rule notify score changes rule applies.] discussed
[Rule parse command rule applies.] discussed

Even though rules output may seem intimidating, we’ve already discussed a healthy chunk of it! By the end of this project, I’ll have a better handle on debugging things. Hopefully I won’t be the only one.

Next up: shutdown and then the action processing rules, the biggest missing piece of the debugging puzzle so far.

1 Like

This is rather interesting; I suspect that it allows, for example (admittely inspired from the RB), changing the failure message into ***YOU LOSE THE TRAIN*** if the player don’t embark on a famous british train.

1 Like

I believe this is for commands like take all which interestingly only takes one turn. Great shortcut if your lamp is running dim.

1 Like

This is an issue with the online version. If you open the SR in the IDE you’ll see that those are ordinal numbers to give the reader a tip as to the final position of the respective rules.

2 Likes

I think this is just in case someone adds a Turn Sequence rule: it will automatically go after all the “first” rules.

1 Like

The multiple object list, in this case. For commands like TAKE DIAMOND AND BAR AND COINS.

By default, yeah. It’s meant to keep people from accidentally breaking things when they add a rule to this rulebook without specifying its position.

It’s a bug in inweb—the ! character starts a comment in I6, but for some inscrutable reason if a ! is followed by certain characters inweb will delete both of them. It’s supposed to say “5th”, “4th”, “3rd”, “2nd”, and “1st”.

Indeed; “timed events” are those timers you set with “in 5 turns” or “at 3:00”.

I imagine the property gets set in both places specifically because authors might say “now the jacket is worn by the player” without thinking about “handled”.

It’s a pile of hacks on top of hacks, really.

Back when Inform was first being developed, inventory management was a Big Deal. If you wanted to let the player carry an unlimited number of things, for the sake of mimesis you were supposed to give the player a container (ideally wearable) that excess inventory would be stowed in, rather than letting them carry everything in their arms.

(You know how Moby Dick has a really weird epilogue that doesn’t really fit in with the rest, explaining how Ishmael got back to land to write the book, because readers complained that it was unrealistic for the book to be published if everyone died? It’s like that. Player’s holdalls require a lot of fiddly code and also make things more annoying for the player, but players in the 90s apparently found it easier to suspend their disbelief if the protagonist had an infinite-capacity backpack rather than infinite-capacity pockets.)

So the Inform 6 library lets you designate one container as the infinite-capacity backpack: the SACK_OBJECT constant.

In Inform 7, though, this approach doesn’t really work. Inform 7 didn’t actually have constants until fairly recently! So instead SACK_OBJECT is a variable, and any time the player is holding a “player’s holdall” that is not the SACK_OBJECT, the SACK_OBJECT is updated to match.

The end result is a mess that doesn’t really accomplish much, but needs to be maintained for historical reasons.

2 Likes

Ha! I read this an hour ago and I’m still laughing about it.

2 Likes

There must be a bug in whatever generates the HTML version that you’re looking at. In the actual code seen when you open the Standard Rules in the IDE, you’ll see that those are actually [1st], [2nd], [3rd], [4th], etc – in other words, they are comments that elucidate the actual order in which the rules end up being listed in the rulebook.

I’m not really sure what you’re trying to say here, but I guess the point of marking things handled as part of the turn sequence is so that things programmatically moved to the player still get marked.

Uhh, this is I7 code, not I6…

This sounds really confusing. What if you have three player’s holdalls? What if they aren’t infinite and have limited capacity and you just filled one up?

Ooh, interesting. I’ve only seen that bug before in I6 code. So the bug must be with how inweb renders comments, not how it parses them.

I think the I7 answer is “don’t do that”.

I don’t think that counts as an answer.