For those fluent in inform7, how long would it take you to implement Cloak of Darkness?

Starting from scratch, how long would it take you to code a working version of “Cloak of Darkness”.

1 Like

With no descriptions of any of the objects and no scenery, I’d say about one hour and most of it would be making the hook work. There’s be some bugs.

With “full polish” I’d say 3-4 hours and I’d need a friend to help play through it to find missing descriptions and bugs.

Edit: For those not familiar with Cloak of Darkness, these are the specifications:

The “Cloak of Darkness” specification

There are just three rooms and three objects.

  • The Foyer of the Opera House is where the game begins. This empty room has doors to the south and west, also an unusable exit to the north. There is nobody else around.
  • The Bar lies south of the Foyer, and is initially unlit. Trying to do anything other than return northwards results in a warning message about disturbing things in the dark.
  • On the wall of the Cloakroom, to the west of the Foyer, is fixed a small brass hook.
  • Taking an inventory of possessions reveals that the player is wearing a black velvet cloak which, upon examination, is found to be light-absorbent. The player can drop the cloak on the floor of the Cloakroom or, better, put it on the hook.
  • Returning to the Bar without the cloak reveals that the room is now lit. A message is scratched in the sawdust on the floor.
  • The message reads either “You have won” or “You have lost”, depending on how much it was disturbed by the player while the room was dark.
  • The act of reading the message ends the game.
  • And that’s all there is to it…
2 Likes

A bit less for me, if I was in a rush. Maybe two hours. Maybe that’s less polished than Brian’s version. :)

2 Likes

Thanks, I just started with Inform 7 and that gives me a good idea going forward.

1 Like

Apologies to Tom, as what I’m about to post won’t help you, but this thread reminded me I have something novel but kind of pointless up my sleeve: A version of Cloak of Darkness you can play via parser or choices, and switch during the game. Also with overkill screen reader support:
Cloak of Darkness two modes.gblorb (726.4 KB)
-Wade

4 Likes

The real question is…how long did it take to make? (also, it’s very cool, just checked it out)

2 Likes

Thanks. The truthful answer is – I can’t remember (EDIT - it’s dated 2015) but my gut feeling is Cloak didn’t take very long at all to put together. This game was an example project in my aborted CYOA/parser extension. I worked on the extension itself for months, but putting Cloak into it was really quick, shorter than producing any of the original examples.

Dragon’s Pass and Captain Piedaterre’s Blunders are two of the examples I released as standalone games. There are two unshared ones left. One’s another existential one about your last day of work that I’m not sure is any good. The last one was intended as an example of managing a complex inventory in choice mode and involves a fashion shoot on a picnic, but my memory is that Hanon is the only person alive who tried it, and he found it maddening. I think it may actually be funny to release it as a very deliberately annoying game. Like those Annoyotron games.

-Wade

3 Likes

Four minutes and sixteen seconds, apparently. I just improvised the descriptions since I don’t know what the canonical ones are supposed to be.

"Cloak Speedrun" by "Daniel Stelzer"

The Foyer of the Opera House is a room. "This is the foyer where you've just come in out of the rain. Doors lead south, west, and north.".

Instead of going north in the Foyer: say "But it's raining out there, and you just got dry!"

The Bar is south of the Foyer. It is dark. "This is the bar. It's empty with everyone gone for the night."

Some sawdust is fixed in place in the Bar. The sawdust can be scuffed. The sawdust is not scuffed.

Before doing anything except going north when the location is the Bar and in darkness:
	now the sawdust is scuffed;
	continue the action.

The Cloakroom is west of the Foyer. "This is the cloakroom. Also empty right now."

A small brass hook is fixed in place in the Cloakroom. It is a supporter.

The player wears a velvet cloak. The description of the cloak is "The light from the room seems to be drawn in and swallowed by the fabric."

Before going to the Bar:
	if the cloak is worn, now the Bar is dark;
	otherwise now the Bar is lit;
	continue the action.

Instead of examining the sawdust:
	say "There's a message spelled out here...";
	if the sawdust is scuffed, end the story saying "You have lost";
	otherwise end the story saying "You have won".
7 Likes

Impressive.

I wonder if Chat GPT could beat that. :thinking:

I’d never tried to implement the scenario before, so here’s another data point for you: 59 minutes and about 600 words (587 exactly, excluding comments) for the working and cursorily tested core mechanical scenario, skipping room descriptions and any auxiliary objects.

