[INFORM] Takeable actors?

13 views
Skip to first unread message

Magnus Olsson

unread,
Jan 11, 1997, 3:00:00 AM1/11/97
to

Does anybody know of a simple way of making an actor that can be picked
up (like a small animal)?

The problem is that there is an if statement buried deep inside the
RTakeSub routine that won't let me take an animate object ("I don't
suppose the cat would care for that."), and the only way of changing
that is to replace the entire RTakeSub routine, something I'm
reluctant to do. What happens, for example, if Graham decides to
change the way the Take verb is implemented in the next release?

The best solution I've been able to think of is a bit of a kluge, but
it works: give the actor a before routine that pretends it's not
animate after all:

before [ ;
Take:
if (self has animate) {
! Pretend the actor is just any old object. The surrounding
! if statement is there to prevent an infinite loop.
give self ~animate;
! Now the player can take the actor
< Take self >;
! Stop pretending we're inanimate.
give self animate;
! And end processing here
rtrue;
}
]

This is, of course, a neat hack, but it's not very transparent, is it?


--
Magnus Olsson (m...@df.lth.se, zeb...@pobox.com)

-

unread,
Jan 11, 1997, 3:00:00 AM1/11/97
to

Magnus Olsson wrote:
>
> Does anybody know of a simple way of making an actor that can be picked
> up (like a small animal)?
[snip]

Couldn't you use a before routine that moved the animal to the player,
eg

before
[;
Take:move self to player;!Or possibly move self to actor
"You pick up Fred the Albanian Fuzzball.";
],

I'm _pretty_ sure this works, and I _think_ I used it for my pet cat in
a simulation I started of my house.
--
Nicholas Daley
<mailto:dal...@ihug.co.nz>

Everyone agreed it was a splendid funeral, but no one enjoyed it more
than the deceased himself.
--Pt1 C11 Red Dwarf Grant Naylor

Andrew Plotkin

unread,
Jan 12, 1997, 3:00:00 AM1/12/97
to

Magnus Olsson (m...@bartlet.df.lth.se) wrote:
> Does anybody know of a simple way of making an actor that can be picked
> up (like a small animal)?

> The problem is that there is an if statement buried deep inside the


> RTakeSub routine that won't let me take an animate object ("I don't
> suppose the cat would care for that."), and the only way of changing
> that is to replace the entire RTakeSub routine, something I'm
> reluctant to do. What happens, for example, if Graham decides to
> change the way the Take verb is implemented in the next release?

You recall my plan from a few weeks ago:

Hack the libraries, and put that if statement inside #ifndef:

