In-Line Topical Hints by Andrew Schultz


PURPOSE

In-Line Topical Hints is meant to circumnavigate hint menus, which can break immersion for the player. Also, it tries to keep unwieldy hint menus under control. While it offers progressive hinting, it also tries not to overwhelm the reader with text. The basic use case is that a player asks for hints and is given a list of potential topics. Then he types the topic number, and he can type H to see the next hint. By default, hints are shown one at a time if the player requests them continually, but if the player performs a few actions and comes back, the whole list is shown again. This is what the extension terms flexible hinting. The programmer can also force the default to showing all hints in a topic or only the last one, but the player can override these with special commands.

There are two ways for a programmer to decide whether to display a specific hint topics. You can either label it active to inactive, or you can make it rule-based and create a rule whether you can display them. If you are comfortable with rules, it may be smoother for you to establish a rule (e.g. if escape hatch is visited and typed-security-code is false).

One special case worth mentioning is if there is only one available hint topic. HINT AUTO lets the player toggle whether to skip to the hint in the topic or to avoid spoilers. The default is to avoid spoilers, but the programmer can change this by setting the hint-auto flag to true.

So if hint-auto is set to true, and a player tries hints, and there is only one available hint topic, the game chooses that. If not, the player is offered an option from one to the available number of hint topics. Whichever number they choose, they see the next hint they haven't seen yet. Once they choose that option, H goes to the next clue in the topic. It also, by default, only shows the next clue. The player can change this behavior if they want, but the point is to make the hints as unintrusive as possible.

One fine-tuning feature is that you are able to create a show-rule in a hint table. If this is left blank, the hint will always be shown. However, it can be changed to eliminate a hint the player should already know about. Let's take potential hints from a formerly popular RPG. While conditional text is possible, the player may appreciate having longer hint topics cut down as much as possible.

"You still need the bell, book and candle before continuing. That hint topic should be available." -- need-all-three rule
"You still need a party of eight players for the journey through the abyss. That hint topic should be available." -- need-all-eight rule
"You still need the mystic weapons and mystic armor. That hint topic should be available." -- need-weapons-and-armor rule
"[if have-everything]Okay, you're ready to enter the Abyss and get the Codex of Ultimate Wisdom[else]It's a long way down, and you'll be frustrated if you get to level 8 without auto-save and get rejected. Still, let's go ahead[end if]."

Another fine-tuning feature is to label certain hints topics noncritical. If the player just wants to win the game, they may not want to be distracted by a side quest this time around. By default, no hint topics are noncritical, but adjusting the hint-crit-only flag (default false) can change the default behavior, which is showing all hints. HINT CRIT will let the player toggle this at any time.

Also, feel free to modify the hint-usage and HINT VERBOSE documentation. I'd be interested how it could be tweaked.

Second of all, there are things you may wish to change and variables you may wish to set in a When Play Begins rule. These variables are listed below. There doesn't seem to be much reason to change them afterwards.

DEFAULTS POTENTIALLY WORTH CHANGING

See "Section Variables the player can change" in the source for this.

DEBUGGING WHICH HINTS APPEAR WHEN

One of the big problems with a hint system is that your testers can't tell you what's being hinted, when. Or if they do, it sort of spoils the game.

Some basic debugging is provided with In-Line Topical Hints so that you are able to verify a test walkthrough works. HINTDEBUG is a not-for-release command that prints out all the topics available every move. This is probably more useful for the programmer than a player, who may get overwhelmed with the text.

RECORDHINTS is available for the tester if they wish to create a text file of topics they would've seen. It is Glulx-only, since it requires output to a file. The format is >> (command): (List of topics).

ALLHINTNAMES simply shows all the hint names, so you can see if there are any egregious duplicates, or if one sticks out as out-of-place.

CREDITS

I'd like to thank Alice Grove, who tested this extension for inclusion in Delphina's House, which you should play, even if you ignore the hinting. Her suggestions and bug reports (technical and aesthetic) helped me focus on the big picture and also reminded me of scattered features I'd written up for myself but never written out formally.

PREVIOUS VERSIONS

1/150214 was part of Delphina's House and featured basic debugging, HA/HL and the basic commands. 2/150418 added debugging exported to a file. 2/200530 includes small tweaks by Gavin Lambert to fix some code that didn't compile in 6M62; also changed the hint-topic to be a kind of object rather than a thing so that it cannot possibly be confused with in-world things.

EXAMPLE

Example: ** Fetch Quest - A minimal game with hints, rule-dependent and not