I expected it to take half that time. And when I try to imagine what it would look like when I was just starting out, it would be ten times as long, have taken days to complete, and probably have been full of unanticipated bugs.

As a potentially useful guide, here’s what I ended up using that I wouldn’t have understood then:

  1. the action processing cycle and the rulebooks involved (see WWI 7 Basic Actions, WWI 12 Advanced Actions and in particular WWI 12.2 How actions are processed)
  2. how rulebooks are processed and how to place rules within them (see WWI 19 Rulebooks and in particular WWI 19.4 Listing rules explicitly)
  3. how to set up a kind to represent generic doors (see WWI 4 Kinds, WWI 17 Understanding and in particular WWI 17.17 Context: understanding when and the only attempt to explain the item described in RB 2.2 Varying what is read)
  4. how to make use of the built-in best route phrase (see WWI 6.14 Adjacent rooms and routes through the map but note that the second example substitution given there includes an illegal comma)
  5. how to create a kind of action and to build rules excepting that kind (see WWI 7.9 All actions and exceptional actions and WWI 7.15 Kinds of action)
  6. how to manage multiple endings (see WWI 9.4 When play ends)
  7. how to use a random <description> in conjunction with relations (see WWI 8.19 Random choices of things and WWI 13.8 The built-in verbs and their meanings)
  8. how to add a new verb to the parser without creating a new action for it (see WWI 17.2 New commands for old grammar)
  9. how to expose a particular bit of information within internal parser variables for use at the I7 level (see WWI 11.17 Phrases to decide other things, WWI 27.16 Phrases to decide in Inform 6, Parser.i6t and DM4… or don’t)

It would be interesting to see several different implementations by various authors side-by-side for comparison.

EDIT: Since everyone else in the Mad Scientists’ Club has been brave enough to publish theirs, I’ll add mine:

Cloak
"Cloak" by "Otis the Dog"

There is a room called The Foyer of the Opera House.

A door called the main entrance is north of the Foyer. "The double doors of the main entrance lie to the north." Understand "double" or "doors" or "exit" as the main entrance.

[several minutes spent on these rules because of oddities related to doors leading nowhere and the way going through doors translates into actions]
This is the stuck here rule:
	say "You came in because you fancy a drink. You're not leaving without one."

Instead of going the main entrance:
	abide by the stuck here rule.

Instead of going north in Foyer:
	abide by the stuck here rule.

To decide which object is the prospective noun:
	(- parser_results-->INP1_PRES -). [even "fluent" users might not know this trick]

A typical door is a kind of door. The printed name of typical door is usually "door to the [door route to item described]". Understand "[direction]" or "to the [direction]" as a typical door when the prospective noun is the door route to the item described.

[a nicety that cost some time due to need to use phrase options]
To decide which direction is door route to (D - door):
	decide on the best route from the location to the other side of D, using doors.