#ifndef TAKEABLE_ANIMATES ! my hack
if (noun has animate) return L__M(##Take,3,noun);
#endif ! my hack

Or even (for the real perfectionist)

#ifdef TAKEABLE_ANIMATES ! my hack
Attribute takeanyway;
#endif

#ifdef TAKEABLE_ANIMATES ! my hack
if (noun has animate && noun hasnt takeanyway) return L__M(##Take,3,noun);
#ifnot
if (noun has animate) return L__M(##Take,3,noun);
#endif ! my hack

Then, if you decide to upgrade to a new library release, search through
for "my hack" and copy the hacks into the new files.

Well, it *is* simple, and a lot easier to understand than the mess you
came up with. And less fragile, if you understand what I mean. When you
start swapping flags in and out, it is possible (in theory) that
something will abort and leave them in the wrong state, or you'll
accidentally test a flag at the wrong time and get an unexpected result.
My way hacks the libraries, but at least it says exactly what it means.

--Z

--

"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the
borogoves..."

Julian Arnold

unread,
Jan 12, 1997, 3:00:00 AM1/12/97
to

In article <5b6ivg$t...@bartlet.df.lth.se>, Magnus Olsson

<URL:mailto:m...@bartlet.df.lth.se> wrote:
>
> Does anybody know of a simple way of making an actor that can be picked
> up (like a small animal)?
>
> [...]

I don't know of a non-hacky solution other than replacing the routine as
you suggest. Hugo contains the following lines in the DoGet routine:
elseif object is living and object is static
{Message(&DoGet, 3) ! player trying to get character
return false}

Thus a living (animate in Inform-ese) object can be taken, but a living
static object can't. Maybe the next Inform library should do the same?

Jools
--
"For small erections may be finished by their first architects; grand
ones, true ones, ever leave the copestone to posterity. God keep me
from ever completing anything." -- Herman Melville, "Moby Dick"


Magnus Olsson

unread,
Jan 12, 1997, 3:00:00 AM1/12/97
to

In article <erkyrathE...@netcom.com>,

Andrew Plotkin <erky...@netcom.com> wrote:
>> The problem is that there is an if statement buried deep inside the
>> RTakeSub routine that won't let me take an animate object ("I don't
>> suppose the cat would care for that."), and the only way of changing
>> that is to replace the entire RTakeSub routine, something I'm
>> reluctant to do. What happens, for example, if Graham decides to
>> change the way the Take verb is implemented in the next release?
>
>You recall my plan from a few weeks ago:

No, actually I don't - either that article didn't reach our site, or my
mind is going... :-)

>Hack the libraries, and put that if statement inside #ifndef:
>
>#ifndef TAKEABLE_ANIMATES ! my hack
> if (noun has animate) return L__M(##Take,3,noun);
>#endif ! my hack

[...]

>Well, it *is* simple, and a lot easier to understand than the mess you
>came up with. And less fragile, if you understand what I mean. When you
>start swapping flags in and out, it is possible (in theory) that
>something will abort and leave them in the wrong state, or you'll
>accidentally test a flag at the wrong time and get an unexpected result.
>My way hacks the libraries, but at least it says exactly what it means.

I can agree that my solution is rather ugly, hard to understand, and
possibly fragile. Your way is preferable, except for one thing: it
requires changes to the library source (or, alternatively, that I
replace the entire functionality of RTakeSub, which is almost as bad).

My point is that I should *not* have to hack the library source in
order to override some default behaviour. This is against all
principles of sound software engineering: ideally, the library should
have a clean, simple interface to the programmer, and its insides
should be a black box. In fact, in large systems (larger by an order
(or two, or three) of magnitude than even the largest piece of IF), it
is considered imperative that a programmer working on one subsystem be
kept from tampering with - or even exploiting knowledge of - the
internals of other subsystems.

Earlier in your post, you wrote:

>Then, if you decide to upgrade to a new library release, search through
>for "my hack" and copy the hacks into the new files.

But this is _evil_. Not only do you have to do this *every* time there
is a new library release, but what do you do if the internals of the
library change? My solution, ugly as it is, will at least continue to
work even if Graham makes quite extensive changes to the internal
implementation of "Take".


Now, in this particular case, I can agree with you that there may be
no better solution than hacking the library source. But this fact
leads me to state my main criticism of Inform, which, unlike David
Baggett's, doesn't have anything to do with the Inform language
itself, but with the library:


The thing I like the least about the Inform library is that there are
so many cases of hard-coded default behaviour hidden deep inside the
bowels of the library.


And this is intimately connected with the fact that the Inform library
isn't sufficiently object oriented. The Inform language is completely
OO, but the library isn't. Instead of asking an object what should
happen, for example, when the player tries to pick it up, the action
routines contain lots of special cases of the type "if this is an
animate object, then the player shouldn't be allowed to pick it up".

As a consequence, not only is the library source in many places opaque
and difficult to comprehend, it is also quite difficult to override
all the special cases hard-coded into the action routines.

In an OO design, the action routine would simply ask the object "Is
there any reason why the player shouldn't be allowed to pick you up?",
and an animate object could then reply "Yes, I'm a person". The cat in
my example would override this behaviour and instead reply "No, I
don't mind."

This is basically how the TADS library works (with its verification
methods), and the Inform language has the mechanisms for implementing
it (message passing, inheritance, overriding), it's just that the
library doesn't use them to a sufficient degree.

Note that the Inform library's "before" and "after" routines *are*
object-oriented and can be overridden quite elegantly - this works
like a charm. The problem is that a lot of processing takes place
_between_ before and after, in the action routines, and *they* are not
OO. Overriding "before" and "after" is enough in many cases, but not
always.

It should be noted that this is by no means a fatal shortcoming of
Inform. After all, it is perfectly possible to make it do whatever one
likes by hacking the library. It just makes it somewhat less
convenient to work with than it could have been.

Also, I am aware that there is a perfectly good reason for the Inform
library's design not being completely OO, viz. that the library was
designed before the language was fully OO. I can understand that Graham
doesn't want to redesign the Library from scratch!

Finally, Inform remains a remarkably powerful and (relatively) easy to
use tool for writing IF. I don't consider it flawed; I just wanted to
point out that a better library design would have made it even easier
to use. If we compare the Inform library with the standard TADS
library (adv.t), the OO design of adv.t makes it much easier to
override even complicated behaviour, but there are other points where
Inform is more flexible, more powerful, or just simpler than TADS. The
question which language is the best remains open.

Andrew Plotkin

unread,
Jan 13, 1997, 3:00:00 AM1/13/97
to

Magnus Olsson (m...@bartlet.df.lth.se) wrote:
> My point is that I should *not* have to hack the library source in
> order to override some default behaviour.

No, your point was that you wanted to know the best way to solve a
particular problem. That's the question I was answering :) *Now* your
point is as you state, so we continue...

> This is against all
> principles of sound software engineering: ideally, the library should
> have a clean, simple interface to the programmer, and its insides
> should be a black box. In fact, in large systems (larger by an order
> (or two, or three) of magnitude than even the largest piece of IF), it
> is considered imperative that a programmer working on one subsystem be
> kept from tampering with - or even exploiting knowledge of - the
> internals of other subsystems.

> Earlier in your post, you wrote:

> >Then, if you decide to upgrade to a new library release, search through
> >for "my hack" and copy the hacks into the new files.

> But this is _evil_.

Of course it's evil. Computer languages are evil. Compilers are a
terribly painful hack to get around the fact that computers aren't good
enough to interpret English on the fly. The Z-machine is an evil hack to
get around our unbelievably stupid policy of making computers that are
incompatible with each other. Computer games are an attempt to take our
minds off how lonely and miserable we all are because telepathy hasn't
been invented yet.

Nonetheless, I hack the Inform source libraries.

> Not only do you have to do this *every* time there
> is a new library release, but what do you do if the internals of the
> library change?

I'm going to pretend that question wasn't rhetorical and answer it: I
would elect not to upgrade to that library release. (For the
already-existing game.) _So Far_ is built under libraries 5/12 and will
remain so. This means that, sadly, it will never be translated into
another language using the 6/3 language system. Fortunately, I'm
monolingual...

> My solution, ugly as it is, will at least continue to
> work even if Graham makes quite extensive changes to the internal
> implementation of "Take".

I think you're drawing a somewhat artificial distinction between
"interface" and "implementation" for the Inform libraries. *Because* the
library is quite old and contains a lot of relic code -- read "handed-down
brain damage", and Graham is the first to admit it -- I must regard the
implementation of Take (with RTakeSub and so on) as official library API.
It's too old to change, so it will stay the same. It *should* stay the
same. If it is to be changed, it should be redone from scratch in full
light of lessons learned -- which means breaking a lot more Inform source
code than my little evil hack.

> The thing I like the least about the Inform library is that there are
> so many cases of hard-coded default behaviour hidden deep inside the
> bowels of the library.
> And this is intimately connected with the fact that the Inform library
> isn't sufficiently object oriented.

I think I've already admitted this above, but I'll agree explicitly. Yes!
Absolutely, and no kidding.

There ought to be a completely new set of libraries, which are not held to
be compatible with any existing Inform code or the Designer's Manual. I'm
not volunteering for the job. If you are, I'll talk your ear off about
it, starting with Those Goddamn Doors.

> Also, I am aware that there is a perfectly good reason for the Inform
> library's design not being completely OO, viz. that the library was
> designed before the language was fully OO. I can understand that Graham
> doesn't want to redesign the Library from scratch!

Oh, sure. Let's see, have I made explicit all the ideas that I take for
granted but other people will misinterpret? The Inform libraries are a
pain in certain ways, which you can hack around, and this is not news.
Also, evil lurks everywhere, so keep your Uzi loaded.

> Finally, Inform remains a remarkably powerful and (relatively) easy to
> use tool for writing IF. I don't consider it flawed; I just wanted to
> point out that a better library design would have made it even easier
> to use. If we compare the Inform library with the standard TADS
> library (adv.t), the OO design of adv.t makes it much easier to
> override even complicated behaviour, but there are other points where
> Inform is more flexible, more powerful, or just simpler than TADS. The
> question which language is the best remains open.

--Z

Andrew Plotkin

unread,
Jan 13, 1997, 3:00:00 AM1/13/97
to

Andrew Plotkin (erky...@netcom.com) wrote:
> Also, evil lurks everywhere, so keep your Uzi loaded.

In retrospect, a better conclusion is "...so give in to the Dark Side,
buster."

("Oh yeah? Well, *your* thoughts betray *you*, dickweed!")

Magnus Olsson

unread,
Jan 13, 1997, 3:00:00 AM1/13/97
to

In article <32D75D...@ihug.co.nz>, - <dal...@ihug.co.nz> wrote:

>Magnus Olsson wrote:
>>
>> Does anybody know of a simple way of making an actor that can be picked
>> up (like a small animal)?
>[snip]
>
>Couldn't you use a before routine that moved the animal to the player,
>eg
>
>before
> [;
> Take:move self to player;!Or possibly move self to actor
> "You pick up Fred the Albanian Fuzzball.";
> ],
>
>I'm _pretty_ sure this works, and I _think_ I used it for my pet cat in
>a simulation I started of my house.

Sure, it works, so far as it allows the cat to be picked up. The
problem is that it works only *too* well: it allows you to take the
cat even when it's inside a cage which is inside an hermetically
sealed glass box at the bottom of your swimming pool. That is, it
allows you to take the cat as soon as it is in scope.

The RTakeSub routine contains a lot of checks for when you should be
allowed to take something. My problem I only want to override one of
them and keep the rest.

Magnus Olsson

unread,
Jan 13, 1997, 3:00:00 AM1/13/97
to

In article <erkyrathE...@netcom.com>,
Andrew Plotkin <erky...@netcom.com> wrote:
>Magnus Olsson (m...@bartlet.df.lth.se) wrote:
>> This is against all
>> principles of sound software engineering: ideally, the library should
>> have a clean, simple interface to the programmer, and its insides
>> should be a black box. In fact, in large systems (larger by an order
>> (or two, or three) of magnitude than even the largest piece of IF), it
>> is considered imperative that a programmer working on one subsystem be
>> kept from tampering with - or even exploiting knowledge of - the
>> internals of other subsystems.
>
>> Earlier in your post, you wrote:
>
>> >Then, if you decide to upgrade to a new library release, search through
>> >for "my hack" and copy the hacks into the new files.
>
>> But this is _evil_.
>
>Of course it's evil. Computer languages are evil. Compilers are a
>terribly painful hack to get around the fact that computers aren't good
>enough to interpret English on the fly. The Z-machine is an evil hack to
>get around our unbelievably stupid policy of making computers that are
>incompatible with each other. Computer games are an attempt to take our
>minds off how lonely and miserable we all are because telepathy hasn't
>been invented yet.

:-) Though I'm not sure the invention of telepathy would eliminate the
demand for computer games.

>Nonetheless, I hack the Inform source libraries.

OK, you've convinved me: you _are_ evil :-).

Seriously speaking, I didn't really mean that you were evil for
hacking the library source, but rather that it's an evil thing that
one should have to do it.

"Evil" in the hackish sense, of course.

>> Not only do you have to do this *every* time there
>> is a new library release, but what do you do if the internals of the
>> library change?
>

>I'm going to pretend that question wasn't rhetorical and answer it:

FYI, it wasn't.

> I
>would elect not to upgrade to that library release. (For the
>already-existing game.) _So Far_ is built under libraries 5/12 and will
>remain so.

My problem is that I can't afford to do so: I've decided to go with
Library 6/3, which, unfortunately, contains a number of bugs. Which means
that I must be prepared either to upgrade or to fix all the bugs myself.

>> My solution, ugly as it is, will at least continue to
>> work even if Graham makes quite extensive changes to the internal
>> implementation of "Take".
>

>I think you're drawing a somewhat artificial distinction between
>"interface" and "implementation" for the Inform libraries. *Because* the
>library is quite old and contains a lot of relic code -- read "handed-down
>brain damage", and Graham is the first to admit it -- I must regard the
>implementation of Take (with RTakeSub and so on) as official library API.

I agree with you there, and this really should be part of my criticism.

>It's too old to change, so it will stay the same. It *should* stay the
>same.

(...)


>There ought to be a completely new set of libraries, which are not held to
>be compatible with any existing Inform code or the Designer's Manual. I'm
>not volunteering for the job. If you are, I'll talk your ear off about
>it, starting with Those Goddamn Doors.

Hmmm... well... if you could arrange for my days to be extended to
29 hours for the next six months or so I might be talked into it...

But if David Baggett could find the time to write WorldClass from scratch,
perhaps somebody could do the same thing for Inform.

Let me stress the following:

The purpose of this criticism is *not* to slam Graham or Inform, or to
demand a total rewrite of the Inform library. I'm just pointing out
some things that I think could have been done better. Perhaps
prospective authors of new authoring systems (or of new libraries for
Inform, if anybody should attempt such a task) can save valuable time
by avoiding repeating the mistakes of their predecessors.

For I agree with David (I think) in that there is a real danger here:
Inform and TADS are so much better than their predecessors (not
counting Hugo or other newer languages here, but rather AGT and its
likes) that it's all too easy to elevate them to the norm. It's
important that we point out areas where Inform and TADS can be
improved upon.

Finally: despite what has been said before, Inform is not a
professional product (this refers not on Graham's competence, but on
the fact that he isn't working full-time on Inform and doesn't receive
any money for it). This also means that we can't demand the same kind
of performance or quality that we would from a commercial product. I
don't expect the Inform libraries to be perfect. But that doesn't mean
that I shouldn't point out deviations from perfection.

Neil K. Guy

unread,
Jan 13, 1997, 3:00:00 AM1/13/97
to

Andrew Plotkin (erky...@netcom.com) wrote:

: Andrew Plotkin (erky...@netcom.com) wrote:
: > Also, evil lurks everywhere, so keep your Uzi loaded.
:
: In retrospect, a better conclusion is "...so give in to the Dark Side,
: buster."
:
: ("Oh yeah? Well, *your* thoughts betray *you*, dickweed!")

Whoah, Andrew. What are you *on* today? (and where can I get some of it?)

- Neil K.

--
the Vancouver CommunityNet * http://www.vcn.bc.ca/
(formerly the Vancouver Regional FreeNet)

Russell Glasser

unread,
Jan 15, 1997, 3:00:00 AM1/15/97
to

Andrew Plotkin wrote:
>
> Magnus Olsson (m...@bartlet.df.lth.se) wrote:(regarding hacking the Inform libraries)
>
> > But this is _evil_.
> <facetious>

> Of course it's evil. Computer languages are evil. Compilers are a
> terribly painful hack to get around the fact that computers aren't good
> enough to interpret English on the fly. The Z-machine is an evil hack to
> get around our unbelievably stupid policy of making computers that are
> incompatible with each other. Computer games are an attempt to take our
> minds off how lonely and miserable we all are because telepathy hasn't
> been invented yet.
> </facetious>

Yeesh, get serious Andrew. Magnus was talking about solid
programming style, and information hiding is the way good programming is
done. It's called modularity (but I'm sure I don't need to tell you that).
If you write code that way, not just in Inform but in general, you wind up
having to go back and tinker with every individual snippet of code every
time you want to make a simple change in the underlying system.
Sure, it's all very well to say "_So Far_ is built under libraries

5/12 and will remain so. This means that, sadly, it will never be translated

into another language using the 6/3 language system." Speaking ad absurdam,
does that mean software developers have to dump all their old programs every
time their company upgrades to a new version of C++? Does it mean that
changing a game to support graphics accelerator boards must involve
rewriting the whole program from the ground up? I think not.
(Yeah, I know, any program which needs a graphics accelerator board
is also inherently evil and utterly unworthy of consideration... right?)
--
"The reasonable man adapts himself to the world; the unreasonable one
persists in trying to adapt the world to himself. Therefore all
progress depends on the unreasonable man."
-- George Bernard Shaw

Russell can be heckled at
http://sdcc8.ucsd.edu/~rglasser

Graham Nelson

unread,
Jan 15, 1997, 3:00:00 AM1/15/97
to

In article <5bdu63$p...@milo.vcn.bc.ca>, Neil K. Guy

<URL:mailto:n...@vcn.bc.ca> wrote:
>
> Andrew Plotkin (erky...@netcom.com) wrote:
> : Andrew Plotkin (erky...@netcom.com) wrote:
> : > Also, evil lurks everywhere, so keep your Uzi loaded.
> :
> : In retrospect, a better conclusion is "...so give in to the Dark Side,
> : buster."

Evil I may be, but at least I post to the newsgroup these days,
so I'm not quite so much of a lurker.

The substance of this thread is that the Inform library may be
practical and highly evolved, but has a few very murky corners from
a conceptual point of view, and in general isn't what we would
write if we were going to start all over again. I think this
fair comment (though one should distinguish between the parser
and the verb library: the parser's not bad at all, I think).

I have occasionally thought that it would be nice to implement
an entirely new library in a proper object-oriented style. But
I can't find a really convincingly OO way to implement the
typical problems confronting an IF model. The classes of objects
interact too much. Clashes of priority of different rules
(some methods in one class, some methods in another, etc.) have
to be resolved somewhere, and in an explicit way. Not only
that, but objects in Inform basically change class dynamically
and often (as attributes are roughly used to indicate class
membership).

These are not insurmountable problems. I'm just not sure that
I can see the "right" way to object-ify an IF world model.
Neither TADS nor Inform entirely convinces me.

--
Graham Nelson | gra...@gnelson.demon.co.uk | Oxford, United Kingdom


Olav Mueller

unread,
Jan 15, 1997, 3:00:00 AM1/15/97
to

REF: m...@bartlet.df.lth.se (Magnus Olsson) (11.01.1997, 00:22:24)
- Subject "[INFORM] Takeable actors?"

Hallo Magnus,
Hallo Rest,

> before [ ;
> Take:
> if (self has animate) {
> ! Pretend the actor is just any old object. The surrounding
> ! if statement is there to prevent an infinite loop.
> give self ~animate;
> ! Now the player can take the actor
> < Take self >;
> ! Stop pretending we're inanimate.
> give self animate;
> ! And end processing here
> rtrue;
> }
> ]

Well, ehhh ... I may be wrong, but what's about:

before [;
Take:
if( certain conditions are met ) {
move self to player;
print_ret (The) self, " slyly allows himself to be picked up.";
}
],

CU,
Olav

-------------------------------------------------------------------
omue...@tribal.line.org omue...@sunserver1.rz.uni-duesseldorf.de
Fileserver: SEND HELP im Subject an omue...@tribal.line.org

There was a boy called Eustace Clarence Scrubb, and he almost
deserved it.
-C. S. Lewis
"The Chronicles of Narnia"

Magnus Olsson

unread,
Jan 16, 1997, 3:00:00 AM1/16/97
to

In article <y3XpPMD...@trib0029.tribal.line.org>,

Olav Mueller <omue...@tribal.line.org> wrote:
>Well, ehhh ... I may be wrong, but what's about:
>
> before [;
> Take:
> if( certain conditions are met ) {
> move self to player;
> print_ret (The) self, " slyly allows himself to be picked up.";
> }
> ],

The problem is that implementing the "certain conditions are met" part
means re-implementing most of RTakeSub, which is exactly what I wanted
to avoid (for three reasons: 1) If RTakeSub changes, I might have to
change that code as well, 2) There are a lot of "certain conditions"
and it's easy to miss one, and 3) I'm lazy).

Andrew Plotkin

unread,
Jan 16, 1997, 3:00:00 AM1/16/97
to

Russell Glasser (rgla...@penning.lanl.gov) wrote:
> Andrew Plotkin wrote:
> >
> > Magnus Olsson (m...@bartlet.df.lth.se) wrote:(regarding hacking the Inform libraries)
> >
> > > But this is _evil_.
> > <facetious>
> > Of course it's evil. Computer languages are evil. Compilers are a
> > terribly painful hack to get around the fact that computers aren't good
> > enough to interpret English on the fly. The Z-machine is an evil hack to
> > get around our unbelievably stupid policy of making computers that are
> > incompatible with each other. Computer games are an attempt to take our
> > minds off how lonely and miserable we all are because telepathy hasn't
> > been invented yet.
> > </facetious>

First of all, I did not write the "facetious" tags. I was not being
facetious. (Zen, maybe. Whap!)

> Yeesh, get serious Andrew. Magnus was talking about solid
> programming style, and information hiding is the way good programming is
> done.

That's what I said! Many parts of the Inform library implemenation are
evil. RTakeSub is evil. Doors are really, really evil. Bad programming
style is evil. I hate it.

Have I agreed with you loudly enough yet?

> Sure, it's all very well to say "_So Far_ is built under libraries
> 5/12 and will remain so. This means that, sadly, it will never be translated
> into another language using the 6/3 language system."

What do you mean, it's all very well? It's *sad*! I just said so. It
makes me sad.

> Speaking ad absurdam,
> does that mean software developers have to dump all their old programs every
> time their company upgrades to a new version of C++?

Wow, that would be *really* sad.

I will restate my point now:

*The Inform libraries are what we have*. They are not the only compromises
of elegance that I have in my life. Standing up and saying "Wait, this
isn't perfect!" as if it's some vast revelation gets nothing from me but
a disgusted glare.

Moreover, the *practical* consequences of this imperfection (*not* taking
it ad absurdem, but looking at my actual use of Inform in, y'know, real
life) are just not that big. If I *do* upgrade _So Far_ to libraries 6/3,
it will be an extra fifteen minutes of work to transplant my hacks (and
the hack we're arguing about here would be equally easy.) If the libraries
6/4 involve a total reimplementation of RTakeSub, or some other thing I
hacked, it would probably be an extra twenty minutes to upgrade to
*that*.

Compare this to, say, the effort it takes to port a new IF interpreter to
the Mac. It's just not a significant problem on my plate. It's *evil*,
because fifteen minutes times the number of authors who upgrade their
games will eventually equal a large amount of wasted effort. But it's not
a *big* evil. I choose to compromise my sense of programming elegance in
order to work on bigger tasks.

I will restate my point again, quoting from my earlier post:

> The Inform libraries are a pain in certain ways, which you can hack
> around, and this is not news.

> [...]


> There ought to be a completely new set of libraries, which are not held to
> be compatible with any existing Inform code or the Designer's Manual. I'm
> not volunteering for the job.

(but, I should add, the existing libraries should not go away.)

Graham has posted in the interim saying that this job is more difficult
than it looks. I certainly believe that. Nonetheless I will be happy if
someone does it. I would, but I am fully booked with my own crusades to
conquer evil.

Russell Glasser

unread,
Jan 16, 1997, 3:00:00 AM1/16/97
to

Andrew Plotkin wrote:
>
> Russell Glasser (rgla...@penning.lanl.gov) wrote:
> > Andrew Plotkin wrote:
> > >
> > > Magnus Olsson (m...@bartlet.df.lth.se) wrote:(regarding hacking the Inform libraries)
> > >
> > > > But this is _evil_.
> > > <facetious>
> > > Of course it's evil. Computer languages are evil. Compilers are a
> > > terribly painful hack to get around the fact that computers aren't good
> > > enough to interpret English on the fly. The Z-machine is an evil hack to
> > > get around our unbelievably stupid policy of making computers that are
> > > incompatible with each other. Computer games are an attempt to take our
> > > minds off how lonely and miserable we all are because telepathy hasn't
> > > been invented yet.
> > > </facetious>
>
> First of all, I did not write the "facetious" tags. I was not being
> facetious. (Zen, maybe. Whap!)
>

Matter of fact I did not mean to put the "facetious" tags as if they
were quoted text, it was a typo. I take sole credit for adding them.

> I will restate my point now:
>
> *The Inform libraries are what we have*. They are not the only compromises
> of elegance that I have in my life. Standing up and saying "Wait, this
> isn't perfect!" as if it's some vast revelation gets nothing from me but
> a disgusted glare.

> I respectfully withstand your disgusted glare. However, I don't think
the issue is whether Inform is perfect or not; I think it's an aesthetic
preference regarding whether hacking the libraries is a good idea if it can
possibly be avoided.
Now, in Magnus' case, he offered a solution which, although he clearly
said "I hate doing this", was apparently workable -- make the subject not a
creature for the duration of one turn, then make it one again after taking it.
This is bad because it's a kludge, but in my opinion it's STILL better than
hacking the library... in fact, when I ask an Inform question, I'm always
thinking of hacking the libraries as a last-last-last DESPERATE resort. After
all, I think one changes libraries more often than one changes the game
they're writing; and when you do start a new game, you can easily cut n' paste
things you wrote without having to comb through the old code to remember which
is Graham's and which is yours.

DaveK

unread,
Jan 16, 1997, 3:00:00 AM1/16/97
to

Hello, sailors!

The issue of the library's default conditions and behaviour has been
on my mind as well just lately, for a similar but different reason...

In the alien spaceship that I'm coding at the moment, there's an
operating table (for doing those nasty examinations that aliens tend
to give you when you've been abducted, you know). As soon as you are
foolish enough to lie down on it, a bunch of straps and clamps shoot
out from the sides and hold you down. To stop you getting off the
table, I have a before condition which traps the ##GetOff and ##Exit
actions; if you haven't solved the puzzle of how to escape, they
prevent you leaving..... but look at this..... (transcript simulated,
from memory, so forgive the approximations to the output from Actions
and Routines trace...

> get on table
[Action ##Enter with noun table]
[Running before for table] (doesn't interfere)
[Running after for table] (does interfere, with the following message)
As you climb on to the operating table, snake-like straps whip out
automatically from the sides and tie you firmly down!

> get off table
[Action ##GetOff with noun table]
[Running before for table] (does interfere: prevents it)
But you are held down by the straps!

> get off (or Exit)
[Action ##Exit] (...yep, no noun!, so table's before isn't run)
You get off the table.

Similarly, at a later point, you may still be on the table, and have
a pebble in your hands. Then you may try...

> put pebble on table
[Action PutOn with noun pebble and second table]
[Running before for table with fake action ##Insert]
The straps wrap themselves around the pebble !

...but if you had tried (you are on/in the table, remember)

> drop pebble
[Action drop with noun pebble]
Dropped.

> x table
On the table is a pebble....

.. because the DropSub simply does

move noun to parent(player)

.. when it should really send Insert messages if parent(player) is
a container/supporter. I'm willing to bet there's going to be a few
funnies relating to vehicles as well; if you're driving a Sinclair
C5, for example, you might well be unable to change your underwear
whilst in motion (not a lot of room in one of those, you know); but
<Wear noun> and <Disrobe noun> won't be passed to any before routines
except those of the <noun>. Using a react_before for the vehicle isn't
appropriate either, because it would have to repeat all the library's
checks for whether the object is held, wearable etc.

Now I remember reading a textbook on adventure programming technique
a few years back (I've still got it around somewhere, it's an ancient
thing with code examples in IBM QBasic!), that had a very good and
object-oriented solution to exactly these sort of problems. Under the
system they recommended, all actions were passed all the way up the
object tree until they reached the root (generally the room/location
object), and any stage of the tree could interfere. I don't remember
if this process was recommended to stop at closed containers or not -
although using the usual recursion rules might seem good, you might
want something different to happen in some cases; so I guess that each
object would decide for itself whether to abort the command, pass
it further up the tree, or accept it as definitely ok.

So what I reckon is, that an entire re-write of the library structure
(with the possible exception of the parser, which is a) damn fine as it
stands, and b) damn complex to re-write) may be in order here.

Specifically, the two biggest changes I'd like to implement are:

i) Pass actions ALL the way up the tree in RunRoutines (or wherever),
so as to avoid hideous react_before/react_after complications.
ii) BIG change: Implement a during [; ...] stage. I haven't thought
this out in great detail yet: maybe it should be passed through the
tree, or maybe just the player, noun and second should get to look at
this; they could then either replace or OK the library's default
behaviour for the given case. This means no need to hack the library
nor yet to duplicate the xxxSub's in their entireity....

Errmm. I do have a full time job, so I'm not quite volunteering to
do this just yet. And I'm relying on pubnews severs for my usenet
access, so I can't even guarantee keeping up with discussions here!
Nonetheless, if anyone does have any contributions to this debate,
please cc: me a copy in e-mail, and you never know for sure... just
maybe ....

laters all,

DaveK.

------------------------------------------------------------------------
Disclaimer: Guaranteed safe when used as directed. Some assembly may
be required. Batteries not included. May cause drowsiness. Keep all
e-mail out of the reach of children. Not insured under the Export
Credit Guarantee Scheme. Remember, the value of e-mail may go up as
well as down. No more than 10 persons (1700 lbs) at one time. Contents
may have settled during shipping. Void where prohibited by law.
------------------------------------------------------------------------

Magnus Olsson

unread,
Jan 17, 1997, 3:00:00 AM1/17/97
to

[ Cc to Graham because of unreliable news distribution ]

In article <ant152009f7fM+4%@gnelson.demon.co.uk>, Graham Nelson wrote:
> In article <5bdu63$p...@milo.vcn.bc.ca>, Neil K. Guy

> <n...@vcn.bc.ca> wrote:
> >
> > Andrew Plotkin (erky...@netcom.com) wrote:
> > : Andrew Plotkin (erky...@netcom.com) wrote:
> > : > Also, evil lurks everywhere, so keep your Uzi loaded.
>

> Evil I may be, but at least I post to the newsgroup these days,
> so I'm not quite so much of a lurker.

I sincerely hope, though, that nobody is going to take out his
frustration with Inform on you with a Uzi. :-)

> The substance of this thread is that the Inform library may be
> practical and highly evolved, but has a few very murky corners from
> a conceptual point of view, and in general isn't what we would
> write if we were going to start all over again.

Well, yes. In particular: it is excellent as long as one doesn't want
to modify certain behaviour that is hard-coded in the deep core of the
action routines. The fact that animate objects don't like to be picked
up is an example.

Perhaps I should stress here that it's easy to change that particular
fact by modifying the library itself; however, for reasons explained
in previous posts this is generally not a very desirable thing to
do. The "ideal" library should never need to be changed (except by the
author when adding more functionality).

> I think this
> fair comment (though one should distinguish between the parser
> and the verb library: the parser's not bad at all, I think).

So far, the only things that I've wanted to change in the parser have
been in the category of bugs. My criticism was aimed at the verb library.

> I have occasionally thought that it would be nice to implement
> an entirely new library in a proper object-oriented style.

Yes, it would be nice. It would be similar to what Dave Baggett did
for TADS with WorldClass.

But my main goal in starting this thread was not primarily to urge you
to change the library, or implement a new one, but to point out some
deficiencies in it so that prospective authors of new libraries or
authoring systems can avoid them. Without analysis, we're doomed to
repeat other people's mistakes. I suppose Dave Baggett's had similar
reasons for criticizing the syntax of Inform (which I feel is not
reasonable to change at this stage).

> But
> I can't find a really convincingly OO way to implement the
> typical problems confronting an IF model. The classes of objects
> interact too much. Clashes of priority of different rules
> (some methods in one class, some methods in another, etc.) have
> to be resolved somewhere, and in an explicit way.

This is a problem. I think the reason that it is hard to model the
world (using _any_ paradigm, not just OOM), is that the world _is_ a
complicated place. I have some thoughts about what can be done about
it in the context of IF, but they aren't really mature enough to
mention right now.

But we must distinguish between OO modeling and OO programming. In
principle, you could use any way of modelling the world you like, and
use OO "only" as a way of ensuring modularity and encapsulation.

> Not only
> that, but objects in Inform basically change class dynamically
> and often (as attributes are roughly used to indicate class
> membership).

With all respect, I think you're confusing the concept of "class" in
OOD, which is a static concept, with something more dynamic, something
which seems more equivalent to "state". Objects in OOD don't change
classes, ever; their state changes, though. Perhaps one of the
problems with the design of the Inform library is that you're using
attributes both to represent "class" and "state"?

> These are not insurmountable problems. I'm just not sure that
> I can see the "right" way to object-ify an IF world model.

I'm not entirely certain that there *is* a "right" way. But some ways
are more "right" - or at least more convenient - than others.

> Neither TADS nor Inform entirely convinces me.

Let me hasten to point out that the TADS library certainly has its
problems. There are (a few) cases of exactly the same problem as the
one I've pointed out about the Inform library (the way an object is
listed in an inventory listing, for example, is determined *not* by
any method of the object, but by a big if statement deep inside a
global funtion). And TADS's system of verVerb routines is certainly
very powerful and flexible, but suffers of exactly the problem you
point out when talking about OO modelling of the world: the ver
routines of different objects interact in complex and often
non-intuitive ways, with clashes of priority and resulting in much
gnashing of teeth.

Drone

unread,
Jan 17, 1997, 3:00:00 AM1/17/97
to

Russell Glasser wrote:
>
> Now, in Magnus' case, he offered a solution which, although he clearly
> said "I hate doing this", was apparently workable -- make the subject not a
> creature for the duration of one turn, then make it one again after taking it.
> This is bad because it's a kludge, but in my opinion it's STILL better than
> hacking the library... in fact, when I ask an Inform question, I'm always
> thinking of hacking the libraries as a last-last-last DESPERATE resort. After
> all, I think one changes libraries more often than one changes the game
>

Hi. I'm just learning Inform, but I have a lot of experience in maintaining huge C and C++
applications. While I understand and agree with the philosophical underpinnings of avoiding
library hacks, in the case of Inform, it's really a trivial proposition. I've only had the
libraries for a couple of months and I've already hacked them to include "viral"
(self-replicating) objects and to allow multiple third-person "self objects". All this in service
of writing my first game. Sure I could have done somersaults to do these things and keep it
"library-friendly", but frankly, why bother? Nobody's going to compile my hacks but me, and
porting is also trivial if you flag every hack with comments, as I have done. In fact, I'm looking
forward to see how many hacks I can take out when I convert to 6.10 and the 6/3 libraries, but I'm
waiting for the upgrade to reach the Macintosh compiler. <hint>.

So, yes, it's kludgy, but there's a time for avoiding that, like when you know it's going to come
back and make your life hell. I don't see that in this case.

Paul.
--
foxg...@globalserve.net

Erik Max Francis

unread,
Jan 18, 1997, 3:00:00 AM1/18/97
to

Drone wrote:

> I've only had the
> libraries for a couple of months and I've already hacked them to include
> "viral"
> (self-replicating) objects and to allow multiple third-person "self
> objects". All this in service
> of writing my first game.

Interesting. Could you go into more detail?

--
Erik Max Francis, &tSftDotIotE / email: m...@alcyone.com
Alcyone Systems / web: http://www.alcyone.com/max/
San Jose, California, United States / icbm: 37 20 07 N 121 53 38 W
\
"Gods are born and die, / but the atom endures."
/ (Alexander Chase)

Magnus Olsson

unread,
Jan 19, 1997, 3:00:00 AM1/19/97
to

In article <32E025...@globalserve.net>,

Drone <foxg...@globalserve.net> wrote:
>While I understand and agree with the philosophical underpinnings of avoiding
>library hacks, in the case of Inform, it's really a trivial proposition.

What's trivial? Avoiding library hacks or doing the library hacks? My critique was
that it should be - but isn't - trivial (or at least easy) to avoid hacking the library.

>I've only had the
>libraries for a couple of months and I've already hacked them to include "viral"
>(self-replicating) objects and to allow multiple third-person "self objects".

Sounds interesting. Could you please tell us a little more?

>Sure I could have done somersaults to do these things and keep it
>"library-friendly", but frankly, why bother?

If you don't bother, fine, it's your code.

>Nobody's going to compile my hacks but me,

Other people _compiling_ your code is no problem anyway: just give
them a copy of your hacked library.

>porting is also trivial if you flag every hack with comments, as I have done.

Hmm. Of course it depends on what kind of modifications you do make to the
library, but you might be in for some unpleasant surprises when you upgrade
to 6.10 and library 6/3 - Graham has changed quite a few things.

Anyway, my point was simply this: even if it's not much work migrating your
library hacks to a new library version, a better library design would mean
that you wouldn't have to do any migration work at all.

Drone

unread,
Jan 19, 1997, 3:00:00 AM1/19/97
to

I don't know if this is a duplicate, or if it will thread properly, but my news server was down
and I used another to reply and then I wasn't sure if I really had access and then my real server
went back up but it hasn't yet received the message this is replying to, and, well, obviously it
is (er, was) a long story.

Magnus Olsson wrote:
>
> In article <32E025...@globalserve.net>,
> Drone <foxg...@globalserve.net> wrote:
> >While I understand and agree with the philosophical underpinnings of avoiding
> >library hacks, in the case of Inform, it's really a trivial proposition.
>
> What's trivial? Avoiding library hacks or doing the library hacks? My critique was
> that it should be - but isn't - trivial (or at least easy) to avoid hacking the library.
>

Doing and maintaining the library hacks is trivial, IMHO, meaning that I don't think it
really matters that *avoiding* this is non-trivial. And again, I agree in principle that
avoiding it should be easy.

> >I've only had the
> >libraries for a couple of months and I've already hacked them to include "viral"
> >(self-replicating) objects and to allow multiple third-person "self objects".
>
> Sounds interesting. Could you please tell us a little more?
>

It started off with how much I hated the implementation of the ASK/TELL paradigm in Inform.
It just looked to make my life incredibly difficult (I'm BIG on character interaction). I
looked over the libraries and decided that the problem was that they stubbornly refused to
allow the "concept" being asked about to have an object of its own. I considered the
problems inherent in implementing this, and decided that it called for a type of object
that can attach to an object, and replicate a copy of itself into the head of any
"sentient" that ever comes into scope, including NPCs.

So, for example, not only do you have a "rockfall" object, but you have an "idea of the
rockfall" object attached to it, with an each_turn routine that checks for sentients and
"infects" them with copies itself, meaning that sentients who see the rockfall, know about
it. Thus, a new type of object which I called a Viral. I implemented this, and changed the
ask and tell routines to make use of it, and to allow themselves to be overridden by "Ask"
and "Tell" routines either in a specific Sentient object or in a specific Concept object.
Added a few standard viral handling methods, such as x.infects(y), &c., and I had a
complete system which prevented me (I hope) from ever having to use a parse.word loop for
character interaction.

So now I've set about writing the game this depends upon. Working smoothly so far.

For reasons related to my emphasis on story (I was an English Lit major), I have never
liked second-person, and I also hacked the libraries to allow true multiple self-objects
rather than Inform's rather clumsy exception-style way of implementing multiple-character
control. Part of my take on this is changing all the standard library_messages to speak in
third person, and to allow any individual character object to override any particular
library_message (without overriding the whole routine), thus making the game respond to you
differently depending on your current "host". So in effect, my game is going to have a
partly new library_messages routine for each character you can control. This matches my
philosophy that the parsed commands should be directed "at" the main character, who
performs them, rather than at yourself. Just my personal preference, please. I realise that
plenty of excellent and very atmospheric games have been written in 2nd P. I'm not looking
for a paradigm war.

> >Sure I could have done somersaults to do these things and keep it
> >"library-friendly", but frankly, why bother?
>
> If you don't bother, fine, it's your code.
>

Just MHO. I'm not an Inform theorist. I'm just trying to write some games with it, so I
don't agonise over hacking the libraries if, as I said, I don't think it will come back and
bite me very hard. But again, this doesn't really match my general philosophy about
programming.

> >porting is also trivial if you flag every hack with comments, as I have done.
>
> Hmm. Of course it depends on what kind of modifications you do make to the
> library, but you might be in for some unpleasant surprises when you upgrade
> to 6.10 and library 6/3 - Graham has changed quite a few things.
>

Fair enough. Maybe I'll come back here with fresh bite marks on my butt and eat my words.

> Anyway, my point was simply this: even if it's not much work migrating your
> library hacks to a new library version, a better library design would mean
> that you wouldn't have to do any migration work at all.
>

Well, I certainly wouldn't complain if that were the case.

> --
> Magnus Olsson (m...@df.lth.se, zeb...@pobox.com)

Drone.
--
"Esse Est Percipi."
foxg...@globalserve.net

drone

unread,
Jan 20, 1997, 3:00:00 AM1/20/97
to

Erik Max Francis wrote:

>
> Drone wrote:
>
> > I've only had the
> > libraries for a couple of months and I've already hacked them to include
> > "viral"
> > (self-replicating) objects and to allow multiple third-person "self
> > objects". All this in service
> > of writing my first game.
>
> Interesting. Could you go into more detail?
>

Well, I don't know if you're server shows you my reply to
Magnus Olsson (mine seems not to like what's in it since it
refuses to post it but not my other messages), but I do go into
more detail there.

Drone.
--
"esse est percipi"
foxg...@globalserve.net

drone

unread,
Jan 20, 1997, 3:00:00 AM1/20/97
to

Well I don't know why I can't get this particular message to show up on my
server and because of recent technical glitches here on Globalserve, I don't
know what's going on, but here's my last try. If this is the 2nd or 3rd time
you're seeing this, sorry...

Magnus Olsson wrote:
>
> In article <32E025...@globalserve.net>,
> Drone <foxg...@globalserve.net> wrote:
> >While I understand and agree with the philosophical underpinnings of avoiding
> >library hacks, in the case of Inform, it's really a trivial proposition.
>
> What's trivial? Avoiding library hacks or doing the library hacks? My critique was
> that it should be - but isn't - trivial (or at least easy) to avoid hacking the library.
>
Doing and maintaining the library hacks is trivial, IMHO, meaning that I don't think it
really matters that *avoiding* this is non-trivial. And again, I agree in principle that
avoiding it should be easy.

> >I've only had the


> >libraries for a couple of months and I've already hacked them to include "viral"
> >(self-replicating) objects and to allow multiple third-person "self objects".
>

Erik Max Francis

unread,
Jan 21, 1997, 3:00:00 AM1/21/97
to

drone wrote:

> Well, I don't know if you're server shows you my reply to
> Magnus Olsson (mine seems not to like what's in it since it
> refuses to post it but not my other messages), but I do go into
> more detail there.

If the error message comes from your server, it likely didn't get posted.

Drone

unread,
Jan 23, 1997, 3:00:00 AM1/23/97
to

Erik Max Francis wrote:
>
> drone wrote:
>
> > Well, I don't know if you're server shows you my reply to
> > Magnus Olsson (mine seems not to like what's in it since it
> > refuses to post it but not my other messages), but I do go into
> > more detail there.
>
> If the error message comes from your server, it likely didn't get posted.
>

Magnus has informed me by e-mail that the message has posted at least twice.
If you haven't seen it, who knows what's going on, but in order to avoid
tipping into spammage with a semi-long message, I'll e-mail it to you.

Reply all
Reply to author
Forward
0 new messages