"Fetch Quest" by Andrew Schultz

the story headline is "a minimal example".

there is no score in this story.

the print final score rule is not listed in any rulebook.

include In-Line Topical Hints by Andrew Schultz.

the bronze coin is a thing.
the silver coin is a thing.
the gold coin is a thing.

the description of a room is usually "[if number of viable directions is 1]The only exit leads[else]Exits lead[end if] [list of viable directions]."

definition: a direction (called di) is viable:
     if the room di of the location of the player is nothing, decide no;
     decide yes;

description of the player is "As good-looking as ever, but someone or something wrote something on you: N.GET ALL.S.E.GET ALL.W.W.GET ALL.E.S.".

check dropping:
     say "No way! The coin is too valuable, or something." instead;

Center Room is a room. "You can go north to the bronze room, east to the silver room, west to the gold room, or south to the glass room."

Bronze Room is north of Center Room.

check going nowhere:
     say "[if player is in center room]You can go any of the four directions[else]Only one way out[end if]."

Silver Room is east of Center Room. "You can go back west."

Gold Room is west of Center Room. "You can go back east."

Glass Room is south of Center Room. "You can go back north."

The bronze coin is in Bronze Room.

when play begins:
     now hint-crit-only is true;
     activate bronzy;

after taking the bronze coin:
     now the silver coin is in Silver Room;
     activate silvery;
     continue the action;

after taking the silver coin:
     now the gold coin is in Gold Room;
     activate goldy;
     continue the action;

after going to Glass Room:
     if player has gold coin:
         end the story saying "YOU GOT ALL THE LOOT, AND YOU ESCAPED!";
     continue the action;

bronzy is a hint-topic. printed name is "Finding the bronze coin".

hint-list of bronzy is table of bronzy hints.

table of bronzy hints
hint-text     done-yet     show-rule
"The bronze coin is not in the Center Room."     false     a rule
"It's in the bronze room."
"North of the Center Room."

silvery is a hint-topic. printed name is "Finding the silver coin".

hint-list of silvery is table of silvery hints.

table of silvery hints
hint-text     done-yet     show-rule
"The silver coin is somewhere in the maze."     false     a rule
"It's in the silver room."
"The silver room is east of the Center Room."

goldy is a hint-topic. printed name is "Finding the gold coin.".

hint-list of goldy is table of goldy hints.

table of goldy hints
hint-text     done-yet     show-rule
"The gold coin is somewhere in the maze."     false     a rule
"It's in the Gold Room."
"Gold Room is west of the Center Room."
"Once you get the gold coin, you can get out of the maze back at the Glass Room, south of the Center Room."

get-out is a rule-dependent hint-topic. printed name is "Getting out.".

hint-list of get-out is table of get-out hints.

table of get-out hints
hint-text     done-yet     show-rule
"There's one room left where nothing's turned up. Well, other than the center."     false     a rule
"Go south from the center."

avail-rule of get-out is the can-win rule.

this is the can-win rule:
     if the player has the gold coin, the rule succeeds;
     the rule fails.

is-this-easy is a noncritical active hint-topic. hint-list is table of is-easy hints. printed name is "Isn't this example too easy for a real game?"

table of is-easy hints
hint-text     done-yet     show-rule
"Yes, it is, but I was going for practicality."     false     a rule
"It didn't make sense to get too fancy."
"However, having good test cases is important, so here I'm making a semi-long hint topic to test that."
"There is nothing of value from here on out."
"I basically want a topic where I can test various behaviors in a long table, so I am sure nothing in my extension is broken."
"One more random hint should do it."
"There we go."

volume testing - not for release

test win with "n/get all/s/e/get all/w/w/get all/e/s"

test hprod with "hintdebug/n/get all/hint/topic 1/x me/topic 1"

test hintchange with "n/get all/s/hint/n/topic 1/topic 2"

test block with "hint block/hint/hint all/h/t/topic/topic 1/t 1/t1/1/hint block/hint all/hint review/hint one/hint recent/hint on/hint off/"

Example: *** Gems - a small game with strictly rule-based hints

"Gems" by Andrew

include In-Line Topical Hints by Andrew Schultz.

use scoring.

the maximum score is 6.

chapter define gems

a gem is a kind of thing. a gem has a direction called open-dir. a gem has a direction called start-dir. a gem has an object called in-item.

check dropping a gem:
     say "No. The gem is probably valuable[if score > 0]. Especially since you already did something with another gem[end if]." instead;

chapter which gems

chapter Branching Room

