Light traveling through rooms...

I’m learning Inform 7 by making a small game taking place on a pirate ship.

The current thing I’m tackling is trying to allow a light source to stretch through multiple rooms. Since on a pirate ship it’s mostly open space rather than by doors. However I don’t want the light source to travel vertically, just horizontally.

To simplify what I have:

room below decks is a kind of dark room.
ladder is a kind of open, unopenable door.

Storeroom is a room below decks. "This is the Storeroom".
Crew's Quarters is a room below decks. "This is the crew's quarters".
wooden ladder is a ladder. wooden ladder is above storeroom and below Crew's Quarters.

Capstan room is a room below decks. Capstan room is south of crew's quarters. "This is the capstan room".

Assuming the player drops their lantern in the crew’s quarters, I’d like to be able to see in the capstan room but not in the storeroom.

Also, how hard would it be to specify that the light will only stretch the length of one room?
For example if I added another room south of the capstan room, with the lantern dropped in crew’s quarters,
How difficult would it be to have the capstan room lit but the room further south dark?

A room below decks is a kind of dark room.
Before going from a room below decks, now every room below decks is dark.

Definition: a direction is horizontal if it is not up and it is not down.

Before going to a room below decks (called the place):
	repeat with d running through horizontal directions:
		let r be the room d from the place;
		if r is not nothing and r holds something which is lit, now place is lighted.



a ladder is a kind of open unopenable door.

Storeroom is a room below decks. "This is the Storeroom".
Crew's Quarters is a room below decks. "This is the crew's quarters".
Kitchen is south of the Capstan room. The kitchen is a room below decks.
the wooden ladder is a ladder. wooden ladder is above storeroom and below Crew's Quarters.

Capstan room is a room below decks. Capstan room is south of crew's quarters. "This is the capstan room".

The player is carrying a lantern. The lantern is lit.

This is not exactly idiomatic Inform 7, since it involves toggling values on and off rather than computing them. I’m not sure how to fix that issue. Any takers?

In a way, I think the idiomatic Inform 7 way of treating it would be to use visibility rules, as discussed in §12.19. But, as that section discusses, that doesn’t help with looking–the looking action is defined so as not to require light, and instead runs through the activities for printing the name of a dark room and printing the description of a dark room.

So you’d have to modify those two activities as well. It wouldn’t be too hard to modify the rule for printing the name of a dark room so as to print the room’s printed name instead when there was a light in the next room, but modifying the rule for printing the description of a dark room to work correctly would be a humongous and unnecessary pain, since the behavior of the looking action is very complicated. As far as I know there’s no bypass to make this activity go “Just print what you would print if the room were lighted.”

So… the short version is that there’s no idiomatic I7 way to handle this, because the calculation of lighting is handled at the I6 level and there’s no handy way to jump in and tell it “Hey, the room should actually count as being in darkness if there’s a light source in the next room.” Which means your approach, which toggles the lighted/dark property as you need, is surely the best.

The thing I would say is that I’m pretty sure that your approach will leave a trail of light behind you, because you don’t have a provision for making the room dark again when you take the light source away. I’d make a phrase to “update light belowdecks” or something like that, which could be triggered to calculate which rooms are supposed to be lighted and which dark, and which could be calculated whenever something happens that could change it (like going, or a light source failing, or something like that).

Well, there’s a Before statement that darkens all belowdecks rooms. Is that what you mean?

Of course, one problem is that it triggers when going from a room below decks but not other rooms, which doesn’t catch the case that you might be going from another kind of room with the lantern inside.

So that line would preferably read

Before going, now every room below decks is dark.

instead.

It’s a bit old-school now (especially using all those begin;s) but here is how Bronze handles next-room light sources: inform7.com/learn/eg/bronze/source_17.html

Alternate Lighting System allows this to be written using rules, though performance might take a hit.

Ooh, this is interesting. My solution is to create some scenery lights and move them around based on taking or dropping the lantern.

[rant=code][code]“Ambient Light Source”

A very bright lantern is carried by the player. It is lit. “This lantern casts extremely bright light in all directions.”

ambient light is a kind of thing. It is scenery. It is lit.“Light spills in here from [the best route from the location to the location of very bright lantern].”

There are 10 ambient lights.

Carry out dropping lantern:
repeat with place running through adjacent rooms:
now a random off-stage ambient light is in place.

Carry out taking lantern:
repeat with snuffed running through on-stage ambient lights:
now snuffed is off-stage.

after printing the name of a room:
if the location is dark:
if an ambient light is in the location:
say " (lit by ambient light from the [best route from the location to the location of very bright lantern])"

