There seems to be some subtle differences between the testing commands GONEAR (a room or object) and ABSTRACT ME TO (a room or object).
While testing one of my games today, I momentarily forgot about the command GONEAR and in the moment, instead used ABSTRACT ME TO (a particular room). There were some curious oddities–
– only the name of the room was displayed, and even LOOKing did not render a room description
– though the room was adjacent to the room I was in, as I was testing some rules about a locked door that joined them, I could not refer directly to that door, eg. OPEN DOOR would result in ‘You can’t see such a thing’. HOWEVER, when I attempted to go in the direction of that door, the response was still an implicit attempt to open that door (first opening the white front door) and ‘It seems to be locked.’
– though the two rooms were in different regions, Every turn rules that applied to the room/region I came from would still fire, as if I was still in that room
– rules about going certain directions from the previous room were applying as if I were still in that room (eg. GO NORTH would result in ‘You get back down off the porch.’ (a BEFORE rule response)–though I was in the house–then the door response above would register)
Really not urgent or important, I just thought it was curious. When I tried it, I thought, ‘What the heck is going on, here?’ Then I realized I should have used GONEAR, so when I did, the test went without a hitch. I occasionally use ABSTRACT ME TO for enterable supporters and containers, and never noticed any irregularities. Could the above be happening because of the difference between ‘yourself’ and ‘the player’?? Does ABSTRACT ME TO result in an out-of-body experience??
According to the documentation, ABSTRACT is a testing command for moving objects to a place. ABSTRACT ME to a room works only because ME is recognized as an object. The command not going to print the description of the room because it’s just moving a object.
GONEAR prints the description of the room because it’s purpose is to move the player to the mentioned object or room.
As the documentation says, these testing commands aren’t perfect. You can generate a runtime error by simply saying GONEAR NORTH. Try ABSTRACT ME TO NORTH, then LOOK, for a laugh. Also try PURLOIN ME for a bigger laugh.
concur, agree and laugh with AJ Mako; for the record (under spoiler) I have laughed more in the 2nd case, than in the first (Inform 7 6M62):
gonear north
*** Run-time problem P61: Attempt to move the player off-stage.
abstract me to north
[Abstracted.]
l
The compass (in the north)
It is now pitch dark in here!
purloin me
[Can’t move yourself: it would contain itself.]
now that my curiosity was piqued, I tried to purloin & gonear… the compass itself, with an interesting answer:
gonear compass
There seems to be no such object anywhere in the model world.
purloin compass
There seems to be no such object anywhere in the model world.
looking at the generated I6 code, the answer, at least in inform 7 pre-I10 world model, is interesting:
Object Compass "compass" has concealed;
and for the dir object inside the compass:
Object I51_north "" Compass
class K3_direction
with name 'north' 'directions//p' 'n//'
with parse_name Parse_Name_GV1
with action_bitmap 0 0 0 0 0
with KD_Count 3
with IK3_Count 0
with IK3_Link I52_northeast
with vector 0
with short_name BC_93
with article BC_94
with p10_opposite I54_south
with list_together BC_95
with plural BC_96
;
whose means that the compass object is concealed, hence the answer to the attempt to purloin and reach, but the single direction inside the compass don’t have the concealed attribuite (I think for allowing LOOK ) relying on the parent’s concealment, hence, perhaps, the cause of the laughing behavior reported by AJ Mako.
It has to have a name. Everything has a name. I’m not very good with I6, but I’m pretty sure Compass is the name, and “compass” is the printed name.
In Inform 7 (10.current) the I6 is:
Object Compass "(Compass object)"
has concealed
;
The property “has concealed” is what prevents the object from being found in the game. If you use the command ABSTRACT ME TO COMPASS you get the same “There seems to be no such object anywhere in the model world.” This is because the compass is a “way out of world” object. It is merely a holder for compass directions and there’s no reason to refer to it.
Not everything has a typeable name (a synonym). In I6, objects don’t by default; you have to supply a name property.
In I7, things are publicly-named by default, and thus usually have synonyms. But the compass is not a thing (it’s just an object) and thus is privately-named.
The property “has concealed” is what prevents the object from being found in the game.
Not true. The I6 concealed attribute (“undescribed” in I7) doesn’t make an object untypeable anyhow.
You can test this by removing the Compass’s concealed attribute with a bit of I6 code.
Now that I look, even giving the Compass a synonym isn’t sufficient. The debug verbs have a special case to skip library internal objects, and the Compass is considered one.
Fussy details: PURLOIN, ABSTRACT, GONEAR etc all use the testcommandnoun scope token. This runs through every Object in the game which has the KD_Count property. This property is part of the I7 kind system, and is generated for every object declared in I7. But I6 objects like the Compass, thedark, and the (extremely obscure) ValuePropertyHolder objects lack KD_Count and are thus skipped by testcommandnoun.
(Arguably they should also be skipped by the TREE debug command. It’s inconsistent that they can be listed by debug commands when they can’t be affected.) (But I suppose the Compass contains the directions, which can be affected by debug commands. So we can’t really just skip it.)
! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
! Tests.i6t: Abstract Command
! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
[ XAbstractSub;
if (XTestMove(noun, second)) return;
move noun to second;
"[Abstracted.]";
];
[ XTestMove obj dest;
if (obj <= InformLibrary) "[Can't move ", (name) obj, ": it's a system object.]";
if (obj.component_parent) "[Can't move ", (name) obj, ": it's part of ",
(the) obj.component_parent, ".]";
while (dest) {
if (dest == obj) "[Can't move ", (name) obj, ": it would contain itself.]";
dest = CoreOfParentOfCoreOf(dest);
}
rfalse;
];
and here’s >GONEAR:
! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
! Tests.i6t: Gonear Command
! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
[ GonearSub;
PlayerTo(LocationOf(noun));
];
! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
! WorldModel.i6t: Moving the Player
! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
[ PlayerTo newplace flag L;
L = LocationOf(newplace);
if (L == nothing) return RunTimeProblem(RTP_CANTBEOFFSTAGE);
@push actor; actor = player;
move player to newplace;
location = L;
real_location = location;
MoveFloatingObjects();
SilentlyConsiderLight();
DivideParagraphPoint();
if (flag == 0) <Look>;
if (flag == 1) give location visited;
if (flag == 2) AbbreviatedRoomDescription();
@pull actor;
];
What >ABSTRACT is missing relative to >GONEAR is the updating of the location and real_location globals, plus updating the location of floating objects (e.g. backdrops), checking availability of light and printing a room description when appropriate.
You could update XAbstractSub() to:
[ XAbstractSub;
if (XTestMove(noun, second)) return;
if (noun == player)
PlayerTo(second);
else
move noun to second;
"[Abstracted.]^";
];
if you don’t feel like keeping track of the difference.
Leaving aside my proven poor understanding of I6, and the whole discussion of the compass object. The not so subtle difference between GONEAR and ABSTRACT is, as I said before: one is used to move an object from one place to another, and the other is used to specifically move the player near an object.
ABSTRACT has the syntax “ABSTRACT [object] TO [place]”, where “place” can be a room, or another object. It moves “object” to “place” and nothing more. It’s not intended to work on the player. It happens to work on the player because the player is a moveable object. The documentation in the i6 template seems pretty clear:
ABSTRACT ... moves an object to a new position in the object tree.
GONEAR has the syntax “GONEAR [object]”, where “object” can be any named thing including a room. It moves the player to a location near the indicated object, mimicking as near as possible, normal movement. It’s intended to move the player, so naturally it has to do some checks to decide the final location and such. Once again, the documentation in the i6 template seems pretty clear:
GONEAR teleports the player to the vicinity of some named item.
The difference is also pretty clear in the I7 documentation at §24.4. Low-level debugging commands.
GONEAR has the issue of teleporting to items, not rooms (the most logical object for a teleporting debugging command), so one needs an object in the target location, whose can be a debug “programmer’s beacon”, so to speak; but I prefer the “Imp’s gate”, my I7 implementation being this (both 9.x and 10.x):
[from WI, 8.7; also a convenient shortcut during testing.]
the teleport circle is fixed in place in the outside cottage. The description of the teleport circle is "a bit-sized version of the Gate, this teleport ring on the floor leads to the winding path between the enchanted grove and the mystical grove.".
instead of entering the teleport circle: move the player to winding path.
Hope that this is useful…
Happy Informing new year and
Best regards from Italy,
dott. Piergiorgio.