a room can be gemmish. a room is usually gemmish.

Branching Room is a not gemmish room.

the gaudy hatch is a supporter in Branching room. "A gaudy hatch blocks the way south. It seems to be indented. You can go any other way from west clockwise to east."

the blue hole is a container. the blue hole is part of the gaudy hatch.
the green hole is a container. the green hole is part of the gaudy hatch.
the white hole is a container. the white hole is part of the gaudy hatch.
the red hole is a container. the red hole is part of the gaudy hatch.
the yellow hole is a container. the yellow hole is part of the gaudy hatch.
the black hole is a container. the black hole is part of the gaudy hatch.

description of gaudy hatch is "The gaudy hatch has holes positioned in a half-circle: yellow[filled of yellow] on the left, then clockwise: blue[filled of blue], green[filled of green hole], red[filled of red hole], white[filled of white], and finally black[filled of black hole] below them all, opposite the red."

to say filled of (c - a container):
     if number of things in c is 1:
         say " (filled by the [random thing in c])";

chapter forest room

Forest Room is northwest of Branching Room.

chapter big sky room

Big Sky Room is north of Branching Room.

chapter lava room

Lava Room is west of Branching Room.

chapter snow room

Snow Room is east of Branching Room.

chapter sunlight room

Sunlight Room is northeast of Branching Room.

chapter going

check going when player is in Branching Room:
     if the room noun of Branching Room is nowhere:
         say "You can go south, or any direction clockwise from west to east." instead;
     repeat with Q running through gems:
         if open-dir of Q is noun:
             if in-item of Q encloses Q:
                 continue the action;
     say "An invisible force repels you." instead;

check going south when player is in Branching Room:
     if gaudy hatch is visible:
         say "The hatch blocks you." instead;
     say "You walk through the hatch to some place that grants you ultimate wisdom, or something.";
     end the story saying "YOU WIN";

chapter gems

check inserting a gem into:
     if second noun is gaudy hatch:
         if noun is onyx:
             say "There's only one hole left, so...";
             try inserting onyx into black hole instead;
         say "You may want to specify which hole." instead;
     if second noun is not in-item of noun:
         say "The [noun] doesn't fit there." instead;
     else:
         say "The [noun] fits in naturally.";
         increment the score;
         if score is 6:
             say "The hatch clicks open, revealing a way down.";
             now gaudy hatch is off-stage;

report inserting a gem into:
     do nothing instead;

check taking a gem:
     if noun is enclosed by in-item of noun:
         say "You can't pull it out." instead;

the sapphire is a gem. open-dir of sapphire is north. start-dir of sapphire is northwest. in-item of sapphire is blue hole.
the emerald is a gem. open-dir of emerald is northwest. start-dir of emerald is west. in-item of emerald is green hole.
the ruby is a gem. open-dir of ruby is west. start-dir of ruby is east. in-item of ruby is red hole.
the diamond is a gem. open-dir of diamond is east. start-dir of diamond is northeast. in-item of diamond is white hole.
the amethyst is a gem. open-dir of amethyst is northeast. start-dir of amethyst is north. in-item of amethyst is yellow hole.

the onyx is a gem. open-dir of onyx is south. in-item of onyx is black hole.

when play begins:
     move onyx to a random gemmish room;
     repeat with Q running through gems:
         if Q is not onyx:
             let J be the room start-dir of Q from Branching Room;
             if onyx is not in J:
                 now Q is in the room start-dir of Q from Branching Room;
             else:
                 now player carries Q;

volume hintsies

chapter emerald

emerald-hint is a rule-dependent hint-topic. printed name is "using the emerald"

avail-rule of emerald-hint is emerald-hint rule.

this is the emerald-hint rule:
     if emerald is in green hole:
         the rule fails;
     if player has emerald or location of emerald is visited:
         the rule succeeds;
     the rule fails;

hint-list of emerald-hint is table of emerald hints.

table of emerald hints
hint-text     done-yet     show-rule
"The emerald is a nice treasure, but you have no treasure horde."     false     a rule
"You can put the emerald in the green hole."

chapter amethyst

amethyst-hint is a rule-dependent hint-topic. printed name is "using the amethyst"

avail-rule of amethyst-hint is amethyst-hint rule.

this is the amethyst-hint rule:
     if amethyst is in yellow hole:
         the rule fails;
     if player has amethyst or location of amethyst is visited:
         the rule succeeds;

hint-list of amethyst-hint is table of amethyst hints.

