Completely hidden objects?

Here’s some Inform 7 code from my current project (it’s borrowed from some almost identical code I used for Weird City Interloper):

A thing can be known or unknown. A thing is usually unknown.

Understand "[any visible known thing]" as investigating.

To say investigation failure:
	say "You don't know about any such thing."
	
Rule for printing a parser error when the latest parser error is the not a verb I recognise error:
	say investigation failure.

Rule for printing a parser error when the latest parser error is the noun did not make sense in that context error:
	say investigation failure.

Rule for printing a parser error when the latest parser error is the didn't understand error or the latest parser error is the can't use multiple objects error:
	say investigation failure.
	
Rule for printing a parser error when the latest parser error is the only understood as far as error:
	say investigation failure.

Carry out investigating a thing (called the target):
	say "[the description of the target][line break]".

That little Understand "[any visible known thing] as" is doing a lot of heavy lifting here, it makes the game throw an error if you try referring to any object in this context that isn’t “known”. I just have to write an appropriately broad response to all those errors. :slight_smile: And, crucially, the game doesn’t suggest any “unknown” objects when disambiguating.

Now, I’ve tried to implement something similar in Dialog… First of all I added some prevent rules to stop my investigate verb from working unless ($obj is known). Easy! But I still need to stop the game from mentioning unknown things when disambiguating. The standard library includes the is hidden property which almost does that

But flagging every single object in my game as hidden until I reveal it seems like a big ask. I mean, I could use an exhaust statement, but I’d sooner do something smarter. I’ve tried inverting “is hidden” into “is known” (stdlib-known.dg (153.4 KB)), but it didn’t seem to work… Objects are suggested for disambiguation whether (* is known) or not.

And the other issue is that if every disambiguation match is for a hidden object, then Dialog suggests them all, when I want it to not suggest any of them…

TLDR: how can I completely hide an object from disambiguation? Ideally, how can I completely hide it from anything until I want to reveal it?

(On a small scale, I’d do this by moving objects in from out of play, but I want almost all objects in my game to be in this state until revealed, while keeping them correctly nested…)

Example game for stdlib.dg
(current player #player)
(#player is #in #room)
(room #room)

#RedFish
(name *) red fish
(* is hidden)
(* is #in #room)

#GreenFish
(name *) green fish
(* is hidden)
(* is #in #room)

#BlueFish
(name *) blue fish
(* is hidden)
(* is #in #room)

> X FISH
Did you want to examine the red fish, the blue fish, or the green fish?

No! Don’t suggest any fish! They’re all hidden! :sob:

Example game for stdlib-known.dg
(current player #player)
(#player is #in #room)
(room #room)

#RedFish
(name *) red fish
(* is known)
(* is #in #room)

#GreenFish
(name *) green fish
(* is #in #room)

#BlueFish
(name *) blue fish
(* is #in #room)

> X FISH
Did you want to examine the red fish, the blue fish, or the green fish?

No! Assume I meant the red fish! It’s the only one that’s known! :sob:

The purpose of ($ is hidden) in Dialog is to allow the player to refer to the object if they can do so unambiguously, just not to have the game mention it. For example, the smoke alarm in Miss Gosling is available the first time you go into the dining room (you can TAKE SMOKE ALARM and then it’s treated like any other object in the game), but it won’t be mentioned at all until it goes off (in room descriptions, disambiguation, etc).

Is that what you want here? Or do you not want it to be able to be referred to at all, explicitly or not?

1 Like

Correct.

I don’t have any time left to experiment for a while, but having rubber ducked you all, I believe it may be that I want to add a condition to the ($Obj is in scope) predicates…

i was about to respond with the same suggestion. add a (known $Obj) predicate to ($Obj is in scope) in stdlib.

1 Like

Yeah, I think removing it from scope will do what you want, in that case. In Inform you also have to worry about the parser filling in a noun when there’s exactly one possibility (e.g. > GET when there’s one takable thing in the room), but Dialog’s parser doesn’t do that without explicit confirmation from the player, iirc.

1 Like

first let’s briefly discuss the inescapable tangential approach, the use of monologue in debugging. I use the always-present inanimate object here, that is, this very machine. hence the classical stereotype, the coder literally talking to his machine.
(tangentially on tangential, this is an interesting puzzle…)

now, on the hidden object. I think that Pacian’s problem is also one of the well-known generic IF cheat, exploiting that the “not in vocabulary” and “not in scope” stock answer are often different. and Pacian asks about dealing with the second point.
In The Portrait I actually exploited this cheat for delivering a QoL feature to players (the object being examining 40+ details of a single item…) so in my opinion, the best solution perhaps is changing the disambiguation routine, excluding from the list of disambiguations the hidden/not known objects ?

Best regards from Italy,
dott. Piergiorgio.

Dialog doesn’t actually make a distinction between “not in vocabulary” and “not in scope” by default, but it’s not too hard to add one (thanks to (unknown word $)). I did this in Miss Gosling to flag possible typos (after showing the normal parser error, if you used a word that wasn’t in the game’s dictionary, it also notes that Watson didn’t understand [the list of unknown words]).

I did take a crack at that, but sadly I didn’t have much luck understanding or changing the disambiguation logic - either nothing changed or I broke it completely.

Tweaking the scope rules seems to have worked with much less effort…