Dark Dungeon is a room. It is dark. “You can go north and south here.”

North Catacomb is north of Dark Dungeon. it is dark. “You can go south here.”

South Chamber is south of Dark Dungeon. It is dark. “You can go north here.”
[/code][/rant]

[rant=transcript]

[/rant]

I just lit one room in each direction, but if you make the ambient light a lit backdrop and each deck of your ship a region, you can similarly move the ambient light backdrop into the appropriate region where the lamp is and it will fill the region.

Ooh, I missed that rule. Teach me to talk about code without running it!

Also, I didn’t realize that your code works by only lighting up the room that you’re going to, if appropriate. What I was thinking of is that there are some circumstances in which you might want to know the lighting status of every room, or adjust it another time than at the Before going stage. For instance, if a light source can spontaneously turn off, you might need to recalculate the lighting even without going. Or if you have a rule like this:

Instead of going from a dark room to a dark room: say "You can't see the way to the next room."

you need to recalculate lighting all at once instead of just lighting up the new room when you get there. If you add this line to your code, you can’t get up the ladder, because the Storeroom gets darkened and the lantern in the Storeroom won’t light the Capstan.

But yeah, I missed that in your code completely!

Honestly, if I wrote this as a game, I’d probably end up doing a transcript first just to determine what issues I wanted the player to face. I know the OP just wants to play with it, but even if you’re going big it’s a nice scenario to ruminate on, you really could do a lot with it. Like, you could add Epistemology to make the player aware of something only if they’ve previously touched it, and then only if they’re aware just what room they’re in… you could add various light levels, even.

Thanks a lot for all the help! Really appreciate the community.

No problem, we’re happy to help.

Just a tip, though: if you want the same behavior to affect a whole bunch of rooms, you might consider putting them all inside a region.

There is a room called Vestibule. "This is the entrance to the greenhouse. Sunlight streams in through all the windows, but a faint breeze prevents the heat from becoming oppressive."

There is a room called Balmy Room. "Where the vestibule was pleasantly warm, this room is almost a sauna. All the windows are closed, and a sticky heat rises from the soil to hang mistlike in the air."

There is a room called Tomato House. "This area is packed with rows and rows of tomato plants, which grow tall and lush in the tropical air."

There is a room called Pathway. "A gravel path curves along this gentle slope, amids grass and boulders. To the north is the top of the hill, where the windows of the greenhouse gleam with reflected sunlight. To the south is the parking lot. A small path has been trampled in the tall grass to the west."

There is a room called Herb Gardens. "A neat, orderly herb garden grows here. There[']s thyme, coriander, basil, and a myriad stranger spices. Bees flit from flower to flower, and you can feel a breeze on your face."

There is a room called Pond. "A small wooden bench stands next to an artfully arranged pond. A solitary willow tree provides shade."

There is a room called Apiary. "This enclosure is bounded by a low fence. A double row of honeybee hives stand here, around which thick patches of lemon balm have been planted."

There is a room called Parking Lot. "This patch of gravel serves as a parking lot for the area. A wooden plank rests over the low ditch to the north, allowing an intrepid customer access to the greenhouse."

North of Vestibule is Balmy Room.
South of Vestibule is Pathway.
North of Balmy Room is Tomato House.
South of Pathway is Parking Lot.
West of Pathway is Herb Gardens.
North of Herb Gardens is Apiary.
West of Herb Gardens is Pond.

Greenhouse Environs is a region. Herb Gardens, Pond, Pathway, Apiary and Parking Lot are in the Greenhouse Environs.
Greenhouse Interior is a region. Vestibule, Tomato House and Balmy Room are in the Greenhouse Interior.

The sun, the sky, the clouds and the wind are backdrops. Instead of doing something other than examining with a backdrop (called phenomenon), say "[The phenomenon] [are] beyond reach." 
The description of the sun is "High and bright in the sky."
The description of the sky is "A blue expanse dotted with white clouds."
The description of the clouds is "Thankfully, not the rainy kind."
The description of the wind is "A soft breeze on your skin."

The sun, the clouds, the sky, and the wind are in the Greenhouse Environs.


Every turn when the player is in the Greenhouse Environs, say "You hear the whisper of the wind and the buzzing of bees."
Every turn when the player is in the Greenhouse Interior, say "You feel warm and clammy."

Above is just a quick example to show you how regions can be used to quickly divide the game up into areas where the same rules apply. That way, you don’t need a lot of code to create a whole slew of behaviors that only occur within a given region.