table of amethyst hints
hint-text     done-yet     show-rule
"The amethyst is a nice treasure, but you have no treasure horde."     false     a rule
"You can put the amethyst in the yellow hole."

chapter sapphire

sapphire-hint is a rule-dependent hint-topic. printed name is "using the sapphire"

avail-rule of sapphire-hint is sapphire-hint rule.

this is the sapphire-hint rule:
     if sapphire is in blue hole:
         the rule fails;
     if player has sapphire or location of sapphire is visited:
         the rule succeeds;

hint-list of sapphire-hint is table of sapphire hints.

table of sapphire hints
hint-text     done-yet     show-rule
"The sapphire is a nice treasure, but you have no treasure horde."     false     a rule
"You can put the sapphire in the blue hole."

chapter diamond

diamond-hint is a rule-dependent hint-topic. printed name is "using the diamond"

avail-rule of diamond-hint is diamond-hint rule.

this is the diamond-hint rule:
     if diamond is in white hole:
         the rule fails;
     if player has diamond or location of diamond is visited:
         the rule succeeds;

hint-list of diamond-hint is table of diamond hints.

table of diamond hints
hint-text     done-yet     show-rule
"The diamond is a nice treasure, but you have no treasure horde."     false     a rule
"You can put the diamond in the white hole."

chapter ruby

ruby-hint is a rule-dependent hint-topic. printed name is "using the ruby"

avail-rule of ruby-hint is ruby-hint rule.

this is the ruby-hint rule:
     if ruby is in red hole:
         the rule fails;
     if player has ruby or location of ruby is visited:
         the rule succeeds;

hint-list of ruby-hint is table of ruby hints.

table of ruby hints
hint-text     done-yet     show-rule
"The ruby is a nice treasure, but you have no treasure horde."     false     a rule
"You can put the ruby in the red hole."

chapter onyx

onyx-hint is a rule-dependent hint-topic. printed name is "using the onyx"

avail-rule of onyx-hint is onyx-hint rule.

this is the onyx-hint rule:
     if onyx is in black hole:
         the rule fails;
     if player has onyx or location of onyx is visited:
         the rule succeeds;

hint-list of onyx-hint is table of onyx hints.

table of onyx hints
hint-text     done-yet     show-rule
"The onyx is a nice treasure, but you have no treasure horde."     false     a rule
"You can put the onyx in the black hole."

chapter hatch

hatch-opening is a hint-topic. hatch-opening is active. printed name of hatch-opening is "opening the hatch".

check opening the gaudy hatch:
     if onyx is in the black hole:
         say "Already is.";
     else:
         say "The hatch won't budge. You have no way to grip it.";
     the rule succeeds;

check closing the gaudy hatch:
     if onyx is in the black hole:
         say "You don't want to risk it locking again.";
     else:
         say "Already is.";
     the rule succeeds;

hint-list of hatch-opening is table of hatch hints.

table of hatch hints
hint-text     done-yet     show-rule
"The hatch's holes provide a clue what to do."
"Each one requires a different gem."
"Once you've put all the gems in the hatch, just go south."

chapter tests

test win-di with "put diamond in white/e/get ruby/w/put ruby in red/w/get emerald/e/put emerald in green/nw/get sapphire/se/put sapphire in blue/n/get amethyst/s/put amethyst in yellow/ne/get onyx/sw/put onyx in hatch/s"

test win-ru with "put ruby in red/w/get emerald/e/put emerald in green/nw/get sapphire/se/put sapphire in blue/n/get amethyst/s/put amethyst in yellow/ne/get diamond/sw/put diamond in white/e/get onyx/w/put onyx in black/s"

test win-am with "put amethyst in yellow/ne/get diamond/sw/put diamond in white/e/get ruby/w/put ruby in red/w/get emerald/e/put emerald in green/nw/get sapphire/se/put sapphire in blue/n/get onyx/s/put onyx in black/s"

test win-em with "e/put emerald in green/nw/get sapphire/se/put sapphire in blue/n/get amethyst/s/put amethyst in yellow/ne/get diamond/sw/put diamond in white/e/get ruby/w/put ruby in red/w/get onyx/e/put onyx in hatch/s"

test win-sa with "put sapphire in blue/n/get amethyst/s/put amethyst in yellow/ne/get diamond/sw/put diamond in white/e/get ruby/w/put ruby in red/w/get emerald/e/put emerald in green/nw/get onyx/se/put onyx in hatch/s"

test win-1 with "i/test win-di/test win-ru/test win-am/test win-em/test win-sa"