-
Notifications
You must be signed in to change notification settings - Fork 4
IE-0015: World model enforcement #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IE-0015: World model enforcement #15
Conversation
|
As noted in I7-2211 the world-model violations go beyond holding, wearing, and carrying; they also apply to supporting and containment. Is discussing those, also, in scope for this proposal? The current proposal gives us different meanings of
We're left without a verb corresponding to checking whether one region is the direct parent of another; that would have to be checked with
They come really close, though, the sole exceptions being when X is a non-person quantifier or a description of objects that's not a description of people. I'm making a plea for having As I noted in I7-2220, this parallels And it's useful (as demonstrated by the Fallout Enclosure example, for one). I expect the thing-requirement would break some existing programs, albeit a small number. But the chance of code breaking due just to changing the person requirement in the cases cited is much smaller still: I think it'd be reasonable to expect it to be nil. I would sympathize with the rationale, at least, of changing its meaning to make it consistent with one or both of the other uses of |
|
Yes, the containment, support, enclosure and incorporation relations will come next. Today we settle all relations business. When regions contain each other, that can be tested with containment. If we have If we allow |
I'm suggesting that the relation's domain be (object, object) but that its usage in assertions and now-phrases be special-cased. In the proposal as written, assertion-hold and conditional-hold are already special-cased relative to now-phrase-hold. So this suggestion doesn't increase the amount of special-casing in the world, it just makes now-phrase-hold a special case instead of conditional-hold.
Inform will be continuing to say that via the Excising one little bit of sub-optimal English usage in a single case of where a word applies such that the word has a separate meaning in every context in which it may appear constitutes a net loss for comprehensibility and usability. |
|
Would this proposal turn holding into a generic (object tree based) relation any objects could use? If so that could be the solution for the spawning relation for Glk Windows (#12 (comment)). |
|
I think I basically agree that (object, object) achieves better consistency, and experiment seems to suggest that this works well (at any rate, it breaks nothing in the test suite). Since this means embracing the idea that the verb is used more widely than just for things, I've made a more permissive This may be a useful idea when we come to the harder problem of improving the consistency of |
|
To pose a question: given https://inform7.atlassian.net/browse/I7-2219 should we alter HolderOf so that it returns In an ideal world, the pseudo-object |
|
I favor HolderOf returning nothing for directions. It's hard to imagine that that change would break anyone's code. I had been going to bring it up, having noticed the inclusion of direction and region among spatial objects, but without further discussion. I'm guessing you were saving regions for discussion alongside containment. And I assume the spec will get explicit about how doors and backdrops will fit into the revised spatial relation scheme (beyond "awkwardly"). |
|
I've now made this change, and documented it in IE-0015. It caused no problems with the test suite. On further reflection, I'm sure this was a good change to make: it guarantees that |
|
Thanks Graham & Zed for this. I see that there had already been a change between 9.3 and 10 such that 'Nirvana is in Shangri La' became true in 10.1, whereas it was false in 9.3 (where the compiler generally assumed regional containment as the meaning of 'in' or 'contains' in phrases like this, so conditions about one region containing another were always false unless the containment relation was forced, which could be done by the containing region being in an object variable (if <obj-variable> contains ) or the condition being expressed obliquely as '<containing-region> relates to <contained-region> by the containment relation'). Is this change documented somewhere? If not, is it worth documenting here? The current proposal confuses me where it says that Am I right in thinking that 'holds' now exactly corresponds to 'ParentOf()`? How do you envisage authors reorganising the object tree of abstract objects at runtime if 'now X holds Y' is restricted to spatial objects? |
|
On the subject of spatial relations, is there a good reason why it's not possible to move rooms from one region to another at runtime (except through subterfuge, by 'manually setting' their map region property)? Inform currently throws an error suggesting that moving a room to a region would imply that it would appear in all rooms in that region, like a backdrop, but plainly that isn't the case. If there are two regions, Indoors and Outdoors, then I board up the Verandah and set its map property to Indoors, it is simply now contained and regionally-contained by the Indoors region instead of the Outdoors. Does this cause a potential difficulty? And if not, why not allow 'now the Verandah is in Indoors? |
|
Another thing I've just noticed- since Ver 10, a region now appears in 'the list of objects to which it relates by the regional-containment relation' i.e. it appears to regionally-contain itself- which I assume is unintentional |
|
Also, for some reason the compiler's parser struggles with:
|
|
Another change from 9.3 to 10 I've noticed: Regions now regionally-contain other regions that they enclose, which was not the case in 9.3. In 9.3, regions contained, held and/or enclosed other regions but never regionally-contained them (despite what the docs said) |
|
Ah. And, I see, that's the explanation for my first observation- the reason that 'Nirvana is in Shangri La' is now (since Ver. 10) true is not because the compiler has changed its interpretation of the condition- it's still testing for regional-containment and not containment- it's just that regions can now regionally-contain each other (and even, it would seem, themselves!) |
|
Consequently, to test for direct containment of a region there is still no easy alternative to 'holds' or 'holder of' |
|
Would something like the following be desirable? It seemed so to me when I first thought of it. On reflection, I realized there are good reasons to lump rooms and doors together, or, more generally, rooms and things, or even rooms, things, and regions; the only time I ever want to lump all of the spatial objects together is when I'm testing I7 behavior. But I thought I'd toss it out in case someone else can think of why there would be a compelling reason for it. |
|
I was thinking about a "spatial" attribute just for efficiency reasons (testing X has spatial is quicker than X ofclass room or thing or region or direction), in fact. Defining this at the I7 level as well is appealing in a way, but does occupy the nouns "spatial" and "abstract": we might want more obscure wording, and do we really want authors to be able to cause chaos by giving or removing this property at runtime? |
The latter doesn't trouble me so long as there's explicit documentation regarding "this is possible, but don't ever do it". I've been assuming it's too radical a change to be plausible, but in case I'm wrong, I'll ask it: could the spatial objects' kinds be subkinds of a |
|
Yes, I think that's a pretty feverish dream, as they go. I basically tremble at the thought of how many places in the code expect room and thing, etc., to be top-level kinds of object (in the compiler as well as the kits, not to mention who knows where in extension). |
|
So I have been looking at the regional containment relation this evening, prompted by Peter. Even this is not trivial. Firstly, I think it's quite right that regions should regionally-contain all regions they enclose: not doing so was just a bug in Inform 9. But I think saying that a region regionally-contains itself is a bug in Inform 10.1, so I've fixed this. Peter also notes that regional containment cannot be directly changed in 10.1. In fact, some slightly odd maneouvres could be done, but others couldn't. There's an argument against, but I've implemented Tonight's moral conundrum: Should |
If we were spec-ing this out from scratch, I don't think the question would even come up: of course it should. Regions enclosing but not holding their rooms are one of the unfortunate anomalies in the current state of affairs. As much as I'd like to see this change happen, there probably is code in the wild that could break in weird ways if the All that said, it'd be so frustrating to not remove the inconsistency here that I lean toward yes, so long as a lantern is hung on the change, for instance a prominent notice in the IDEs. Maybe the first page of the docs, instead of its very neutral Change Log link could have a short message to the effect of: "10.2 (? 11?) cleans up some fundamentals regarding relations. It's possible, if unlikely, that stories written for previous versions may have depended on the previous messier behavior. See changes since 10.1 to check whether it affects you." |
No, no, a thousand times no. This is something that's not broken in any important way and does not need fixing, IMHO. I can't see many circumstances where it would be really helpful. And it would break SO much code I suspect, both old and new, both I6 and I7, that assumes rooms are held by nothing- even more so if this were to be implemented by the logical and pure method of doing away with the map region property and making rooms a child of their map region in the Object Tree. I think the decision NOT to do this that was presumably taken when regions were first introduced to Inform was the only reasonable one at the time and much more so now, and the odd relations between rooms and regions that exist as a consequence should be regarded as an ancestral evolutionary quirk akin to the human hip joint- it's not how you'd design it from scratch, and it has a few weaknesses, but it basically works well and given its evolved interrelationships with other structures and mechanics we are where we are and it is is best not redesigned by overenthusiastic surgeons and their collaborators.* *50 years of experience in the joint replacement field has proven this to be true |
|
Well, always good to reach a consensus. Enclosure is defined at runtime by the function Currently the code looks like this: It seems to me that the That leaves This I think is the real significance of the issue of whether a region can be the holder of a room. At present, a region can only enclose another region. Surely a region does enclose a room which is part of it, and therefore also anything in that room? (I note that, at present, a region is the So today I have two questions: (a) Should we make a room enclose any backdrop found in it? (b) On the subject of regions enclosing stuff, which is the more attractive option?
|
It's an awkward thing to arrange in I7, and I doubt any existing code makes use of this remote possibility- particularly since I7 has already deviated from I6 in that in I7 when in darkness children of
Do you mean all rooms which would be returned by inspecting the backdrop's I6 found_in property would enclose it? or just the room (if any) the backdrop is currently a child of in the Object Tree? I would be in favour of an inbuilt I7 verb- 'found in' is probably as good as any- to mean where doors and backdrops would appear if the player were to be that location, but without making rooms enclose backdrops. Making just the room currently holding a backdrop also enclose it would tidy up the nice 'enclosure'=='(indirectly) hold', 'hold==parent of' paradigm, but it may be best to abide by the principle of 'if it ain't broke don't fix it' and leave things as they are.
There already exists an indirect relation that transcends the region/room barrier- regional containment- and which now encompasses all of regions, backdrops, rooms and their contents, direct and indirect. I'm not sure much is to be gained by extending enclosure across the region/room barrier. So I would lean towards leaving things as they are, with the 'cascade of enclosure' broken at the region/room interface, with regional containment being the 'one relation to rule them all'. It's already straightforward enough I think to access the 'lowest in the hierarchy of regions' region of a room, or of any of its contents, via
The same concern already applies to backdrops and regions. I think the present situation is that if a backdrop is 'found in' any of the rooms regionally contained by a region, the backdrop is said in conditions to be 'regionally in' said region, whether its current position in the Object Tree reflects that or not. |
|
Something unfortunate which I should give notice of, though: Looking more carefully at how regions and backdrops are implemented, I think we have to take a firm stance that rooms cannot change region, and that regions cannot be moved to other regions, with |
|
No, I take it back. On closer inspection, |
|
Just to be sure of desired behavior in the concealment (iv) case: If a box is a container that conceals a note, and a player takes the box, then the default behavior will be that they will see nothing other than the usual "Taken." and the next time they do an inventory they'll see (all of which is the same as today) but now the note will be in scope, right? |
|
Okay, that seems wrong, doesn't it? I would have naively thought that the correct thing is for the note to be not only out of scope but also not listed in the inventory. Is there some reason why we don't want to do it that way? |
|
I had thought the previous discussion indicated that what the player encloses shouldn't be concealed from the player. Is it merely that what the player directly holds isn't concealed from the player? |
|
Um, so if the player conceals the box, but the box does not conceal the note, then we should get the inventory: But if the box conceals the note, the inventory should surely be: I think the idea here is that concealment is about holders, not enclosers. |
|
I think Graham's idea of this is what naive authors would instinctively expect, also what would be most useful to experienced authors, so I would support it on both those grounds. Further, as Graham suggests, it fits with the idea that things (along with their contents) are functionally concealed only by their direct holder- so if actors can't conceal their direct possessions from themselves, likewise the contents of those possessions should be unconcealed unless the possessions themselves do their own concealing. |
|
As things stand at present, it is already the case that concealment of things enclosed by an actor works in this way (which is, of course, why concealed things enclosed by the player, and their contents, are out of scope). It's just that at present by default inventory lists things concealed from the actor, and their contents. But I guess you knew that :-) |
|
OK. That's the same behavior currently in Concealer and I agree that it's better (I was never advocating for the behavior I described above; I had misread Graham's comments as indicating it would be the desired behavior.) |
|
I'm polishing the concealment code. I'm not sure what call to make for this case: The Undescribed test case has a glass jar with 3 undescribed scraps of paper inside. By the current behavior, they're not mentioned; if one searches or examines the jar, one is told it's empty. But if one drops another container alongside it, it'll have the '(empty)' tag in the room description and the jar won't, and, of course, the paper is in scope. On balance, I think it's probably better to have the '(empty)'. Any thoughts? |
|
Yes. It seems hard to argue with the point that a container with only undescribed contents should look the same as a container which is actually empty, which argues for printing the '(empty)', even though in some sense this is a lie. It's weird to be effectively transmitting side-channel information to the player who is sufficiently au fait with Inform's internals, i.e., that because we don't print '(empty)' now we are in effect signalling that the container must contain something undescribed. It's interesting that we used the term "undescribed" and not, say, "invisible". At some point it was conceptually a little less clear-cut than simply not being seen. This no doubt goes back to the "concealed" attribute in Inform 1. |
|
Revenge of the World Model! I found another way a person can end up enclosing a person. -> OK, but it took deactivating a standard rule, so maybe it doesn't count. But... -> The actor becomes the holder of the thing being pushed, and thus encloses the player during the implicit look that's part of the going action below... this seems like a reasonable and parsimonious patch for this, but I'm testing further. (Found this while working on fixing I7-1995.) |
|
I'm shocked, shocked I say. That would probably win the prize for the most eldritch rule in the Standard Rules, but it seems a reasonable solution to me. Would we give it a name? (I cannot imagine what.) |
It certainly does, and "undescribed" remains untidy to this day. (SCORE__UNCONCEALED in Adjudicate(), etc.) |
This is problematic for the abstract object case: there's no non-I6 way to undo the holding relation. |
|
This may have already been argued as much as that most controversial "describe what's on scenery supporters in room descriptions rule", so my apologies if revisiting it is unwelcome. If you search a container or supporter (the container or supporter in question can be scenery or not), held scenery things are equivalent to undescribed or concealed things: unless there's something directly in or on the thing that's none of scenery, undescribed, concealed, then upon searching it, the default is that the player is told "[The container] is empty" or "There is nothing on [the supporter]". The same "[The container] is empty" message is given when examining containers that contain scenery but either contain nothing else or only contain other things that are concealed or undescribed. This seems off to me for the scenery case. Scenery is de-emphasized but it seems weird to explicitly deny its existence. I think in the searching case that the default should be that the player is told about scenery things in or on the thing being searched (and they hold that are neither concealed nor undescribed, and so on) or in containers being examined. I'm not suggesting changing any of looking's behavior, or anything else about examining's or searching's behavior in this regard. |
Hm. Scenery is (as a rule) not hidden from the player. The point of That doesn't mean we should hide a scenery object from the SEARCH action. However, both LOOK and SEARCH are going to do a bit of "list the contents of the container" business. It would be both fussy and surprising if that contents list included or excluded scenery objects depending on the current action. If I recall correctly, that "scenery is equivalent to concealed" logic was added because of a bug report reading like:
(All contents were scenery, therefore all skipped.) |
|
To be sure, I've long since decided to only use |
|
I just noticed another weirdness of the existing concealment behavior that my fixes in 10.2 didn't change: an item can be all of concealed, lit, and the only light source in the room, and it'll remain concealed but the player won't be in darkness. My thinking is that the room should remain in darkness. Certainly one could say that it's more "realistic" that a lit concealed item in a dark room would thus reveal itself, but that would mean trumping the author's concealment rules, which I wouldn't want to do. But I think if concealment-trumps-litness is chosen and implemented the docs should call attention to being the case that if an author creates a situation where a concealed lit item might be the only light source in a dark room, they're on their own regarding what to do about it. |
|
@ganelson My draft outlining further suggestions for World Model enforcement is now available in a branch on my fork of this repo. (Fear not, everyone; I won't be making a pull request.) |
|
The description of changes to the support relation sounds like it would break the Rideable Vehicles extension, since it redefines the relation in terms of a supporter, yet neither rideable vehicle nor rideable animal are kinds of supporter. Was this tested? |
|
Rideable vehicles are kinds of supporter. There are problems with rideable animals. These work:
This doesn't:
Testing |
|
You can still Additional work would be necessary to make the support relation work. |
|
Hmm. If rideable animal were a kind of supporter that was usually animate, male, not neuter, the only things I can think of that you'd lose would be:
|
|
actually, I was confused. There isn't a problem. It's a bug in versions before current development that one can say |
|
Is it at all possible to give "on" a different meaning when used with rideable animals? Right now it looks like the compiler rejects using the same verb for two different relations, but it would definitely be convenient if "on the horse" were translated to the carrying relation, and with the support relation defined only on supporters, it's not as if that would actually be ambiguous (it can be disambiguated in the same way that the containment and regional-containment relation already is). I suppose it's not that big of a deal if that can't be done or is just too complicated. That said, the Rideable Animals documentation should maybe mention explicitly that rideable animals carry you rather than support you. |
No. A perhaps helpful sort-of-mitigation might be: with that |
That sounds great, except that the relation is not assertable, right? So RV would still have to make it clear that rideable vehicles support their passenger(s) while rideable animals carry them. |
|
Yes, it could only be used in conditionals, not in assertions or with |
Summary
WorldModelKit and the Standard Rules, together with support hard-wired into the if module of the Inform compiler, collectively provide a "world model". At present it is not as consistent or as well-enforced as we would like, and this leads to unexpected and unhelpful behaviour. IE-0015 gathers up a set of changes to improve (though not fully fix) matters in one place, rather than leaving these in scattered responses to bug reports.