[typical rabbit hole activity; couldn't leave out these valid adjectives]
Understand "northern" as a typical door when the door route to the item described is north.
Understand "eastern" as a typical door when the door route to the item described is east.
Understand "southern" as a typical door when the door route to the item described is south.
Understand "western" as a typical door when the door route to the item described is west.

South of the Foyer is a typical door called a door to the south.

South of door to the south is a room called The Bar.

[wanted easy extensibility for other potentially disturbance-exempt behavior, e.g. looking or waiting]
Going north is disturbless behavior.

[had to investigate I6 output to figure out best way to phrase these rules; really didn't want to track state with special-purpose properties or globals but did anyway]
Before doing something other than disturbless behavior (this is the Bar warning rule):
	if message is not pre-warned and the player is in dark Bar:
		say "I don't know... messing about in the dark could result in something being disturbed. Maybe it would be better to just go back north.";
		now the message is pre-warned;
		stop the action.

Before doing something other than disturbless behavior (this is the Bar consequence rule):
	if message is pre-warned undisturbed and the player is in dark Bar:
		now the message is disturbed.

A fixed in place thing called a message is in The Bar. "A message[if disturbed], somewhat disturbed by a careless passer-by, [end if] is scratched into the sawdust here." The message can be disturbed or undisturbed. The message can be pre-warned. The description of the message is "It reads:".

After examining the disturbed message:
	end the story saying "You have lost."

After examining the undisturbed message:
	end the story finally saying "You have won."

A typical door called a door to the west is west of Foyer.

The Cloakroom is west of door to the west.

[this is not robust, but there is exactly one movable item (the cloak) in the basic scenario]
A fixed in place supporter called a small brass hook is in the Cloakroom. "A small brass hook is attached to the wall here[if the hook supports something]. [A random thing supported by hook] hangs from it[end if]."

Understand "hang [something preferably held] on [hook]" as putting it on.

The player wears a black velvet cloak. The description of the cloak is "A splendid fuligin hue. It's curiously light-absorbent when even trace amounts of alcohol are in the air."

[not a formal requirement of the scenario but seemed reasonable]
Instead of dropping the cloak:
	say "Surely there's somewhere proper to leave it in this establishment." 

[took a several minutes to work out the best way to handle lighting puzzle]
First carry out going to the Bar while the player encloses the cloak:
	now the Bar is dark.

Last carry out going from the Bar while the Bar does not enclose the cloak:
	now the Bar is lighted.

As a follow-up for fellow mad scientists (and interested spectators), there were two features I had intended to use that did not end up working as expected and that I abandoned for time reasons. (… but of course felt compelled to come back to dig into later.)

The first issue popped up while trying to use a rule based on the action variable door gone through (see Standard Rules) for blocking use of the main entrance.

stumbling block 1

The issue seems to arise from interactions resulting from my implementation of it as a “one-sided door” and some compiler assumptions about the logic of going through doors. The preamble:

Instead of going north through the main entrance:

looks like it should work but doesn’t. The reason is that the I7 compiler builds a condition into the I6 translation that wants the room gone to to be a room, and for one-sided doors this will be set to nothing. Since the built-in debugging tools weren’t very informative here, my first thought was that the issue was specifying north. However, the preamble:

Instead of going through the main entrance:

doesn’t work correctly, either. After looking at the I6 and decoding the problem, some experimentation shows that:

Instead of going nowhere through the main entrance:

works, which allows the logic preventing use of that door to be covered by just one rule. It seems that the I7 compiler understands that going nowhere means there will not be a room gone to and the I6 translation is adjusted to expect the room gone through to be nothing accordingly.

Due to the hardcoded inclusion of a check for a non-nothing noun if no noun is specified, the above doesn’t seem to entirely accord with the special note for rulebook sorting Law III.3.2 as described in WWI 19.16 The Laws for Sorting Rulebooks, which says:

In the case of “going” actions, the first noun is a direction. The special constraint “going nowhere” (which means: a direction in which the actor’s location has no map connection) is considered more general than any other constraint placed on the first noun, but more specific than having no constraint at all. Thus “Instead of going north” beats “Instead of going nowhere” which beats “Instead of going”.

The second issue popped up while trying to make use of “number of times” conditions to handle the warning about disturbing things in the dark.

stumbling block 2

While the preamble:

Before doing something other than disturbless behavior in dark Bar the first time (this is the Bar warning rule):

may seem natural but is actually ambiguous, and the way that the first time works is that it applies to the entirety of the rest of the condition (… or so I thought based on past experience). As a result the I6 predicate generated is broader than intended, and the first automatic looking action at startup (as well as almost any other action) triggers it. (This is correct behavior, but it still catches me off-guard quite frequently when I try to use these types of conditions. I7 is not a DWIM compiler of English.)

Really looking at the generated I6 in detail (and some more experimentation) showed that – to my surprise – the first time does not actually apply to the entire condition, it applies to the rest of the “described action” (an internal construct of the compiler) that includes it. It’s therefore possible to construct the preamble condition a little more carefully (using compound conditions and parentheses) so that the first time applies only where it is desired to.

That said, it still wasn’t easy because of the way that times and turns are functionally defined by the generated I6 code. I ended up getting what I wanted after much additional experimentation, by making use of a previously-underappreciated mode of past-tense tracking for kinds of action.

@TomTAP: Those are new things that I learned due to your question, so thank you for asking it!

6 Likes

About 90 minutes.

The Foyer of the Opera House is a room. "This empty room has doors to the south and west, also an unusable exit to the north. There is nobody else around.".

The Bar is a dark room. "A message is scratched in the sawdust on the floor." It is south of the Foyer.
The Cloakroom is a room. "A long disused cloakroom. [if the first thing held by the hook is nothing]A bare small brass hook is on the wall.[end if]".
It is west of the Foyer.
Understand "foyer door", "east door", "open door", "doorway" as the cloakroom-door when the location is the Cloakroom.

After deciding the scope of the player when the location is the bar:
  place the bar-door in scope.

A fake door is a kind of backdrop.
A fake door is usually privately-named.
understand "door", "doorway" as a fake door.
Instead of closing a fake door, say "Best to leave it open.".
Instead of opening a fake door, say "It's already open.".
The unusable exit is scenery in the foyer. "The ceiling above the corridor collapsed long ago, and the passage is unusable."
Understand "north exit" as the unusable exit.

The bar-door is a fake door. "[if the bar is dark]A passage into darkness[else]The way to the Bar[end if].".
It is in Foyer. It is in Bar.

Visibility for examining the bar-door when the location is the bar and the bar is dark:
rule fails.

Carry out examining the bar-door when the location is the bar:
  if the bar is dark, say "The only source of light is through the doorway to the north, back to the Foyer.";
  else say "The doorway back to the Foyer.";
  stop the action;

Understand "south door" as the bar-door when the location is the foyer.
Understand "bar door" as the bar-door when the bar is visited.
Understand "north door", "foyer door" as the bar-door when the location is the bar.


The cloakroom-door is a fake door. It is in Foyer. It is in Cloakroom.
Understand "cloakroom", "door", "west door" as the cloakroom-door when the location is the Foyer.
Understand "foyer", "east door" as the cloakroom-door when the location is the Cloakroom.
Before entering the cloakroom-door when the location is the foyer, instead try going west.
Before entering the cloakroom-door when the location is the cloakroom, instead try going east.
Before entering the bar-door when the location is the foyer, instead try going south.
Before entering the bar-door when the location is the bar, instead try going north.

For printing the name of the cloakroom-door: say "the door to the [If the location is the foyer]cloakroom[else]foyer[end if]".
Understand "bare" as the small brass hook when the first thing held by the small brass hook is nothing.
After examining the message, end the story finally.

Instead of going nowhere when the location is the foyer and the noun is north:
  say the description of the unusable exit;
  say line break.

For printing the description of a dark room when the location is the bar: say "It's pitch black; the only thing you can see is the doorway back north to the Foyer."

The bar has a number called disturbance.

Instead of going nowhere when the location is the bar and the bar is dark:
increment disturbance of the bar;
say "There's too much risk of disturbing things in the dark to do anything but return north."

Carry out going when the room gone to is the bar:
  if the player encloses the cloak, now the bar is dark;
  else now the bar is lit.

The message is scenery in the Bar. Description is "[We] [have] [if the disturbance of the bar > 1]lost[else]won[end if]."

Understand "floor", "sawdust" as the message.

Understand "return" as going.

The small brass hook is a scenery supporter. "Perfect for hanging cloaks." It is in the Cloakroom.

The black velvet cloak is a thing. Description is "It's so dark, it seems to be sucking in all the light around it.".

The player wears the black velvet cloak.
4 Likes

Speed-creating “Cloak of Darkness” should totally be a thing. Including Youtube speedruns and World Championship matches.

3 Likes

Also, FYI – RB Ex 291 is an implementation of “Cloak of Darkness” that may be of interest.

1 Like

yes, I was more interested to see what others (who are fluent) could do as a benchmark. While I appreciate all the interest, some that I see (perhaps because of speeding through) are not full implementations.

Ah, damn, did I miss something? That’s what I get for speedrunning.

What’s missing?

not looking at yours specifically, but you get more credit if you win while the cloak is on the hook. Many suggest that means winning with 2 points. You can also win with one point if you drop the cloak on the cloakroom floor. One should be able to either drop, hang, take, or wear (while in the cloakroom). One should not be able to take the hook.

I didn’t see those on the page I got the specifications from; is there a list somewhere that includes more detail?

I’ve been trying to get ChatGPT to help me learn/write Inform 7, and while it is usually right about what can be done, it is often very, very wrong when it comes to the code.

Countless Inform authors feel its pain.

3 Likes

For those unfamiliar, “Cloak of Darkness” is intended as the “Hello World” for evaluating text game authoring systems to determine whether some generally simple and slightly more advanced concepts are possible to pull off and how easily they can be implemented. It also can serve as a tutorial and a demonstration for a new system.

Other versions:
Quest (annotated)
TextureWriter
TADS
Twine (Chapbook)
Dialog
Undum

4 Likes