In this scene, the player is in the middle of an endless forest. No matter what direction they decide to move in, they will still be in the forest. I don’t want to code in millions of different “rooms” acting as the forest because that will be cumbersome and Inform won’t allow rooms with the same name. I want to change the description to give the illusion that they are moving when they actually aren’t, and to the advance the story as they traverse the forest.
There are two good ways I can think of doing this.
The easiest is a text substitution, found in §5.7. Text with random alternatives. For instance, you can type:
Forest is a room. The description of Forest is "[one of]You are in a forest of twisty trees, all alike.[or]You are near a mystical brook, the source of all the weirdness in the forest.[or]You are in the deep forest. There are red-eyed things in the woods.[then at random]"
It will change the description every turn and then cycle through them randomly once they’ve seen them all.
A more complex but powerful way is to use scenes and/or tables. A good example of this is Day One, an example in the documentation. This example shows how to get the game to print an interesting message every turn and then end when it’s out of things to say. You could edit it by changing ‘every turn’ to ‘Report looking in Forest’ or ‘report going in Forest’.
To maintain the illusion of infinite rooms, you’d want to change the description every time the player moves.
This is one way:
Before going to the Forest: pick forest description. Forest is a room. To pick forest description: now the description of the Forest is the substituted form of "[one of]You are in a forest of twisty trees, all alike.[or]You are near a mystical brook, the source of all the weirdness in the forest.[or]You are in the deep forest. There are red-eyed things in the woods.[then at random]". Instead of going nowhere in the Forest: pick forest description; move the player to the Forest;
There’s more to do here. For example, you’d want to move all portable objects in the Forest off-stage every time the player moves. (Or else not allow them to drop anything there.)
If not disallowing dropping entirely, then rather than moving them actually off-stage, you should probably move them to a designated location (e.g. a treasure pit of something that lives nearby) so that they can later be recovered. (And they can be kept separate from objects off-stage for other reasons.) Dropping things in mazes to figure out their layout is a fairly standard trope, and otherwise this might get these objects permanently lost.
before going rule is not necessary unless there is a standard exit leading to the Forest – and unless that’s set up as a one-way exit then it will also lead out of the Forest, no matter how far you think you’ve travelled. Which might be convenient, but probably isn’t intended.
This is off the top of my head and I haven’t coded it out to see if it would work, but would ohuang1224 also be able to, broadly, create areas of the forest using number flags, without actually creating a large number of rooms or regions? Ie. “northDirection is a number that varies,” increment northDirection when the player tries to go north/decrement it when the player tries to go south, print the forest description based on, essentially, the player’s coordinates?
I know this would probably require a little additional code to catch attempts to go north if no north exit actually exists, but does this work on principle?
edit: hah, I suppose it does work on principle, jinx @FriendOfFred!
Re. the problem of dropping objects in an endless space that is actually a singe room, it’s possible to track the “location” of any dropped objects while staying in one room under the hood, moving them in and out of play as needed. See Example 271 “Dubai” in the docs.
Here’s some code I wrote a while ago (while thinking about different ways to procedurally generate mazes) that puts the player in an infinite Cartesian grid, with a couple of portable objects that can be dropped, walked away from, and returned to as expected. It would be straightforward to extend this to a space of as many dimensions as you want.
"Test" The Endless Grid is a room. "You are in an endless maze of featureless square rooms." Limbo is a room. A pair of bolt cutters is a thing in the Endless Grid. A bottle of vodka is a thing in the Endless Grid. North of The Endless Grid is The Endless Grid. South of The Endless Grid is The Endless Grid. East of The Endless Grid is The Endless Grid. West of The Endless Grid is The Endless Grid. The x-location number is a number that varies. The x-location number is 0. The y-location number is a number that varies. The y-location number is 0. A thing has a number called the object x-location. After dropping or taking a thing (called prop): now the object x-location of prop is the x-location number; continue the action. A thing has a number called the object y-location. After dropping or taking a thing (called prop): now the object y-location of prop is the y-location number; continue the action. Definition: a thing is present if (it is carried by the player or it is the player or (its object x-location is the x-location number and its object y-location is the y-location number)). After going a direction in The Endless Grid: now everything that is not present is in Limbo; now everything that is present in Limbo is in The Endless Grid; continue the action. Before going north in The Endless Grid: increment the y-location number. Before going south in The Endless Grid: decrement the y-location number. Before going east in The Endless Grid: increment the x-location number. Before going west in The Endless Grid: decrement the x-location number; [Some testing commands] Requesting the location is an action applying to nothing. Understand "loc" as requesting the location. Carry out requesting the location: say "You are at position ([x-location number],[y-location number])." Requesting the object location is an action applying to one thing. Understand "loc [anything]" as requesting the object location. Carry out requesting the object location: if the noun is carried by the player: now the object x-location of the noun is the x-location number; now the object y-location of the noun is the y-location number; say "[The noun] is at position ([object x-location of the noun],[object y-location of the noun]) [if the noun is present](present)[else](not present)[end if]. You are at position ([x-location number],[y-location number])." Understand the command "x" as something new. [To get nowhere fast - unfortunately an action can't apply to two numbers, so we need separate verbs for x and y dimensions] X-teleporting is an action applying to one number. Understand "x [number]" as x-teleporting. Carry out x-teleporting: now the x-location number is the number understood. Y-teleporting is an action applying to one number. Understand "y [number]" as y-teleporting. Carry out y-teleporting: now the y-location number is the number understood; try requesting the location. After deciding the scope of the player while requesting the object location: place the contents of Limbo in scope. A reaching inside rule while requesting the object location: rule succeeds.