I believe it would be more efficient to accomplish this with a single backdrop whose position is updated dynamically.

Using a scenario from other people in this thread:

[rant=code][code]A room below decks is a kind of dark room.

A ladder is a kind of open unopenable door.

Storeroom is a room below decks. “This is the Storeroom.”
Crew’s Quarters is a room below decks. “This is the crew’s quarters.”
Kitchen is a room below decks, south of the Capstan room.
The wooden ladder is a ladder, above storeroom and below Crew’s Quarters.

Capstan room is a room below decks, south of Crew’s quarters. “This is the capstan room.”

A very bright lantern is carried by the player. “This lantern casts extremely bright light in all directions.”
It is lit.
Understand “light” and “lamp” as the lantern.

The ambient light is a backdrop. “Light spills in here from [nearby].”
It is lit.
The indefinite article is “some”.

Definition: a room is penumbral:
[not too close or too far]
unless (the number of moves from it to the location of the bright lantern, using doors) is 1, decide no;
let way be the best route from it to the location of the bright lantern, using doors;
if the door (way) from it is an open door, decide yes;
if the room (way) from it is the location of the bright lantern, decide yes;
decide no.

After dropping the lantern:
move the ambient light backdrop to all penumbral rooms;
continue the action.

After taking the lantern:
now the ambient light is nowhere;
continue the action.

After printing the name of a room when the location is dark and the ambient light is in the location:
say " (lit by ambient light from [nearby])"

To say nearby:
let way be the best route from the location to the location of the very bright lantern, using doors;
if way is a direction:
if way is down:
say “below”;
otherwise if way is up:
say “above”;
otherwise if way is outside or way is inside:
say way;
otherwise:
say the way;
otherwise:
say “nearby”.[/code][/rant]

[rant=Transcript]Storeroom
This is the Storeroom.

You can see a wooden ladder here.

drop lamp
Dropped.

u

Crew’s Quarters (lit by ambient light from below)
This is the crew’s quarters.

You can see a wooden ladder here.

x light
Light spills in here from below.

s

Darkness
It is pitch dark, and you can’t see a thing.

n

Crew’s Quarters (lit by ambient light from below)
This is the crew’s quarters.

You can see a wooden ladder here.

d

Storeroom
This is the Storeroom.

You can see a wooden ladder and a very bright lantern (providing light) here.

get lamp
Taken.

u

Crew’s Quarters
This is the crew’s quarters.

You can see a wooden ladder here.

drop lamp
Dropped.

l
Crew’s Quarters
This is the crew’s quarters.

You can see a very bright lantern (providing light) and a wooden ladder here.

d

Storeroom (lit by ambient light from above)
This is the Storeroom.

You can see a wooden ladder here.

x light
Light spills in here from above.

u

Crew’s Quarters
This is the crew’s quarters.

You can see a wooden ladder and a very bright lantern (providing light) here.

s

Capstan room (lit by ambient light from the north)
This is the capstan room.

x light
Light spills in here from the north.[/rant]

Ooo! ChrisC! Very elegant, and a great use of regions.

Ooo, that’s pretty.

In fact, the only potential snag I can see is that it hard-codes the light source to be the lantern, which may be nonideal in a bigger game.

Correct. That’s thing to keep in mind, small vs. large projects: simplicity vs. scaling up and efficiency.

If you have multiple flooding lights, you’re going to want to define them as a kind of thing (or an adjective on things), so they can be iterated through. You’ll want to use “carry out dropping” and “carry out taking” rules for them, adding “an actor” if multiple people will be moving lights around, or maybe even use every turn rules instead if they’re moved around by code. You’ll need to update backdrop positions in these rules, in case the player’s lighting situation changes out of their control. And the [nearby] text token will need to list the directions to all nearby flooding lights, not just one.

Yeah, sometimes, going too far into generalities will mess things up. I recall experimenting with darkness and drafting some kind of representation of the amount of light held by each room, so that each room’s volume and propensity for absorbing light would matter. Light inside containers would “leak” and diffuse, etc. Turned out rather a lot of work for what was in the end a fairly naff result.

That’s the thing about Inform 7 that drives some people nuts but I love: there’s no one specific way to accomplish a task. There can be clunky code and elegant code and they will both work in different instances. I had never thought about “light leaking” to another room and the question inspired me to come up with a slightly different implementation that I will use in the future and would have used in a previous game if I had thought of it!

Some people write source texts that are incredibly enjoyable to read and well documented and therefore instructive. Emily Short and Ryan Veeder are two authors that come to mind who notate their source code wonderfully.