How do I not list hidden items?

Hello everyone.

As part of my game I have the game list the items the player is carrying when their score goes up by one. I don’t need to do this but rather than just removing the code, I wonder if there is a way to list differently. I’ve looked up lists but I can’t find the exact wording to get what I want.

In short, [the list of things enclosed by the player] will list even the things that are in an undiscovered pocket in something they are wearing, for example, the pocket and what’s inside.

I’d just like to print the inventory. I followed “Oyster Wide Shut” and wrote

[the list of things contained by the player]

but this is wrong.

I’m not quite sure if this is what you’re aiming for, but it seems to meet your description. You can make the pocket a part of the jacket. It won’t show up in the inventory, and nothing inside the pocket will show up either.

Laboratory is a room. 

The player wears the lab coat.

The pocket is part of the lab coat. The test tube is in the pocket.
3 Likes

B.J.‘s approach is likely best, but offering another idea just for completeness’ sake – you can also tell Inform to print the [list of things carried by the player], which does what it sounds like. In particular, it will exclude things that are worn, or things that are held by containers carried by the player, which may or may not be what you want.

Thank you @bjbest60.

I have a similar construction but not as efficiently coded.

I appreciate you taking the time to write.

That you @DeusIrae that’s the one I was after. I didn’t want people to see the hidden things they were carrying but unaware of.

Sure – though to be clear, this approach also means they won’t see some non-hidden things, say if they’re in transparent containers the player’s carting around. Again, that could be what you’re after, but wanted to flag that in case that creates issues!

The primary purpose of the list is to remind novice/unfamiliar players that they have stuff that could be important for solving other puzzles.

In the instance of the transparent containers, they should have seen what’s inside when they picked it up. It’s a sacrifice I’m willing to make for them also not being able to see stuff they’ve not found despite the fact that they are carrying it.

In my example the player wears a coat with a ticket in the pocket they have to search for to be ale to use. The game sort of guides them to wearing the coat but not to searching it.

I’m wary in general of schemes to keep things secret while having them in the location, 'cause there are too many ways for it to go wrong.

With the pocket as part of the jacket, the test tube doesn’t show up in inventory, but it’s still in scope. It’d be out of scope if the pocket were closed, but the pocket itself would still be in scope. And that a thing exists becomes easy to leak if it’s in scope, for instance through disambiguation messages.

Making the pocket a part is still a good approach, but I’d suggest having the pocket be off-stage until it’s discovered, at which point you have

now the pocket is part of the lab coat;

If you want to be really sneaky, you can have the pocket conceal the ticket until the player examines the pocket, or searches the pocket or the coat.

That way the player can’t successfully refer to the ticket in any command without first performing one of these three actions, even if they know or suspect that it’s there:

Rule for deciding the concealed possessions of the pocket when the pocket encloses the particular possession:
	if we are examining, decide no; [examining *the pocket* doesn't work here, since although action name is known at this point in parsing, the full action is still in the process of being constructed and the noun is unspecified]
	if we have examined the pocket,decide no;
	decide yes.
Instead of searching the coat, try examining the pocket.
Instead of searching the pocket, try examining the pocket.

With this in place, anything in the pocket is concealed exactly as if it weren’t there until the player has performed one of the specified actions- thereafter anything found or put in the pocket can be accessed as normal.

We can also ensure that inventory always includes any contents of the pocket once the ticket has been revealed:

Last carry out taking inventory when the player encloses the coat and the pocket conceals nothing (this is the list contents of the pocket rule):
	say "The coat pocket contains:[line break]" (A);
	list the contents of the pocket, with newlines, indented, including contents,
		giving inventory information, with extra indentation.
1 Like

That’s a good point @drpeterbatesuk .

I suspect I have this issue elsewhere but I will add this for sure and plan to do better in future.

Inform does make it genuinely difficult to hide things in situ in a watertight manner.

I think the concealment relation was intended to hide things from the player ‘as if they weren’t even there’ but, as you obliquely suggest, if the player is somehow able to take direct or indirect possession of a concealed item it will show up in inventory. This is perhaps the only way a concealed item differs from one removed from play in it’s degree of ‘hiddenness’. It’s easy to tweak the inventory listing rule so that it doesn’t list concealed things (and, by extension, their contents):

The print empty inventory rule is not listed in any rulebook.
The print standard inventory rule is not listed in any rulebook.
Carry out taking inventory (this is the hide indirectly held concealed things inventory rule):
	if the player has a described not scenery thing:
		say "[We] [are] carrying:[line break]" (A);
[Setting the 'not listing concealed items' option for the list writer will (paradoxically) not suppress DIRECTLY held concealed items (and, by extension their contents) - although it will suppress directly held undescribed and scenery items. We use the possession relation ('has') to exclude thing incorporated by the player]
		list the contents of the player, with newlines, indented, including contents, giving inventory information, not listing concealed items, with extra indentation;
	otherwise:
		say "[We] [are] empty-handed" (B);

but direct possessions that the player themself conceals- from others, but evidently not from themself- (and by extension, their contents) will still be listed. That shouldn’t be a practical issue because things are concealed by their holder, so if the player takes the holder into their possession the concealed item(s) are not direct possessions and will be suppressed from an inventory listing ‘tweaked’ not to list concealed things. Furthermore, it’s probably desirable that directly-held concealed items are not suppressed from inventory (although directly-held scenery and undescribed items are). With respect to the latter, it’s generally only when taking inventory on the first turn that undescribed items get the chance to be suppressed from inventory, as any undescribed items enclosed by the player are made described at the end of each turn.

It’s not too difficult to take matters one step further and suppress even directly-held concealed items from inventory- although this still leaves them in scope (for the player, not for NPCs):

The print empty inventory rule is not listed in any rulebook.
The print standard inventory rule is not listed in any rulebook.
Carry out taking inventory (this is the hide all concealed things inventory rule):
	if the player has a described unconcealed not scenery thing:
		say "[We] [are] carrying:[line break]" (A);
		now all things enclosed by the player are unmarked for listing;
		now all unconcealed described not scenery things had by the player are marked for listing; [To suppress ALL concealed items we need to use 'marked for listing' because setting the 'not listing concealed items' option for the list writer will (paradoxically) not suppress DIRECTLY held concealed items (and, by extension their contents) - although it will suppress directly held undescribed and scenery items. We use the possession relation ('has/had') to exclude from consideration things incorporated by the player]
		list the contents of the player, listing marked items only, with newlines, indented, including contents, giving inventory information, not listing concealed items, with extra indentation;
	otherwise:
		say "[We] [are] empty-handed" (B);

It’s instructional to list the standard rule as well as both alternative rules, so that all three produce output, and compare what is shown when things directly or indirectly held by the player are concealed, and/or undescribed and/or scenery.

Notable is that all things enclosed by a person who is themselves enclosed by the player (e.g. the direct and indirect possessions of a monkey carried by the player) are never listed, neither is anything which is a part of something, or anything enclosed by that part. This is because the subroutine the list-writer uses to list the contents of something (through the ‘including contents’ phrase option) only does so for containers and supporters and doesn’t consider parts at all. The only worn and carried things listed therefore are the direct possessions of the player. Similarly, if you illicitly move something through code to a possession of the player that is not a person, container or supporter that something will not appear in inventory.

So a fairly full answer to the oft-asked question ‘How do I stop something from appearing in inventory?’ might be:

  1. move it off-stage (or at least somewhere beyond the player’s scope ceiling) until it’s needed
  2. make it a part of the player or a part of something the player encloses
  3. move it to a person enclosed by the player
  4. move it to a supporter/container that is a part of something else enclosed by the player
  5. move it (illicitly through code) to something enclosed by the player that is none of person, container or supporter
  6. make it scenery or concealed and tweak the ‘carry out taking inventory rule’ to suppress concealed things
  7. write a custom ‘carry out taking inventory rule’ that specifically excludes that item (or a description of items)

To also keep said item out of scope and invisible:

  1. move it off-stage (or at least somewhere beyond the player’s scope ceiling)
  2. make it concealed (by something other than the player) or inside something concealed (by something other than the player)
  3. move it to a closed opaque container enclosed by the player
  4. move it (illicitly through code) to something opaque enclosed by the player that is none of person, container or supporter

Note that the immediate possessions of the player are ALWAYS in scope to the player- this is a basic tenet of the scope model not easy to circumvent without some minor I6 hacking. I7 makes it easy to directly add objects to scope, but not to remove them.

All these 4 manoeuvres will also

(i) prevent the hidden item being discovered should its (purported) holder be examined or searched. To allow discovery, the author must (if desired) supply code to remove or circumvent the method of hiding if these actions are taking (or have taken) place. However, a (readily fixable) bug currently causes concealing supporters or containers with no unconcealed contents to hint at their secret when their contents are listed (e.g. when examining) by announcing that on or in them is ‘nothing’. To work around this, either apply a fix for the bug or place an immovable unconcealed object on or in said supporter or container.
(ii) prevent the hidden item being included in ‘all’ for commands such as ‘take all’ (unless the command invokes a grammar token that bypasses scope, such as [any things], in which case making the hidden item undescribed will block this too- albeit this won’t work for things enclosed by the player)
(iii) prevent the hidden item being included in disambiguation questions (an object must be in scope to get as far as being included in a disambiguation list)

In most instances- although it may offend against the author’s sense of simulation- the well-established quick-and-dirty route is to completely hide objects by moving them to nowhere or to a ‘limbo room’ with no map connections.

In edge cases where this is not possible or undesirable (e.g. the inbuilt Inform door kind, which can’t be moved around, or when testing for the presence of the item in a specified room or other place is highly desirable) the other methods may be useful. A workaround for keeping objects off-stage while retaining the ability to easily check their ‘true position’ and/or return them to it, when their ‘true position’ is not fixed, is to give them a property that can be checked (called ‘true-position’ or similar), which is given the value of the ‘true’ holder of the object when they are moved off-stage.

The main advantage of the concealment option (apart from it not feeling like a ‘hack’) is that, being rule-based, it it very easy to set the conditions whereby the object is hidden or not, particularly if these are complex and changeable.

Other options are likely to be useful mainly when it is desirable for the hidden object to remain in scope.

In the index case that started this thread, the pocket as a part of the coat is perhaps a somewhat unnecessary complication unless it is required as an ongoing facility for things to be put into and taken out of. The standard very-quick-and-dirty approach would be to keep the ticket off-stage until the player examines or searches the coat and have an ‘Instead rule’ that announces the discovery, moves the ticket to the player’s possession and politely blocks further examination with ‘The pockets of the coat are empty.’, perhaps with another rule politely dissuading the player from trying to insert things into the (unsimulated) pocket. Having the pocket as an ongoing facility is a nice simulationist touch however, so I guess you pays your money and takes your choice on that.

There’s also that a truly empty scenery supporter doesn’t get a paragraph during room descriptions, but one with a concealed item gets a paragraph to say there’s nothing on it.

For everyone’s reference, the snippet below demonstrates all the shortcomings Dr. Bates and I are referring to.

A final issue with concealment is that those rules get checked over and over during scope-determination. WI 18.9 is one of few places the docs acknowledge speed issues, obliquely warning one that parsing could slow to a crawl if concealment decisions aren’t kept simple and quick.

I did write fixes for all of these world model issues (not the speed issue – see Scope Caching by Mike Ciul for that one). It was a bigger pain than it sounds. I suppose I should collect 'em and publish an extension, but it was this exercise that killed my enthusiasm for concealment and made me a devotee of just leaving things off-stage. (To no great surprise, I have another unpublished extension to facilitate managing revelation of off-stage items.)

or, my favorite: the nuclear option. Move it off-stage and use Scopability by Brady Garvin to mark it unscopable, ensuring it can’t be found even by grammar lines with an “[any thing]” token.

2 Likes

Undescribed and unscopable usually does the trick. That would be a useful extension, though; if the concealment relation worked properly, I would use it a lot more.

I’ll take a shot at it. The good news is that I could readily locate it. The bad news is that boy howdy does my ADHD manifest really clearly in my hobby programming sometimes, and carving out what’s actually useful and relevant will take some effort. :grinning:

1 Like

Digging into my old code reminded me of yet another concealment information leak: if you open a truly empty container, the default message is, e.g., “You open the box.” but if you open a container that’s empty but for one or more concealed items, it’s “You open the box, revealing nothing.”

Ugh. Here’s a wrinkle I had left undone last time: for containers with content, but all of whose contents are concealed I need customized inventory details and room description details activity rules to mimic the equivalent behavior of one that was truly empty.

At that point, would it be easier to just write a new “Definition: a container is apparently-empty” and use that instead of “empty” in those rules? Then you don’t have to duplicate all the code.

For those who are squeamish about I6 hacking the parser, you can make an off-stage thing both undescribed and privately-named: when you want the thing back in play, switch it to being described and switch on conditional name recognition 'Understand <<hidden-thing> name(s)>" as the <hidden-thing> when the <hidden-thing> is not off-stage.

Being undescribed (or scenery) keeps it from being considered by ‘all’-type commands that have access to [any things] without having to specify a name; being privately-named with no active ‘Understand…’ phrase keeps it from being accessed by [any thing], which will be looking for a named thing.

This is stuff that defaults to I6 code in WriteAfterEntry in ListWriter if not overridden by activity rules.

That’s obvious in hindsight but I never thought of it, and I’m bigger fan of privately-named and manual explicit Understand lines than many.

I’ve uploaded my new Concealer extension to my extensions repo. Right now, it doesn’t have any examples, meaningful documentation, or history of extensive testing to interfere with your enjoyment.

I guess my position here is to never use grammar lines with an “[any thing]” token. It’s too broad. You always have some kind of constraint. (Unless you’re writing a debug verb like “showme”, which really needs to scope every object.)

Like if the verb is “remember”, you’d make it “remember [any known thing]” (with Epistemology or some other “known” flag) so you could shift objects in or out of scope as needed.

3 Likes