Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Lessons learned creating an IF authoring system ?

28 views
Skip to first unread message

David Fisher

unread,
Jun 15, 2005, 10:41:19 PM6/15/05
to
I was wondering what kinds of lessons people who have created (or started to
create) an IF authoring system have learned ...

There are a few comments in the RAIF archives I have found, but I would love
to hear what people have to say about this topic. Here are some I can think
of / remember:

* Parsers are tricky to write (obviously !)

* A well designed World Model is at least as important as a good parser (and
is intricately linked with the parser, eg. when performing disambiguation)

* Don't make assumptions about the kinds of games that will be written in
the language.

* Don't hard wire stuff - put everything in a library so it can be
overridden and/or replaced completely. Add "hooks" to let game authors
override specific behaviour in the library without having to edit the
library source.

* Target an existing virtual machine if possible (eg. Glulx) to take
advantage of existing interpreters on different platforms.

* Try to provide a simple "entry level" for beginning programmers without
preventing more complex things from being done.

* Allow standard data structures to be created (as in normal programming
languages), eg. 2 dimensional arrays, graphs / networks, etc.

Thanks for any deep thoughts (or shallow thoughts :-),

David Fisher


Andrew Plotkin

unread,
Jun 15, 2005, 11:56:46 PM6/15/05
to
Here, David Fisher <da...@hsa.com.au> wrote:
> I was wondering what kinds of lessons people who have created (or started to
> create) an IF authoring system have learned ...

The first problem was making the damn thing run at all, and be
customizable. AGT did that (among many others).

The second problem was putting in clean abstractions for actions and
objects. (The world model is a minor side effect of this.) TADS 2 and
Inform 6 did that.

The third problem will be scalability. Does each bit of customization
you write, for an action or object, make the next one harder to think
about? Inform 6 does that for simple, non-overlapping customizations.
For complex ones... it works for about two iterations, and then starts
to shake itself apart.

I've seen enough of the draft Inform 7 to think that it *might* do
this right. I can't tell yet.

(Obviously, there's no point in even trying the third problem unless
you've got the first two down pat.)

--Z

"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*
I'm still thinking about what to put in this space.

Mike Rozak

unread,
Jun 16, 2005, 12:28:22 AM6/16/05
to
Not to sound too negative, but...


> * Parsers are tricky to write (obviously !)

Anyone that thinks parsers are tricky to write probably shouldn't be writing
an authoring toolkit. There are a lot more complex things, such as an actual
scripting language, database, 3D graphics, AI, multiuser support, game
design theory, and other bits. I think I have ordered and read about 50
books since starting my IF authoring toolkit, and only one of them goes into
detail about parsers. (Which is the book on writing game scripting
languages.)


> * Don't make assumptions about the kinds of games that will be written in
> the language.

The more assumptions you can make about the game that will be written, the
easier you can make it for the authors. (After all, if you make NO
assumptions whatsoever you get C++, Java, etc. with all the graphics
libraries and whatnot.) I would agree that making "as few assumptions as
possible" is good though.


> * Target an existing virtual machine if possible (eg. Glulx) to take
> advantage of existing interpreters on different platforms.

This is the last thing I'd do. Inform and TADS do a great job at what
they're trying to do. If you target a Glux VM then your authoring system
will produce text IF titles (with some token graphics support) that won't be
any different than what Inform or TADS can produce.

There's no point reinventing the wheel. If your system can't produce an
experience that's markedly different than what's already available then why
do it? (Unless you just want to have fun writing a development tool, and
don't care how many people will use it. Programming an authoring system for
fun is perfectly valid.)

To produce a tool that hasn't been produced 100 times before, you need good
graphics and sound, and probably multiuser support.

> * Try to provide a simple "entry level" for beginning programmers without
> preventing more complex things from being done.

This is a good goal, but you'll discover that if you try to make everything
very easy (aka: no programming) then the system won't be flexible enough and
all the games will be similar. If you allow flexibility, you'll require
programming and people who can't program won't be able to use it. If you
make a dual-mode UI, an easy programming-free mode and a difficult
programming-mode, then users will first learn the programming-free mode, and
then RE-LEARN the programming mode when they discover the programming-free
mode doesn't do what they want.

Some important things you didn't mention:

- English is the 1st language of only 10%(?) of the world's population.

- Artificial intelligence... and not just the A* algroithm. You need
semi-intelligent NPCs, including ones that you can converse with.

--

Mike Rozak
http://www.mxac.com.au


Andrew Plotkin

unread,
Jun 16, 2005, 1:21:01 AM6/16/05
to
Here, Mike Rozak <Mike...@bigpond.com> wrote:
>
> > * Target an existing virtual machine if possible (eg. Glulx) to take
> > advantage of existing interpreters on different platforms.
>
> This is the last thing I'd do. Inform and TADS do a great job at what
> they're trying to do. If you target a Glux VM then your authoring system
> will produce text IF titles (with some token graphics support) that won't be
> any different than what Inform or TADS can produce.

The abilities of the VM were the *first* problem. Long solved. Not
interesting any more.

The current constraints IF are allowing the author to design the
game, not making the output dance or solve the Halting Problem.

David Fisher

unread,
Jun 16, 2005, 4:03:57 AM6/16/05
to
"Mike Rozak" <Mike...@bigpond.com> wrote in message
news:Gd7se.18189$F7....@news-server.bigpond.net.au...

>> * Parsers are tricky to write (obviously !)
>
> Anyone that thinks parsers are tricky to write probably shouldn't be
> writing an authoring toolkit.

[snip]

Tricky as in "complex and requiring careful thought" ... not as in "no idea
how it would be done". Surely you agree that it is a complex task, not a
trivial one ?

See the thread "Next level parser" for an idea of what I am thinking about:
http://groups-beta.google.com/group/rec.arts.int-fiction/browse_frm/thread/6388498003889b17

>> * Don't make assumptions about the kinds of games that will be written in
>> the language.
>
> The more assumptions you can make about the game that will be written, the
> easier you can make it for the authors. (After all, if you make NO
> assumptions whatsoever you get C++, Java, etc. with all the graphics
> libraries and whatnot.) I would agree that making "as few assumptions as
> possible" is good though.

Some examples of assumptions to avoid:

* The game is always set underground, and so every location has a north,
south, east & west wall (and a ceiling)
* The PC will never change to another character
* Objects never occupy more than one location (eg. a river)
* "No one would ever want to ..." (use real time input, floating point
coordinates, etc)

>> * Target an existing virtual machine if possible (eg. Glulx) to take
>> advantage of existing interpreters on different platforms.
>
> This is the last thing I'd do. Inform and TADS do a great job at what
> they're trying to do. If you target a Glux VM then your authoring system
> will produce text IF titles (with some token graphics support) that won't
> be any different than what Inform or TADS can produce.

??? I see a virtual machine as something similar to "hardware" on which a
low level, assembly-like language runs ... there is an infinite variety of
programs which can be run on such a machine. Some are more difficult to
produce than others, depending on the language you compile from ... a
Prolog-like IF language would be difficult to simulate using TADS or Inform,
for example.

The pros and cons of using an existing virtual machine that I can see are
follows:

(+) Portability. No need to write a new interpreter for each platform you
want it to run on; and people can use their favourite interpreters without
modification.
(+) Development. Existing VMs are tested and reliable, and save you from
having to develop & test your own.
(-) Code size and speed. If you want to do something processor intensive,
such as a rule-based system with lots of backtracking, it might be better to
put the code/logic in the interpreter directly rather than in the game
itself.
(-) Inefficient use of resources. Maybe the source language doesn't match
the target VM very well (which would be the case if you tried to compile
TADS to Z code, from people's previous comments). Glulx seems to be a nice
general purpose VM, not strongly tied to the Inform language, so this should
be less of a problem than for Z code.

> There's no point reinventing the wheel. If your system can't produce
> an experience that's markedly different than what's already available
> then why do it?

Well, the point is exactly that - what I am thinking of doesn't actually
exist.

The experience would be different (with the kind of parsing mentioned
above), but even if it wasn't, it would be valid enough to create a language
with a different approach to IF authoring ... you can write equivalent
programs in LISP, C and Smalltalk, but that doesn't mean that any of the
three should not have been invented.

>> * Try to provide a simple "entry level" for beginning programmers without
>> preventing more complex things from being done.
>
> This is a good goal, but you'll discover that if you try to make
> everything very easy (aka: no programming) then the system won't be
> flexible enough
> and all the games will be similar.

Definitely ... although I don't equate "easy" with "no programming".
Programming will always be required to write IF. Otherwise it's just "F" :-)

> If you allow flexibility, you'll require programming and people who can't
> program won't be able to use it.

I believe it is possible to have a "slope" rather than a "cliff edge"
dividing the basic stuff from more complex programming ... it seems a bit
extreme to say that flexibility inevitably leads to something that is
unusable by people with no programming background.

> Some important things you didn't mention:
>
> - English is the 1st language of only 10%(?) of the world's population.
>
> - Artificial intelligence... and not just the A* algroithm. You need
> semi-intelligent NPCs, including ones that you can converse with.

(Good points ...)

Thanks,

David Fisher


Jacek Pudlo

unread,
Jun 16, 2005, 4:17:47 AM6/16/05
to
A couple of months ago, from the Prince of Hypocrisy:

"Since the system [Inform 7] has not yet been finalized, it wouldn't really
be appropriate for us to start trumpeting it yet."


Now:

> I've seen enough of the draft Inform 7 to think that it *might* do
> this right. I can't tell yet.

Oooh! Andy gets to play with the latest toys while the rest of us kiddies
can only watch and salivate.


Didn't Graham tell you to keep your mouth shut?


Isn't it kind of funny how Graham, who puts in all the hard work, never
flaunts his feathers here, but Plotkin, who's just a bystander, struts
around like a peacock just because he's seen a draft?


JohnyMrNinja

unread,
Jun 16, 2005, 6:12:41 AM6/16/05
to
Andrew Plotkin wrote:

> I've seen enough of the draft Inform 7 to think that it *might* do
> this right. I can't tell yet.

I thought we weren't supposed to be discussing Inform 7 just yet...

JohnnyMrNinja

unread,
Jun 16, 2005, 8:24:13 AM6/16/05
to

JohnnyMrNinja did not write that, gonad. I am *very* sorry that Andrew
Plotkin doesn't like you in *that way*, but please don't disturb the
rest of the playground. There is a picture of Zarf somewhere, though it
may only be his face, perhaps you can paste it on a Fabio cutout? It
may then be difficult for you to continue typing after that.

I really don't give a damn who you don't like, but please start your
own threads instead of degrading the threads of people who are just
trying to discuss IF. You can pretend to be whoEVER you want, and lets
all have a good *giggle* about it. I can't stop you, and if you think
it's funny, you can. I'll tell you it's not. What's funny is using
words like "Gonad" or "Pee-Pee".

Seriously, you sound like a bitter ex-girlfriend, one he dumped because
she'd never laugh at the right times during movies.

Now excuse me, I have to make the pee-pee.

~THE REAL
JohnnyMrNinja~
Coming to UPN this Fall!

P.S. - Please ignore this intrusion into an otherwise productive
thread.

P.P.S -


> I thought we weren't supposed to be discussing Inform 7 just yet...

I'll be discussin' yo mama ALL NIGHT!!! WHOOOO-HOOO!
Thank you.

Andrew Plotkin

unread,
Jun 16, 2005, 11:24:49 AM6/16/05
to
Good thing I was so vague, then. :)

Adam Thornton

unread,
Jun 16, 2005, 4:14:47 PM6/16/05
to
In article <LAase.140395$dP1.4...@newsc.telia.net>,

Jacek Pudlo <ja...@jacek.jacek> wrote:
>Isn't it kind of funny how Graham, who puts in all the hard work, never
>flaunts his feathers here, but Plotkin, who's just a bystander, struts
>around like a peacock just because he's seen a draft?

I FEEL A DRAFT.
(M)OVE OR (S)HOOT?

Adam

samwyse

unread,
Jun 16, 2005, 11:41:25 PM6/16/05
to
Jacek Pudlo wrote:
> Oooh! Andy gets to play with the latest toys while the rest of us kiddies
> can only watch and salivate.

You mean you don't have your copy yet? I'll do everything I can to
correct that oversight.

ke...@lysseus.com

unread,
Jun 17, 2005, 5:01:57 PM6/17/05
to

Andrew Plotkin wrote:
> Here, David Fisher <da...@hsa.com.au> wrote:
> > I was wondering what kinds of lessons people who have created (or started to
> > create) an IF authoring system have learned ...
>
> The first problem was making the damn thing run at all, and be
> customizable. AGT did that (among many others).
>
> The second problem was putting in clean abstractions for actions and
> objects. (The world model is a minor side effect of this.) TADS 2 and
> Inform 6 did that.

Should we take it then that there will be no changes to the
abstractions in Inform 7?

> The third problem will be scalability. Does each bit of customization
> you write, for an action or object, make the next one harder to think
> about? Inform 6 does that for simple, non-overlapping customizations.
> For complex ones... it works for about two iterations, and then starts
> to shake itself apart.
>
> I've seen enough of the draft Inform 7 to think that it *might* do
> this right. I can't tell yet.

That's a tough one. TADS 3 improves on this from TADS 2, but even so,
there are are areas in the library where customizations might conflict
(one example would be the tokenizer, where library extensions adding
new tokens might clash).

The other difficulty, of course, is in getting the community to take
full advantage of the design. The advantages of using the library the
way it was designed may be tremendous, but it'll take a certain amount
of learning curve.

--Kevin

David Fisher

unread,
Jun 18, 2005, 4:04:33 AM6/18/05
to
<ke...@lysseus.com> wrote in message
news:1119042117.7...@g43g2000cwa.googlegroups.com...

>
> Andrew Plotkin wrote:
>> The third problem will be scalability. Does each bit of customization
>> you write, for an action or object, make the next one harder to think
>> about? Inform 6 does that for simple, non-overlapping customizations.
>> For complex ones... it works for about two iterations, and then starts
>> to shake itself apart.
>>
>> I've seen enough of the draft Inform 7 to think that it *might* do
>> this right. I can't tell yet.
>
> That's a tough one. TADS 3 improves on this from TADS 2, but even so,
> there are are areas in the library where customizations might conflict
> (one example would be the tokenizer, where library extensions adding
> new tokens might clash).
>
> The other difficulty, of course, is in getting the community to take
> full advantage of the design. The advantages of using the library the
> way it was designed may be tremendous, but it'll take a certain amount
> of learning curve.

How's the documentation for TADS 3 going, by the way ? Anything the general
public can look at ?

David Fisher


Eric Eve

unread,
Jun 18, 2005, 4:52:52 AM6/18/05
to
"David Fisher" <da...@hsa.com.au> wrote in message
news:OBQse.19930$Le2.1...@nasal.pacific.net.au...

> How's the documentation for TADS 3 going, by the way ? Anything
> the general public can look at ?

In a fairly recent post on the TADS 3 list Mike Roberts indicated
that the TADS 3 manual was still some way off. There is some
documentation that's been available for a while, however, namely the
language documentation that comes with the TADS 3 distribution and
the technical articles at http://www.tads.org/articles.htm. There's
also quite a bit of unofficial documentation produced by people
other than Mike, for example at
http://webhome.idirect.com/~dswxyz/t3/index.html,
http://kwi.homepage.dk/t3/ and
http://users.ox.ac.uk/~manc0049/TADSGuide/intro.htm.

-- Eric


soufflec...@gmail.com

unread,
Jun 18, 2005, 5:05:48 PM6/18/05
to
>Oooh! Andy gets to play with the latest toys while the rest of us kiddies
>can only watch and salivate.
>Didn't Graham tell you to keep your mouth shut?
>Isn't it kind of funny how Graham, who puts in all the hard work, never
>flaunts his feathers here, but Plotkin, who's just a bystander, struts
>around like a peacock just because he's seen a draft?

Hahahah! STILL hilarious after all these years!

You're amazingly fresh and relevant! Don't you ever quit posting these
zingers. You haven't even remotely grown tiresome and stale!

Jacek Pudlo

unread,
Jun 18, 2005, 8:51:54 PM6/18/05
to
<soufflec...@gmail.com> skrev i meddelandet
news:1119128748.4...@g44g2000cwa.googlegroups.com...

Your writing is so controlled and your sarcasm so subtle that at first I
thought you were being serious. You clearly possess a considerable comedic
talent. Make sure you don't waste it.

soufflec...@gmail.com

unread,
Jun 19, 2005, 2:05:37 AM6/19/05
to
>Your writing is so controlled and your sarcasm so subtle that at first I
>thought you were being serious. You clearly possess a considerable comedic
>talent. Make sure you don't waste it.

Well, you're from the Third World, which of course means you're quite
stupid and slow. I can understand if you didn't get it at first. After
all, if you had a better grasp of English you'd have more range than
continually bleating "Waaaaah Plotkin!"

But don't let me stop you! You're doing the Lord's work here! Hahaha,
you called him "Andy!" Good one, I bet it stung! ROFL!!

Hassan

unread,
Jun 19, 2005, 8:59:18 AM6/19/05
to
soufflec...@gmail.com wrote in message news:<1119161137.6...@o13g2000cwo.googlegroups.com>...

> >Your writing is so controlled and your sarcasm so subtle that at first I
> >thought you were being serious. You clearly possess a considerable comedic
> >talent. Make sure you don't waste it.
>
> Well, you're from the Third World, which of course means you're quite
> stupid and slow. I can understand if you didn't get it at first. After
> all, if you had a better grasp of English you'd have more range than
> continually bleating "Waaaaah Plotkin!"

Save your strength for the POWs in Iraq, cowboy. I hear some of them
haven't been raped yet. A most unfortunate oversight by the US
military. The good thing is that your dick is so small they won't feel
anything.

God bless America!

JohnnyMrNinja

unread,
Jun 19, 2005, 9:40:20 AM6/19/05
to
Hassan wrote:
> Save your strength for the POWs in Iraq, cowboy. I hear some of them
> haven't been raped yet. A most unfortunate oversight by the US
> military. The good thing is that your dick is so small they won't feel
> anything.
>
> God bless America!

All this learned while creating an IF authoring system? Surely these
features are going too far.

steve....@gmail.com

unread,
Jun 22, 2005, 4:36:58 PM6/22/05
to
Andrew -- could you please elaborate a bit on what you mean by
scalability?

You specifically address action and object customizations. I think
you're saying that more than two levels of customization become
problematic. Is this because layers of custom-actions and
custom-objects produce sort-of exponential combinational complexity? Is
it because it's godawful to keep track of which customization(s)
is(are) going to prevail when there's a conflict?

Let me explain very quickly how TADS-3 handles this. (I'm skipping
action resolution and the parser stuff, and I'm simlpifying a bit; but
I'll enter whatever greater detail you think is relevant to this
discussion. Right now, I just want to frame the question.)

There are several stages of action processing. Take one for example:
each object that might be involved in the action is verified for the
action; it can inherit any of its parents' verify() routines at any
time within its own verify() block, or it might not inherit its
parents' routines at all. Likewise with the pre-action check()
code-block, or the action() code-block.

There's a few other routines for action processing, but to give you a
rough picture: verify() is used to determine which objects are sensical
for the given command; check() is used to disallow a command, after the
objects have been resolved; action() carries out the command. These
methods are called on each of the objects involved in the action, per
stage; whether they're called first on the direct-object or the
indirect-object is determined by the action.

While it is typical for the child object to inherit its behavior from
the parent class (for any of the above-described process-stages), it is
also normal for this inheritance to be overridden or conditional. Where
there are multiple parents, sometimes it inherits from either one or
the other.

So, because the action process is sliced up in a useful way, and
because inheritance is optional, I don't think scalability is much of a
problem in Tads-3. In the library we see four- or five-deep
customizations, with no problem. I see seven- or eight-deep
customizations in some games, and this seems quite usual and intuitive.
In short, it scales fine. Unless I'm missing your point...

So, please elaborate. I'm not sure what you mean. I don't think you're
simply saying that Inform-6 doesn't have an adequate inheritance
structure for action processing, and I don't think you've concluded
that the problem is simply that the action stages have not been
appropriately broken-down.

===

It's been a few days since this was seriously discussed, so I'll quote
as a refresher:

> The third problem will be scalability. Does each bit of customization
> you write, for an action or object, make the next one harder to think
> about? Inform 6 does that for simple, non-overlapping customizations.
> For complex ones... it works for about two iterations, and then starts
> to shake itself apart.
>
> I've seen enough of the draft Inform 7 to think that it *might* do
> this right. I can't tell yet.

(Kevin wrote something about the scalability of the tokenizer. -- I
guess this is somewhat off-topic, if we're talking about action and
object customizations. But, ya, the question is in the same area of
design issues.)

Andrew Plotkin

unread,
Jun 25, 2005, 12:57:35 PM6/25/05
to
Here, steve....@gmail.com wrote:
> Andrew -- could you please elaborate a bit on what you mean by
> scalability?
>
> You specifically address action and object customizations. I think
> you're saying that more than two levels of customization become
> problematic.

More than one *kind* of customization becomes problematic.

> Is this because layers of custom-actions and custom-objects produce
> sort-of exponential combinational complexity? Is it because it's
> godawful to keep track of which customization(s) is(are) going to
> prevail when there's a conflict?

Yes. In Inform there's a third root-level notion, the "react_before",
which is a customization based on *what is nearby*. And notionally
there are many other conditional customizations used in particular
games: whether you're drunk, what time it is, whether you're carrying
the sword.

The interactions between these always requires special attention.
Either you can't control which customizations override which, or you
can but it requires fiddling around.

Conclusion: a next-stage IF system requires the ability to treat all
conditional customizations as first-class objects, with direct control
over how conflicts resolve. "Object orientation" just isn't a useful
model, because the problem involves sets of predicates, not single
objects.

(People have talked in the past about "multiple dispatch". I haven't
seen a formal definition of this concept, but I believe the idea is OO
with methods resolved by sets of objects, not single objects. Problem
is, IF isn't about objects. You need logical analysis to determine
which conditionals conflict, so it's in the realm of Prolog, not
object orientation.)

Then there's the idea of phases -- I haven't worked with TADS, but you
describe check/verify/do. Inform doesn't really have phases at all
(the before/after distinction doesn't map to verify/do), although
people have tried to add them (various library extensions, or Platypus
which is a complete library replacement).

My problem with all of this is that no fixed list of phases is
actually adequate. When I start trying to break down specific design
problems from my own work, I realize that I'm *always* adding in
subphases and sub-subphases.

Conclusion: a next-stage IF system requires the ability to treat all
conditional customizations as first-class objects, with direct control
over what order they're applied in... hey! This is the same as my
previous conclusion!

So when I talk about scalability, what I'm thinking is that nobody has
actually solved this problem. There are hacks in existing models that
let you control these factors *for a while* -- just as previous-
generation IF systems let you customize the names of objects, *in some
ways*. It kind of worked, but quickly got brittle and broke down.

I have many screens of notes "Towards a calculus of IF conditional
customizations". I have not yet succeeded in inventing a model that I
like. When I do, I'll write an IF compiler, and I7 and TADS 3 will
become vague footnotes in history.

(Note: humor.)

David Fisher

unread,
Jun 27, 2005, 8:10:38 PM6/27/05
to
"Andrew Plotkin" <erky...@eblong.com> wrote in message
news:d9k2dv$6m0$1...@reader1.panix.com...

> ... a next-stage IF system requires the ability to treat all


> conditional customizations as first-class objects, with direct
> control over how conflicts resolve. "Object orientation" just
> isn't a useful model, because the problem involves sets of
> predicates, not single objects.

I guess the problem is that these conflicts & resolutions are scattered
throughout the code, and/or implicit (in the inheritance rules, etc).

What about a language + compiler which:

(i) Requires every conflict to be explicitly resolved in the code, and
(ii) (Optionally) generates any missing resolution code for you, using
default rules you supply. You can then check all of the generated
resolutions manually and adjust them as necessary.

One possible problem with this is that if the compiler doesn't know all of
the possible combinations of (potentially conflicting) classes at compile
time (eg. if the class of an object can be dynamically changed at run time),
then the explicit resolution for all possible combinations of classes must
be specified - which is 2 to the power of the number of classes (or 2^N -
N - 1 if you want to be pedantic and exclude the case of 1 or 0 classes :-)

Just thinking about it, maybe rule (ii) above is going a bit far ... instead
of having to be explicit about all combinations, I guess a set of *explicit*
rules about conflict resolutions could be used; for example, action X in
class A always overrides (replaces) action X in any other class. This loses
a little bit of the benefit of being able to explicitly see all the rules,
though ...

What are the possible resolutions if a class C inherits both A::X and B::X ?

(a) A::X replaces B::X
(b) A::X is called before B::X (unless A::X returns a particular value)
(c) A new function C::X2 is called instead

I'm sure more complicated situations could happen as well, but (c) should be
general enough to handle them ... for example, C::X2 could be defined as
"call A::X and B::X, and if they both return false, do something".

Or am I thinking on a completely different track ?

David Fisher


Andrew Plotkin

unread,
Jun 27, 2005, 9:39:59 PM6/27/05
to
Here, David Fisher <da...@hsa.com.au> wrote:
> "Andrew Plotkin" <erky...@eblong.com> wrote in message
> news:d9k2dv$6m0$1...@reader1.panix.com...
>
> > ... a next-stage IF system requires the ability to treat all
> > conditional customizations as first-class objects, with direct
> > control over how conflicts resolve. "Object orientation" just
> > isn't a useful model, because the problem involves sets of
> > predicates, not single objects.
>
> I guess the problem is that these conflicts & resolutions are scattered
> throughout the code, and/or implicit (in the inheritance rules, etc).

If the language supports them as first-class entities, they can be
extracted. And implicit rules just give you more information.



> One possible problem with this is that if the compiler doesn't know
> all of the possible combinations of (potentially conflicting)
> classes at compile time (eg. if the class of an object can be
> dynamically changed at run time), then the explicit resolution for
> all possible combinations of classes must be specified - which is 2
> to the power of the number of classes (or 2^N - N - 1 if you want to
> be pedantic and exclude the case of 1 or 0 classes :-)

Well, for a start, I wouldn't allow the class of an object to be
dynamically changed at run-time. (Neither TADS nor Inform allows
this.) See, already the problem gets simpler. :)

(Inform allows you to add or delete the "container" and "supporter"
attributes to an object dynamically, but that's a historical mistake.
There's no need to repeat it.)

But look: the compiler *does know* all the combinations of classes at
compile time. It's compiling the object list. If there's a rule on
containers and a rule on supporters, that's not a conflict -- unless
you create an object which is *both a container and a supporter*. (If
you do that, then it's your responsibility to resolve the conflict.
Obvious, right?)

As to exponential explosion -- expressing a precedence order for
conflicting rules lets you define all the behavior in N statements,
not 2^N.

David Fisher

unread,
Jun 27, 2005, 10:05:44 PM6/27/05
to
"Andrew Plotkin" <erky...@eblong.com> wrote in message
news:d9q9pf$g7o$1...@reader1.panix.com...

> Here, David Fisher <da...@hsa.com.au> wrote:
>> "Andrew Plotkin" <erky...@eblong.com> wrote in message
>> news:d9k2dv$6m0$1...@reader1.panix.com...
>>
>> > ... a next-stage IF system requires the ability to treat all
>> > conditional customizations as first-class objects, with direct
>> > control over how conflicts resolve. "Object orientation" just
>> > isn't a useful model, because the problem involves sets of
>> > predicates, not single objects.
>>
>> I guess the problem is that these conflicts & resolutions are scattered
>> throughout the code, and/or implicit (in the inheritance rules, etc).
>
> If the language supports them as first-class entities, they can be
> extracted. And implicit rules just give you more information.

What might that look like ? Could you give an example of an (imaginary)
language construct where they are first class entities ?

I don't understand the statement, "implicit rules just give you more
information" ...

> As to exponential explosion -- expressing a precedence order for
> conflicting rules lets you define all the behavior in N statements,
> not 2^N.

Assuming the conflict resultion rules are this simple; eg. what if the
resolution of inheriting A::X, B::X and C::X is a custom function which
cannot be deduced from the resolution of combining any pair of these ?

You also wrote in a previous post:

> I have many screens of notes "Towards a calculus of IF conditional
> customizations". I have not yet succeeded in inventing a model that
> I like.

I would love to hear where you have come to so far ...

Thanks,

David Fisher


Andrew Plotkin

unread,
Jun 28, 2005, 12:41:29 PM6/28/05
to
Here, David Fisher <da...@hsa.com.au> wrote:
> "Andrew Plotkin" <erky...@eblong.com> wrote in message
> news:d9q9pf$g7o$1...@reader1.panix.com...
> > Here, David Fisher <da...@hsa.com.au> wrote:
> >> "Andrew Plotkin" <erky...@eblong.com> wrote in message
> >> news:d9k2dv$6m0$1...@reader1.panix.com...
> >>
> >> > ... a next-stage IF system requires the ability to treat all
> >> > conditional customizations as first-class objects, with direct
> >> > control over how conflicts resolve. "Object orientation" just
> >> > isn't a useful model, because the problem involves sets of
> >> > predicates, not single objects.
> >>
> >> I guess the problem is that these conflicts & resolutions are scattered
> >> throughout the code, and/or implicit (in the inheritance rules, etc).
> >
> > If the language supports them as first-class entities, they can be
> > extracted. And implicit rules just give you more information.
>
> What might that look like ? Could you give an example of an (imaginary)
> language construct where they are first class entities ?

I've been using "rule <R>: handle <atom> as <code> if <condition>" in
my notes. An atom is more or less a function name. Rules are named so
that you can refer to them with some construct like "R1 > R2", to
define a precedence.



> I don't understand the statement, "implicit rules just give you more
> information" ...

Well, if A is a subclass of B, then the conditional "O ofclass A" is a
subset of "O ofclass B". You can then presume that a rule with the
former condition has a higher precedence than a rule with the latter
-- it's a specific exception.

> > As to exponential explosion -- expressing a precedence order for
> > conflicting rules lets you define all the behavior in N statements,
> > not 2^N.
>
> Assuming the conflict resultion rules are this simple; eg. what if the
> resolution of inheriting A::X, B::X and C::X is a custom function which
> cannot be deduced from the resolution of combining any pair of these ?

First of all, the fact that X is a class method is a distraction.
You're entangling conflict resolution with the class hierarchy, which
is just what I want to avoid -- except for the kind of implied
precedence I just mentioned.

The question is: the code invokes atom X, under a set of conditions
(object is O, action is A, the troll is angry, it's Thursday...) What
do we do?

I think you're describing the case where we have these rules: (Where B
and C are subclasses of A.)

R1: handle X as [...code1...] if (O ofclass A)
R2: handle X as [...code2...] if (O ofclass B)
R3: handle X as [...code3...] if (O ofclass C)

If there were no R3, this would be easy: it would translate as

if (O ofclass B) [...code2...]
else if (O ofclass A) [...code1...]
else [...run the default code for X...]

Given all three rules, if there's no object which is both B and C,
it's still easy.

If we have all three rules and an object which *is* both B and C,
that's a conflict. The compiler must throw an error. To resolve it,
either the user has to add a declaration "R2 < R3" or "R2 > R3", or
add a fourth rule:

R4: handle X as [...code4...] if (O ofclass B) and (O ofclass C)

Note that the compiler has to be smart enough to do Venn diagrams.

I have lots of these simple examples. What I don't have is a general
model that correctly handles all of them. There are lots of
complications -- particularly with the problem of gaining access to
overridden or renamed bits of code. Which you *do* often want to do.

(As you note, one very common case is wanting to do Y before X. In
other words, "handle X as [Y,X]." But coming up with a consistent
semantics for resolving which "X" you mean is hard. Easy for that base
case, but hard in general. Trust me, my legion of examples is vast --
and they're drawn from actual IF cases, not just arbitrary
combinations of letters. Darkness is a fruitful subject.)

steve....@gmail.com

unread,
Jun 28, 2005, 5:52:00 PM6/28/05
to
Andrew Plotkin wrote:

> More than one *kind* of customization becomes problematic.

Ok, I got it. So yes, we're talking about conflict resolution outside
of class hierarchy. In OO, we handle this with an additional
conditional for each possible conflict -- and these conditionals must
be strategically placed so that the program flow will encounter these
conditionals in the right order. This is prone to error, and of course
tends towards tangled code. So as you suggest, something of a logical
analysis language would likely produce code that's cleaner, clearer,
and more compact. So I think I'm getting your point (in broad strokes),
but I'm not yet fully "with it," so I'll make a few more remarks and
questions, and hopefully you'll figure out what I'm missing.

(By the way, I'm sure you're aware of Phil Goetz's writing on using
logic-programming for IF. (This was around 8 years ago.) He wrote a
well-elaborated piece on using STREPS. Nothing that I know of has come
from this. I remain particularly interested in the application of
logic-programming to NPC-AI, and I expect your considerations dovetail
with this interest.)

(Also, you seem to be concerned with conflicts within a limited sphere
of the larger IF problem domain: namely, the interaction of game-world
stuffs, be they objects or actors, their states, the game state, or
whatnot -- all game-world stuff. In this case, would it make sense to
write a sub-language interpreter within the larger language, be it
Inform or Tads-3, to handle the subset of problems? I know this hugely
amplifies the computation complexity; and I don't know if this is even
feasible in Inform. On the other hand, I would not be suprised if a
Prolog-like extension was done for Tads-3 within months. So, in short,
do you think a logic-programming sub-language sounds reasonable/useful
or no?)

[...]


> Either you can't control which customizations override which, or you
> can but it requires fiddling around.
>
> Conclusion: a next-stage IF system requires the ability to treat all
> conditional customizations as first-class objects, with direct control
> over how conflicts resolve. "Object orientation" just isn't a useful
> model, because the problem involves sets of predicates, not single
> objects.

I agree, except I suspect that OO remains a useful model in any case.

First, once you understand the OO model and understand program flow
(and these things are relatively easy to understand), it quickly
becomes quite intuitive, plus, it's well usable. (It meets most needs,
right?) Also, and importantly, when something goes wrong, it's normally
pretty easy to figure out where and why, because the program flow is
really explicit. In any case, something better still pending, it's
pretty sensical that this would be the model of choice of IF-writers.

I don't have sufficient experience with logic programming to make fair
and well-informed comparisons, but my untutored sense is that a
language that works through rule resolution has some problems with
usability: errors in rule resolution can be relatively difficult to
locate, and since there's no explicit flow in which the code-blocks are
couched, this "apparent" independence of the rules can make for a
pretty confusing read. Am I wrong that a sophisticated rulebase tends
to produce a sensation of slogging through rule declarations, sort-of
in the dark, easily losing track of the root for the forest?

Second, I think OO is an appropriate programmatic representation (or, a
mirror-image) for the conventional IF-world-model, which is a world
made of objects.

I'm not sure if you were following up your critique of the "multiple
dispatch" notion, when you write:

> [...] Problem is, IF isn't about objects.

This is a tantalizing statement, maybe a radical one. I mean, on the
face of it, IF does indeed seem to be about objects. -- Not
programmatic objects, but "game-world" objects. And if there's a
programmatic object for each game-world object, that makes intuitive
sense, right?

Now, yes, I understand your argument that IF is about the objects'
behavior with respect to other objects, states, actions, and what have
you. And I agree that a logical analysis would be useful for resolving
sophisticated conflicts.

So, hmm, we can organize the code by object, or organize the code by
conditional or rule, but it's not clear that -- as far as readability,
writability, debug-ability and intuitiveness -- it's not clear that one
organization is better than the other. I hazard a guess that OO is
preferable on these counts, but I admit that I'm biased.

One speculation: I wonder how far IF writers avoid those situations
that cannot be well implemented in their programming language. An
alternate programming language, with different strengths and weaknesses
(or simply, different organization), might lead to a different species
of IF writing, that is, a development of the genre.

So, ya, I have a couple questions: how sure are you that
logic-programming would better address the large problem domain of IF,
as compared to OO? Do you think logic-programming code would be easier
to work with, in terms of readability, code/writability, and debugging?

Towards the question of sufficiency of OO, let me respond to your
problem with phases:

> Then there's the idea of phases -- [...]


> My problem with all of this is that no fixed list of phases is
> actually adequate. When I start trying to break down specific design
> problems from my own work, I realize that I'm *always* adding in
> subphases and sub-subphases.

Sure, but this is how it's supposed to work, right? For example, Tads-3
was designed to provide a generally adequate series of phases or
stages, each one either reflective of the state of action or object
resolution, or at least a robust conceptual stage. But that's just the
standard library-level: games are expected to break these down further
as needed. (However, I can tell you from some experience that it's
difficult to come up with a scenario that isn't handled by the library.
-- The normal problem is discovering or figuring out which stage
(code-block) you need to modify or override. The library is not
designed to be complete, but it's almost disturbingly robust.)

I think I underemphasized my main point here, regarding phases: they
allow you to take advantage of the flow of the program, to order your
conditionals strategically, so at runtime they are encountered in the
right order (and so your conflict resolution works right). However, I
agree that (in principle) you can't always rely on flow: sometimes you
need that kind of back-and-forth reference for which logic-programming
seems ideal.

Finally, I fear I'm not yet fully appreciating your points. I'm really
interested, though, and I hope we're not talking too much past each
other, so to speak. I'm at my best when understanding through examples,
and I expect I'll really get your point once I study the necessary
examples. You have collected a number of examples, so do share them
with me if you please, however you like.

steve....@gmail.com

unread,
Jun 28, 2005, 8:52:02 PM6/28/05
to
Oops. I mentioned that Phil Goetz wrote about using "STREPS" -- but,
alas, there's no such creature: I meant SNePS. I expect I confused the
acronims SNePS, and STRIPS (the canonical planner language, of which
Goetz also writes).

The main piece I was referring to is available here:

http://groups-beta.google.com/group/rec.arts.int-fiction/browse_frm/thread/90d6c977eea21143/e10b4dc41e493460?q=goetz+logic&rnum=2#e10b4dc41e493460

David Tanguay

unread,
Jun 28, 2005, 9:57:45 PM6/28/05
to
steve....@gmail.com wrote:

> Andrew Plotkin wrote:
>>[...] Problem is, IF isn't about objects.
>
>
> This is a tantalizing statement, maybe a radical one. I mean, on the
> face of it, IF does indeed seem to be about objects. -- Not
> programmatic objects, but "game-world" objects.

On the face of it, IF does indeed seem to be about verbs (especially of the
"guess-the" kind). Maybe a functional programming model (with pattern
matching) would work well. :-)

Procedural/OO, relational/logic, and functional: I think all three can work,
since they all do work with general progamming. At different points, you want
to see the game world from each of those views. Whichever you choose as your
primary focus will run into complexity when you need to see things from
another (of the three) prespective.
--
David Tanguay Kitchener, Ontario

David Fisher

unread,
Jun 28, 2005, 10:42:54 PM6/28/05
to
"Andrew Plotkin" <erky...@eblong.com> wrote in message
news:d9rujp$o5q$1...@reader1.panix.com...

>
> I've been using "rule <R>: handle <atom> as <code> if <condition>" in
> my notes. An atom is more or less a function name. Rules are named so
> that you can refer to them with some construct like "R1 > R2", to
> define a precedence.

[snip stuff]

> If we have all three rules and an object which *is* both B and C,
> that's a conflict. The compiler must throw an error. To resolve it,
> either the user has to add a declaration "R2 < R3" or "R2 > R3", or
> add a fourth rule:
>
> R4: handle X as [...code4...] if (O ofclass B) and (O ofclass C)
>
> Note that the compiler has to be smart enough to do Venn diagrams.

Thanks for the explanation ... it's a lot clearer now. (Do you use "union",
"intersection" and "difference" operators, or are you not thinking along
those lines ?)

> I have lots of these simple examples. What I don't have is a
> general model that correctly handles all of them. There are lots
> of complications -- particularly with the problem of gaining access
> to overridden or renamed bits of code. Which you *do* often
> want to do.

> Trust me, my legion of examples is vast

I do !

You made a comment in a previous post:

> "Object orientation" just isn't a useful model, because the problem
> involves sets of predicates, not single objects.

So are you thinking in terms of a "rule based" system, replacing and/or
supplementing an OO system ?

A thought - have you considered the possibility of writing *all* the game
code as rules (rather than having two separate kinds of object: "rules" like
your R4 example above, and "code" - routines that do stuff) ? For example,
instead of the code:

before [;
Gruble: if (something > 3) "You can't gruble.";
"You gruble.";
]

You could have the rules:

action_Gruble && something > 3 : "You can't gruble."
action_Gruble && something <= 3 : "You gruble."

(Translating code that contains loops, etc. into a set of rules could be
tricky, though).

Before you dismiss this idea completely ;-) ... one advantage of everything
being represented in a manipulable rule is that NPC reasoning becomes
simpler to implement. Phil Goetz posted an article on "Why you must use
Prolog" for IF (Oct 1996) - the main idea being that an NPC reasoning engine
must have access to the "world rules" (or at least some of them).

The original article is at:
http://groups-beta.google.com/group/rec.arts.int-fiction/browse_frm/thread/b0778dc26ab4e663

(BTW, I know the above example rules are silly - realistically you would
want to allow for broader context, "else" clauses, etc).

David Fisher


Joe Strout

unread,
Jun 28, 2005, 11:23:46 PM6/28/05
to
In article <1120006322....@o13g2000cwo.googlegroups.com>,
steve....@gmail.com wrote:

That's really interesting stuff. But I see that it was written years
ago -- is Phil still around, and did anything ever come of his attempt
to write a logic-based IF system?

Thanks,
- Joe

,------------------------------------------------------------------.
| Joseph J. Strout Check out the Mac Web Directory: |
| j...@strout.net http://www.macwebdir.com |
`------------------------------------------------------------------'

steve....@gmail.com

unread,
Jul 2, 2005, 10:26:38 PM7/2/05
to
Joe Strout wrote, of Phil Gotez's logic-programming ideas:

> really interesting stuff. But I see that it was written years
> ago -- is Phil still around, and did anything ever come of his attempt
> to write a logic-based IF system?

No, Phil hasn't been around for five years. Nothing has come of
logic-programming for IF, so far. It's really interesting, what he
wrote of NPC-AI.

I hope Andrew is still reading this thread. I asked some questions
about this, my last post.

Chris Pickett

unread,
Jul 3, 2005, 3:07:47 AM7/3/05
to
steve....@gmail.com wrote:
> Joe Strout wrote, of Phil Gotez's logic-programming ideas:
>
> > really interesting stuff. But I see that it was written years
> > ago -- is Phil still around, and did anything ever come of his attempt
> > to write a logic-based IF system?
>
> No, Phil hasn't been around for five years. Nothing has come of
> logic-programming for IF, so far. It's really interesting, what he
> wrote of NPC-AI.

Actually, Dennis Merritt's AIFT is a decent start. The source is
available, I asked him about it and he said do what you want (i.e.
public domain).

<spam> We also did some (sort of) related stuff using Petri Nets for IF
that allow you do things like look at reachability and do formal
verification, but it isn't really a knowledge-based system... I started
a topic on it the other day. The related work section of the paper
linked therein does mention some other logic-based attempts (we didn't
know about Phil's work), the most extensive of which is probably Kakas'
language $\mathcal{E}$.</spam>

Chris

Ross Presser

unread,
Jul 5, 2005, 11:59:53 AM7/5/05
to
On Thu, 16 Jun 2005 04:28:22 GMT, Mike Rozak wrote:

> To produce a tool that hasn't been produced 100 times before, you need good
> graphics and sound, and probably multiuser support.

It seems to me as a player that every time a game makes the leap to good
graphics and/or sound and/or multiuser support, it loses my interest. Or at
least fails to hold it as long.

Chris Pickett

unread,
Jul 5, 2005, 6:45:33 PM7/5/05
to
Andrew Plotkin wrote:

> The question is: the code invokes atom X, under a set of conditions
> (object is O, action is A, the troll is angry, it's Thursday...) What
> do we do?
>
> I think you're describing the case where we have these rules: (Where B
> and C are subclasses of A.)
>
> R1: handle X as [...code1...] if (O ofclass A)
> R2: handle X as [...code2...] if (O ofclass B)
> R3: handle X as [...code3...] if (O ofclass C)
>
> If there were no R3, this would be easy: it would translate as
>
> if (O ofclass B) [...code2...]
> else if (O ofclass A) [...code1...]
> else [...run the default code for X...]
>
> Given all three rules, if there's no object which is both B and C,
> it's still easy.

I think that's exactly what Java gives you though, and its certainly
expressive enough: you only get multiple inheritance through the use of
interfaces, and methods declared in interfaces don't have method
bodies. I think C++ on the other hand is messier, and does allow for
real conflicts (don't know too much about C++, but that's what I
remember).

There's lots of literature out there on typing systems and polymorphic
method call resolution if you want answers from experts, but from what
I've seen, IF doesn't need anything nearly as complex as what
mainstream languages provide; I'd even argue that there's no real need
for dynamic class instantiation.

Cheers,
Chris

Andrew Plotkin

unread,
Jul 5, 2005, 7:39:08 PM7/5/05
to
Here, Chris Pickett <cpi...@gmail.com> wrote:
> Andrew Plotkin wrote:
>
> > The question is: the code invokes atom X, under a set of conditions
> > (object is O, action is A, the troll is angry, it's Thursday...) What
> > do we do?
> >
> > I think you're describing the case where we have these rules: (Where B
> > and C are subclasses of A.)
> >
> > R1: handle X as [...code1...] if (O ofclass A)
> > R2: handle X as [...code2...] if (O ofclass B)
> > R3: handle X as [...code3...] if (O ofclass C)
> >
> > If there were no R3, this would be easy: it would translate as
> >
> > if (O ofclass B) [...code2...]
> > else if (O ofclass A) [...code1...]
> > else [...run the default code for X...]
> >
> > Given all three rules, if there's no object which is both B and C,
> > it's still easy.
>
> I think that's exactly what Java gives you though, and its certainly
> expressive enough: you only get multiple inheritance through the use of
> interfaces, and methods declared in interfaces don't have method
> bodies.

My original point was that *these are not all class relationships*, or
even *type* relationships. That particular example happened to be
about classes.

An analogous example, involving containment relationships: Consider
a table A, supporting box B and handbag C. "Within" means "directly or
indirectly contained within".

R1: handle X as [...code1...] if (O within A)
R2: handle X as [...code2...] if (O within B)
R3: handle X as [...code3...] if (O within C)

Another example, with the same logical structure:

R1: handle X as [...code1...] if (action == EAT)
R2: handle X as [...code2...] if ((action == EAT) and (noun == PORKCHOP))
R3: handle X as [...code3...] if ((action == EAT) and (hungerlevel == STARVED))

It is not important whether we're talking about class membership, or
objects with properties, or contained objects. The important point
is that conditions 2 and 3 are subsets of condition 1, but are
orthogonal to each other. The rule engine must be able to break down
all the given conditions into these sorts of relationships, and then
resolve them according to a uniform algorithm.

Andrew Plotkin

unread,
Jul 5, 2005, 7:48:48 PM7/5/05
to
Here, Andrew Plotkin <erky...@eblong.com> wrote:
>
> An analogous example, involving containment relationships: Consider
> a table A, supporting box B and handbag C. "Within" means "directly or
> indirectly contained within".
>
> R1: handle X as [...code1...] if (O within A)
> R2: handle X as [...code2...] if (O within B)
> R3: handle X as [...code3...] if (O within C)

Footnote: not quite the same logical structure as the other examples,
since conditions 2 and 3 are mutually exclusive. However, if the box
is allowed to move into the handbag, or vice versa, you're back to the
same structure. (An object can then be within both.)


> Another example, with the same logical structure:
>
> R1: handle X as [...code1...] if (action == EAT)
> R2: handle X as [...code2...] if ((action == EAT) and (noun == PORKCHOP))
> R3: handle X as [...code3...] if ((action == EAT) and (hungerlevel == STARVED))

--Z

Chris Pickett

unread,
Jul 5, 2005, 9:29:07 PM7/5/05
to
Andrew Plotkin wrote:
> My original point was that *these are not all class relationships*, or
> even *type* relationships. That particular example happened to be
> about classes.

Yes, okay. As for classes, I still think that anything more than Java
interface-like inheritance is asking for trouble.

> An analogous example, involving containment relationships: Consider
> a table A, supporting box B and handbag C. "Within" means "directly or
> indirectly contained within".
>
> R1: handle X as [...code1...] if (O within A)
> R2: handle X as [...code2...] if (O within B)
> R3: handle X as [...code3...] if (O within C)

As for containment, and re: your footnote below, are there situations
where O is within C, and C is within B, such that you really need to
know about the fact that O is technically within B too? Or can it
always suffice to resolve things through O's immediate parent?

> Another example, with the same logical structure:
>
> R1: handle X as [...code1...] if (action == EAT)
> R2: handle X as [...code2...] if ((action == EAT) and (noun == PORKCHOP))
> R3: handle X as [...code3...] if ((action == EAT) and (hungerlevel == STARVED))

So, here I don't think linear complexity is guaranteed.

!porkchop && !starved --> "You can't eat that."
porkchop && !starved --> "Yum."
!porkchop && starved --> "You're so hungry you don't care. Ugh."
porkchop && starved --> "You wolf it down. Yum."

I think it's really O(2^n).

> It is not important whether we're talking about class membership, or
> objects with properties, or contained objects. The important point
> is that conditions 2 and 3 are subsets of condition 1, but are
> orthogonal to each other. The rule engine must be able to break down
> all the given conditions into these sorts of relationships, and then
> resolve them according to a uniform algorithm.

How about an algorithm that looks for 2^n resolution blocks unless a
linear solution will always suffice, as is known for certain
situations, e.g. controlled inheritance or containment?

Chris

Andrew Plotkin

unread,
Jul 6, 2005, 1:35:25 PM7/6/05
to
Here, Chris Pickett <cpi...@gmail.com> wrote:
> Andrew Plotkin wrote:
> > My original point was that *these are not all class relationships*, or
> > even *type* relationships. That particular example happened to be
> > about classes.
>
> Yes, okay. As for classes, I still think that anything more than Java
> interface-like inheritance is asking for trouble.

I agree.



> > An analogous example, involving containment relationships: Consider
> > a table A, supporting box B and handbag C. "Within" means "directly or
> > indirectly contained within".
> >
> > R1: handle X as [...code1...] if (O within A)
> > R2: handle X as [...code2...] if (O within B)
> > R3: handle X as [...code3...] if (O within C)
>
> As for containment, and re: your footnote below, are there situations
> where O is within C, and C is within B, such that you really need to
> know about the fact that O is technically within B too? Or can it
> always suffice to resolve things through O's immediate parent?

No, the immediate parent doesn't always suffice. You can imagine IF
situations where the game is keeping track of (and perhaps forbidding)
"X moves into Y", "X moves out of Y" events, but doesn't want to care
about "X changes containers within Y". The relevant test is then
Y-indirectly-contains, not Y-directly-contains.



> > Another example, with the same logical structure:
> >
> > R1: handle X as [...code1...] if (action == EAT)
> > R2: handle X as [...code2...] if ((action == EAT) and (noun == PORKCHOP))
> > R3: handle X as [...code3...] if ((action == EAT) and (hungerlevel == STARVED))
>
> So, here I don't think linear complexity is guaranteed.

You're right, but I was making a weaker claim. It's not that the
author can always get away with linear complexity (a linear number of
precedence declarations) to make his game work correctly; it's that
the author can always get away with that to resolve all the conflicts
among the rules he's written. It's the "dammit, my game doesn't
compile" phase.

Once he's running and testing, he may realize that his game requires
more work to do what he wants. Of course this may require more
*rules*. That isn't O(2^N) work, that's increasing N.

(It may require more -- or more specific -- precedence declarations
too, but in that area I'm not sure what's needed. Does it makes sense
to say "rule R1 has precedence over R2 if (hungerlevel == STARVED)"?
Or does that shove the whole problem into intractability?)

Chris Pickett

unread,
Jul 7, 2005, 12:01:32 AM7/7/05
to
Andrew Plotkin wrote:
> Here, Chris Pickett <cpi...@gmail.com> wrote:
> > As for containment, and re: your footnote below, are there situations
> > where O is within C, and C is within B, such that you really need to
> > know about the fact that O is technically within B too? Or can it
> > always suffice to resolve things through O's immediate parent?
>
> No, the immediate parent doesn't always suffice. You can imagine IF
> situations where the game is keeping track of (and perhaps forbidding)
> "X moves into Y", "X moves out of Y" events, but doesn't want to care
> about "X changes containers within Y". The relevant test is then
> Y-indirectly-contains, not Y-directly-contains.

I wasn't being too clear. I had two questions in that paragraph above.
The second one was supposed to be:

Given an object O, and a set of containers C = {rooms, the player,
container objects}, how many bits do you need to encode the location of
O?

If you have a strict containment hierarchy, the locations are mutex,
since the object can only be in one element of C at a time. Therefore
I think it's ceil(log|C|) -- as opposed to |C|. Much like a class
hierarchy that only allows for single inheritance.

You can just follow the hierarchy to find information about (in)direct
containment. Asking about whether O is contained by some element of C
costs O(log|C|), if you start from O and go up to the root.

The first one was:

Is it common to ask if O is in both X and Y? Note that this can be
asked regardless of whether you have the strict containment
hierarchy... but that if you do, either X is in Y or Y is in X.

If it is common (I suspect that it is not), then it may be expensive in
terms of the number of rules you have to write.

> > > Another example, with the same logical structure:
> > >
> > > R1: handle X as [...code1...] if (action == EAT)
> > > R2: handle X as [...code2...] if ((action == EAT) and (noun == PORKCHOP))
> > > R3: handle X as [...code3...] if ((action == EAT) and (hungerlevel == STARVED))
> >
> > So, here I don't think linear complexity is guaranteed.
>
> You're right, but I was making a weaker claim. It's not that the
> author can always get away with linear complexity (a linear number of
> precedence declarations) to make his game work correctly; it's that
> the author can always get away with that to resolve all the conflicts
> among the rules he's written. It's the "dammit, my game doesn't
> compile" phase.

I think what you're saying is that for compilation, as an upper bound,
you need rules covering (perhaps with inequalities) each non-zero value
of every state variable, for each action. Even that sounds like a
lot... but it's mitigated by the fact that only a few state variables
are relevant to each action. Declaring that might be necessary.

> Once he's running and testing, he may realize that his game requires
> more work to do what he wants. Of course this may require more
> *rules*. That isn't O(2^N) work, that's increasing N.

Okay, N was the number of booleans in the system (2: porkchop and
starved -- I'm ignoring that 'noun' and 'hungerlevel' can probably take
other values). So, N+1 = 3 is how many rules you need for it to
compile (default, porkchop, starved) -- and that's the maximum.

I still think that O(2^N) is an upper bound on the number of rules
you'll need if you can't guarantee one rule for each boolean for each
action is going to work at runtime (scalars are just an extension).

In practice, yes, it isn't going to approach 2^N ... so it's likely
that a tighter upper bound is possible if you specialize things more
(e.g. take into account containment, inheritance, limiting the number
of 'relevant' variables for each action, etc.). Such tighter upper
bounds are useful, and we can exploit them not only to make promises to
the programmer, but also to reduce the complexity of searching the
state space.

> (It may require more -- or more specific -- precedence declarations
> too, but in that area I'm not sure what's needed. Does it makes sense
> to say "rule R1 has precedence over R2 if (hungerlevel == STARVED)"?
> Or does that shove the whole problem into intractability?)

Provide a default precedence order (numerical order of the rules);
making exceptions to this doesn't appear to be more complex than
introducing new rules past the minimum required...

Chris

Andrew Plotkin

unread,
Jul 7, 2005, 12:44:54 AM7/7/05
to
Here, Chris Pickett <cpi...@gmail.com> wrote:
> Andrew Plotkin wrote:
> > Here, Chris Pickett <cpi...@gmail.com> wrote:
> > > As for containment, and re: your footnote below, are there situations
> > > where O is within C, and C is within B, such that you really need to
> > > know about the fact that O is technically within B too? Or can it
> > > always suffice to resolve things through O's immediate parent?
> >
> > No, the immediate parent doesn't always suffice. You can imagine IF
> > situations where the game is keeping track of (and perhaps forbidding)
> > "X moves into Y", "X moves out of Y" events, but doesn't want to care
> > about "X changes containers within Y". The relevant test is then
> > Y-indirectly-contains, not Y-directly-contains.
>
> I wasn't being too clear. I had two questions in that paragraph above.
> The second one was supposed to be:
>
> Given an object O, and a set of containers C = {rooms, the player,
> container objects}, how many bits do you need to encode the location of
> O?
>
> If you have a strict containment hierarchy, the locations are mutex,
> since the object can only be in one element of C at a time.

Oh, sure. But this encoding may have nothing to do with how the author
is designing the game! The *rules* may be about direct containment,
indirect containment, or more complicated properties. (Like scope, but
let's not start with that.)

The problem of *applying* a set of rules, given an actual game-state,
is much easier than putting together the set in the first place. TADS
and Inform as they stand can already determine the truth of conditions
like "if (A indirectly contains B)".

The problem of putting together the set of rules consists of questions
like "Could X be in Y at the same time that X is in Z?" You're not
looking at game-states, but sets of possible game-states. Enumerating
all possible game-states is silly, so we need to build a
representation of the logic, with the rules of the model world as
build-in axioms. ("It is not possible that X is in Y at the same time
as Y is in X.")

> The first one was:
>
> Is it common to ask if O is in both X and Y? Note that this can be
> asked regardless of whether you have the strict containment
> hierarchy... but that if you do, either X is in Y or Y is in X.

You mean, do I expect rules of the form

R12: handle F as [...code...] if (O in X and O in Y)

Answer: yes, sometimes. I will explain why in a moment.

Does my hypothetical compiler need to ask whether O *might be* in both
X and Y? Yes, all the time. I expect many situations where an author
writes, in different parts of the game:

R1: handle F as [...code1...] if (O in X)
R2: handle F as [...code2...] if (O in Y)

Now, if O can never be in both X and Y, the compiler should accept
this silently. It's not a conflict. If O *could* be in both, the
compiler should complain. The author must either supply a
precedence, *or* supply a rule of the form R12 above. (And that's
where R12 comes from.)

> > ... I was making a weaker claim. It's not that the


> > author can always get away with linear complexity (a linear number of
> > precedence declarations) to make his game work correctly; it's that
> > the author can always get away with that to resolve all the conflicts
> > among the rules he's written. It's the "dammit, my game doesn't
> > compile" phase.
>
> I think what you're saying is that for compilation, as an upper bound,
> you need rules covering (perhaps with inequalities) each non-zero value
> of every state variable, for each action.

I'm not sure what you mean by "non-zero". The set of rules has to
cover every possible combination of state variable values (action is
just another state variable, on a given turn). Moreover, it has to
give a unique outcome for every possible combination.

There are a bunch of ways to simplify the problem, but they are just
formalizations of mechanisms which Inform has long supported (in
ad-hoc, icky ways. :) I'm not going to get into those now. The
underlying problem should still be solvable, however.

> [...]


> Provide a default precedence order (numerical order of the rules);
> making exceptions to this doesn't appear to be more complex than
> introducing new rules past the minimum required...

Oh, dear, not a *numerical* order. That introduces more headaches than
my magical theory could ever solve. (Trust me, I learned Applesoft
BASIC when I was ten. :)

What does it mean to specify an order without using numbers? That's
another whole can of worms. Which curiously resembles my first can of
worms -- taking a bunch of logical relationships ("R1 < R2", "R2 < R3")
and detect conflicts -- but I haven't managed to unify the two
models...

Esa A E Peuha

unread,
Jul 7, 2005, 6:56:44 AM7/7/05
to
Andrew Plotkin <erky...@eblong.com> writes:

> What does it mean to specify an order without using numbers? That's
> another whole can of worms. Which curiously resembles my first can of
> worms -- taking a bunch of logical relationships ("R1 < R2", "R2 < R3")
> and detect conflicts -- but I haven't managed to unify the two
> models...

Let's see... You have a partial ordering of rules (that is, at most one
of R1 < R2 and R2 < R1 is true, and if R1 < R2 and R2 < R3 then R1 < R3),
and you want to find a good way to specify this ordering. Well, a
partial ordering can always be completed to linear ordering (if neither
R1 < R2 nor R2 < R1 is defined, just pick one), you could just list all
the rules in order of precedence.

--
Esa Peuha
student of mathematics at the University of Helsinki
http://www.helsinki.fi/~peuha/

Chris Pickett

unread,
Jul 7, 2005, 12:20:34 PM7/7/05
to
Esa A E Peuha wrote:
> Andrew Plotkin <erky...@eblong.com> writes:
>
>
>>What does it mean to specify an order without using numbers? That's
>>another whole can of worms. Which curiously resembles my first can of
>>worms -- taking a bunch of logical relationships ("R1 < R2", "R2 < R3")
>>and detect conflicts -- but I haven't managed to unify the two
>>models...
>
>
> Let's see... You have a partial ordering of rules (that is, at most one
> of R1 < R2 and R2 < R1 is true, and if R1 < R2 and R2 < R3 then R1 < R3),
> and you want to find a good way to specify this ordering. Well, a
> partial ordering can always be completed to linear ordering (if neither
> R1 < R2 nor R2 < R1 is defined, just pick one), you could just list all
> the rules in order of precedence.

Yes, that's what I meant by "numerical ordering" -- could also be "the
order the rules appear in the file". Unless (a) you can provide a
default ordering for known situations, or (b) the author provides a
total ordering, you're going to have to make arbitrary choices. There
may be a third option: at compile-time, given some analysis, you might
be able to assign an ordering in the absence of a known default and in
the absence of author-provided precedences, that is better than blindly
picking it (e.g. numerical), but I don't know what that analysis would
entail.

Chris

Chris Pickett

unread,
Jul 7, 2005, 1:43:15 PM7/7/05
to
Andrew Plotkin wrote:
> Here, Chris Pickett <cpi...@gmail.com> wrote:
>>Given an object O, and a set of containers C = {rooms, the player,
>>container objects}, how many bits do you need to encode the location of
>>O?
>>
>>If you have a strict containment hierarchy, the locations are mutex,
>>since the object can only be in one element of C at a time.
>
>
> Oh, sure. But this encoding may have nothing to do with how the author
> is designing the game! The *rules* may be about direct containment,
> indirect containment, or more complicated properties. (Like scope, but
> let's not start with that.)
>
> The problem of *applying* a set of rules, given an actual game-state,
> is much easier than putting together the set in the first place. TADS
> and Inform as they stand can already determine the truth of conditions
> like "if (A indirectly contains B)".
>
> The problem of putting together the set of rules consists of questions
> like "Could X be in Y at the same time that X is in Z?" You're not
> looking at game-states, but sets of possible game-states. Enumerating
> all possible game-states is silly, so we need to build a
> representation of the logic, with the rules of the model world as
> build-in axioms. ("It is not possible that X is in Y at the same time
> as Y is in X.")

Yes, axioms like that are useful.

The point about enforcing a strict containment hierarchy is that it lets
you give a default precedence ordering, based on the runtime position of
the object. This also appears to be useful because it reduces the
burden on the programmer. The ordering would either follow the tree up
from the object to the root, or would descend from the root to every
object in either a DFS or BFS.

> You mean, do I expect rules of the form
>
> R12: handle F as [...code...] if (O in X and O in Y)
>
> Answer: yes, sometimes. I will explain why in a moment.
>
> Does my hypothetical compiler need to ask whether O *might be* in both
> X and Y? Yes, all the time. I expect many situations where an author
> writes, in different parts of the game:
>
> R1: handle F as [...code1...] if (O in X)
> R2: handle F as [...code2...] if (O in Y)
>
> Now, if O can never be in both X and Y, the compiler should accept
> this silently. It's not a conflict. If O *could* be in both, the
> compiler should complain. The author must either supply a
> precedence, *or* supply a rule of the form R12 above. (And that's
> where R12 comes from.)

If O can never be in X and Y, then this needs to be specified somewhere,
as opposed to detected by the compiler (you'd have to search the state
space to find it out). At runtime, this can form an assertion or
invariant specification, and a model checker can attempt to verify it.

If O is in both, this is where you might expect to get away with the
default precedence ordering that you get from strict containment:

if X in Y then R1 < R2 else R2 < R1

If that ordering is no good for the situation, then rather than changing
the ordering for the situation, use R12. Whether or not you still want
to use R1 and R2, I don't know.

>>>... I was making a weaker claim. It's not that the
>>>author can always get away with linear complexity (a linear number of
>>>precedence declarations) to make his game work correctly; it's that
>>>the author can always get away with that to resolve all the conflicts
>>>among the rules he's written. It's the "dammit, my game doesn't
>>>compile" phase.
>>
>>I think what you're saying is that for compilation, as an upper bound,
>>you need rules covering (perhaps with inequalities) each non-zero value
>>of every state variable, for each action.
>
>
> I'm not sure what you mean by "non-zero". The set of rules has to
> cover every possible combination of state variable values (action is
> just another state variable, on a given turn). Moreover, it has to
> give a unique outcome for every possible combination.

Here, we were talking about making it compile. If you specify a
precedence ordering, either default or programmer supplied or detected
by the compiler, then you don't need a rule for each combination.

If the precedence ordering doesn't work at runtime, then specifying a
rule for each combination may be necessary in a limited number of cases,
and it's clearly exponential. However, you can probably eliminate many
irrelevant variables from individual cases.

The non-zero part was from your 'porkchop and starved' example -- if
both bits are unset, defer to the default for the action 'eat'. Maybe
each variable should be able to take an ignorable value.

> There are a bunch of ways to simplify the problem, but they are just
> formalizations of mechanisms which Inform has long supported (in
> ad-hoc, icky ways. :) I'm not going to get into those now. The
> underlying problem should still be solvable, however.

I think you've pretty much got an algorithm for the unsimplified case.

However, I don't think the underlying problem is solvable (i.e.
tractable) unless you do formalise all the simplifications (see my
earlier comment about providing a tighter upper bound).

Simplifications that come to mind:

1) Strict containment. An object can only have one immediate parent
container at a time.

2) Scalars. A variable can only take one of its values at a time.

3) Single inheritance. Classes can only have one superclass.

4) Limiting the relevant variables for actions. It is unlikely for all
state variables to affect a single action (verb). Even once you have a
set of variables for a single action, you can probably rule out invalid
combinations from situation-specific knowledge, either default or
supplied by the programmer.

5) Not all actions are available to all characters... an NPC doesn't
have to be able to take every action the player can, for example.

6) One action is performed at a time (no concurrent actions). This can
even extend to multiple players (make it turn-based)... although that
might be undesirable.

7) Puzzle independence. It might be possible to decompose things into
disjoint puzzles, such that the state of one puzzle will never affect
another.

8) Axioms of the world models. So far we just have the one you listed
for containment: X in Y -> Y !in X.

So, what else is there?

Chris

Andrew Plotkin

unread,
Jul 8, 2005, 1:06:24 PM7/8/05
to
Here, Chris Pickett <ch...@fakeemail.com> wrote:
> Esa A E Peuha wrote:
> > Andrew Plotkin <erky...@eblong.com> writes:
> >
> >
> >>What does it mean to specify an order without using numbers? That's
> >>another whole can of worms. Which curiously resembles my first can of
> >>worms -- taking a bunch of logical relationships ("R1 < R2", "R2 < R3")
> >>and detect conflicts -- but I haven't managed to unify the two
> >>models...
> >
> > Let's see... You have a partial ordering of rules (that is, at most one
> > of R1 < R2 and R2 < R1 is true, and if R1 < R2 and R2 < R3 then R1 < R3),
> > and you want to find a good way to specify this ordering. Well, a
> > partial ordering can always be completed to linear ordering (if neither
> > R1 < R2 nor R2 < R1 is defined, just pick one), you could just list all
> > the rules in order of precedence.
>
> Yes, that's what I meant by "numerical ordering" -- could also be "the
> order the rules appear in the file".

I am not very comfortable with that ordering, since it means that the
behavior of your game can silently change when you rearrange your
source code.

> Unless (a) you can provide a default ordering for known situations,
> or (b) the author provides a total ordering, you're going to have to
> make arbitrary choices.

As I said, in some cases, you *want* the author to provide additional
input. (Notionally, the cases where the author has given two
conflicting rules by accident.) In those cases, the compiler
*shouldn't* make a choice.

The fun part is coming up with a model where you can reasonably say
"Here, the author is giving an explicit precedence; there, we can
infer a precedence that the author will agree with; but over there,
we can't infer anything." Too much and too little both reduce the
usability of the system.

Andrew Plotkin

unread,
Jul 9, 2005, 10:39:30 PM7/9/05
to
Here, Chris Pickett <ch...@fakeemail.com> wrote:
> Andrew Plotkin wrote:
>
> The point about enforcing a strict containment hierarchy is that it lets
> you give a default precedence ordering, based on the runtime position of
> the object. [...]

>
> If O is in both, this is where you might expect to get away with the
> default precedence ordering that you get from strict containment:
>
> if X in Y then R1 < R2 else R2 < R1

Hm, no, I don't buy it. That is *a* resolution, but I'm not convinced
that it's right more often than it's wrong. (Over the space of
possible game situations which wind up being modelled that way.)

If there's a special rule which applies inside the aircraft hangar,
and another (conflicting) special rule which applies inside a taxi,
and you drive the taxi into the aircraft hangar... the compiler
shouldn't assume that the taxi rule takes precedence. (Or loses
precedence, either.) It's a genuine conflict, and the compiler
*shouldn't* try to guess.

(Unlike a conflict between "if (A)" and "if (A and B)", where the
second rule is clearly an exception to the first.)

My notion is that the system should work out all the precedences
staticly (at compile-time, not based on run-time state). Unless the
author specifically requests otherwise. I haven't seen anything that
convinces me that this notion is wrong.

(My other notion is that the problem gets nicer if the author can
specify precedence on *groups* of rules, as well as specific rules.
Nicer from the author's point of view, at least.)

In any case, containment and class hierarchy are *both* special cases.
The general problem has to cope with whatever logical expressions the
game designer puts in the "if" clause of a rule. If containment and
classes are easier to deal with, due to the axioms of the world/class
model, that's great -- but the compiler has to be able to cope without
those levers. Fundamentally, it's a bunch of logical expressions of
state variables.



> > There are a bunch of ways to simplify the problem, but they are just
> > formalizations of mechanisms which Inform has long supported (in
> > ad-hoc, icky ways. :) I'm not going to get into those now. The
> > underlying problem should still be solvable, however.
>
> I think you've pretty much got an algorithm for the unsimplified case.

No, I've got a principle (a strict subset of the state space means a
higher precedence). I don't know enough about algorithms which analyze
logical expressions. Turning it into an algorithm may suck. Possibly
NP-suck.

Chris Pickett

unread,
Jul 10, 2005, 5:31:52 PM7/10/05
to
Andrew Plotkin wrote:
> Here, Chris Pickett <ch...@fakeemail.com> wrote:
>>Yes, that's what I meant by "numerical ordering" -- could also be "the
>>order the rules appear in the file".
>
>
> I am not very comfortable with that ordering, since it means that the
> behavior of your game can silently change when you rearrange your
> source code.

Sure... and so at least numerical is fixed (although obviously painful
to update). But then again, presumably you'd only choose these
arbitrary orderings when "it really doesn't matter". IOW, I think there
are times when you can make nondeterministic choices safely.

>>Unless (a) you can provide a default ordering for known situations,
>>or (b) the author provides a total ordering, you're going to have to
>>make arbitrary choices.
>
>
> As I said, in some cases, you *want* the author to provide additional
> input. (Notionally, the cases where the author has given two
> conflicting rules by accident.) In those cases, the compiler
> *shouldn't* make a choice.

Yes (although perhaps not all conflicts matter).

> The fun part is coming up with a model where you can reasonably say
> "Here, the author is giving an explicit precedence; there, we can
> infer a precedence that the author will agree with; but over there,
> we can't infer anything." Too much and too little both reduce the
> usability of the system.

Again agreed.

Chris

Chris Pickett

unread,
Jul 10, 2005, 6:06:14 PM7/10/05
to
Andrew Plotkin wrote:
> Here, Chris Pickett <ch...@fakeemail.com> wrote:
>> if X in Y then R1 < R2 else R2 < R1
>
>
> Hm, no, I don't buy it. That is *a* resolution, but I'm not convinced
> that it's right more often than it's wrong. (Over the space of
> possible game situations which wind up being modelled that way.)
>
> If there's a special rule which applies inside the aircraft hangar,
> and another (conflicting) special rule which applies inside a taxi,
> and you drive the taxi into the aircraft hangar... the compiler
> shouldn't assume that the taxi rule takes precedence. (Or loses
> precedence, either.) It's a genuine conflict, and the compiler
> *shouldn't* try to guess.

Ok, fair enough. I guess I need to formalise everything I want to say
about containment and then see if it's useful for a non-trivial game.
Handwaving is only so useful :(

It might also be the case that sometimes you want precedence R1 < R2 to
mean "R1 then R2", and other times you just want it to mean "R1".

> (Unlike a conflict between "if (A)" and "if (A and B)", where the
> second rule is clearly an exception to the first.)
>
> My notion is that the system should work out all the precedences
> staticly (at compile-time, not based on run-time state). Unless the
> author specifically requests otherwise. I haven't seen anything that
> convinces me that this notion is wrong.

I think you can relax this notion to: we need to know statically that
there is going to be some resolution at runtime that is safe. Indeed,
this is how type checking works for OO languages.

> (My other notion is that the problem gets nicer if the author can
> specify precedence on *groups* of rules, as well as specific rules.
> Nicer from the author's point of view, at least.)
>
> In any case, containment and class hierarchy are *both* special cases.
> The general problem has to cope with whatever logical expressions the
> game designer puts in the "if" clause of a rule. If containment and
> classes are easier to deal with, due to the axioms of the world/class
> model, that's great -- but the compiler has to be able to cope without
> those levers. Fundamentally, it's a bunch of logical expressions of
> state variables.

Yes, of course. However, I think that the general case is probably well
studied outside of IF, and that you'll find this was done years ago.
Which is a good thing, mind you.

>>>There are a bunch of ways to simplify the problem, but they are just
>>>formalizations of mechanisms which Inform has long supported (in
>>>ad-hoc, icky ways. :) I'm not going to get into those now. The
>>>underlying problem should still be solvable, however.
>>
>>I think you've pretty much got an algorithm for the unsimplified case.
>
>
> No, I've got a principle (a strict subset of the state space means a
> higher precedence). I don't know enough about algorithms which analyze
> logical expressions. Turning it into an algorithm may suck. Possibly
> NP-suck.

Ok, so I must admit, my particular interest here is in the formalisation
of the simplifications, special cases, and restrictions that you can
make for IF/narratives, as opposed to your main interest which appears
to be developing a mechanism for ensuring the programmer specifies
everything he needs to. It's because I'm doing symbolic execution of
narratives and every last optimisation and additional constraint counts
-- na\"ively allowing 2^100 possible states for 100 booleans is clearly
intractable. However, it goes without saying that all formal and
logic-based systems are related and are therefore "interesting".

As for the logical analysis stuff... I'm not too familiar with it
either, and I don't know how much it will help you, but perhaps you want
to read Mirjam Eladhari's master's thesis and paper on "causal
normalisation". It's not the most in-depth work, but it does refer to
some known mechanisms for manipulation of logical rules and places it in
the context of computer game narratives.

http://zerogame.tii.se/pdfs/CausalNormalisation.pdf [paper]
http://zerogame.tii.se/pdfs/OOSC-Eladhari-thesis.pdf [thesis]

Cheers,
Chris

samwyse

unread,
Jul 12, 2005, 7:15:31 AM7/12/05
to
Chris Pickett wrote:
>
> Sure... and so at least numerical is fixed (although obviously painful
> to update). But then again, presumably you'd only choose these
> arbitrary orderings when "it really doesn't matter". IOW, I think there
> are times when you can make nondeterministic choices safely.

Back in the day, there were some BASIC-like languages that used
non-integer line numbers to get around the update problem. Some used
floating point, so you could always insert a line between two others,
and I think that I recall one that used a "chapter section paragraph
line" system to allow arbitrary clumping together of lines of code which
could be renumbered as a group:

11 REM do something fancy
11.7 xyzzy = 42
11.7.5 GOSUB 12.6.3
11.7.5.3 IF noun = 'cat' THEN default = 'meow'

In this case, renumbering 11.7 would move three statements elsewhere in
the code. The interaction of this system with block statements
("FOR...NEXT") is left as a headache for the reader.

BTW, all of the BASIC-like languages had the feature that changing a
line's number would also change all references to that line number, so
changing section's 12.6 number would auto-magically update the GOSUB in
line 11.7.5. (My point in all of this is not to advocate a return to
BASIC-like languages, but to point out that other people have
encountered and solved this issue.)

Rexx Magnus

unread,
Jul 12, 2005, 7:18:24 AM7/12/05
to
On Tue, 12 Jul 2005 11:15:31 GMT, samwyse scrawled:

> BTW, all of the BASIC-like languages had the feature that changing a
> line's number would also change all references to that line number, so
> changing section's 12.6 number would auto-magically update the GOSUB in
> line 11.7.5. (My point in all of this is not to advocate a return to
> BASIC-like languages, but to point out that other people have
> encountered and solved this issue.)

I remember the commodore plus4 was the first computer I used that had the
ability to renumber a listing automatically.

--
http://www.rexx.co.uk

To email me, visit the site.

samwyse

unread,
Jul 12, 2005, 8:22:28 AM7/12/05
to
Chris Pickett wrote:
>> If there's a special rule which applies inside the aircraft hangar,
>> and another (conflicting) special rule which applies inside a taxi,
>> and you drive the taxi into the aircraft hangar... the compiler
>> shouldn't assume that the taxi rule takes precedence. (Or loses
>> precedence, either.) It's a genuine conflict, and the compiler
>> *shouldn't* try to guess.
>
> Ok, fair enough. I guess I need to formalise everything I want to say
> about containment and then see if it's useful for a non-trivial game.
> Handwaving is only so useful :(

My experience is that people start off with lists of rules. Then they
discover that explicitly stating the precedences is both cumbersome and
error-prone, because sooner or later someone will introduce a loop:
"The paper rule takes precedence over the rock rule; the rock rule takes
precedence over the scissors rule; and the scissors rule takes
precedence over the paper rule."

So, they impose an arbitrary ordering, usually the order in which the
rules are seen in the source file. This means that rearranging the
source can have side-effects, but it also means that there is always a
well-defined precedence ordering, so loops are impossible. This allows
much larger groups of rules, which leads to a combinatorial explosion.
The usual solution is to allow grouping of things, which imposes a
hierarchy. In I-F, lots of things get grouped into hierarchies.
Physical location is represented as a many-rooted tree, not an arbitrary
graph, while nouns are grouped into classes. Hierarchies allow the safe
relaxation of some of the linear precedence rules, which is a good thing.

Inform, at least, doesn't go nearly far enough in this. For example,
actions need to be organized into classes, such as meta, sensory,
movement, and state-change. Also, properties are too often used to
represent class membership; 'supporter' and 'container' should be
classes from which objects are derived.

Java's class system fixes a lot of things that were broken in C++.
Unfortunately, Inform seems to have taken its ideas about classes from
C++. In both languages, objects can have more than one parent class.
This leads to conflicts. In Java, you can define interfaces, which
don't have methods, as well as classes. In "Jaform" one might have
'supporter' and 'container' interfaces, and 'default_supporter' and
'default_container' classes which implement those interfaces and from
which most objects derive. But if you want to combine the two, you have
to define new classes that potentially implement both interfaces. This
seems like more work, but it pays off in the long run by forcing the
author to consider the conflicts as the classes are being coded, not
when unexpected behavior shows up much later.

When the player is in a taxi inside an aircraft hanger, the compiler
*should* guess which rule takes precedence; however the rules it uses to
decide need to be explicitly spelled out and easily overriden.
Hierarchies give you this power.

David Thornley

unread,
Jul 12, 2005, 9:15:39 AM7/12/05
to
In article <8COAe.562$c41...@newssvr30.news.prodigy.com>,

samwyse <deja...@email.com> wrote:
>
>Inform, at least, doesn't go nearly far enough in this. For example,
>actions need to be organized into classes, such as meta, sensory,
>movement, and state-change. Also, properties are too often used to
>represent class membership; 'supporter' and 'container' should be
>classes from which objects are derived.
>
Which means you *really* want multiple inheritance.

>Java's class system fixes a lot of things that were broken in C++.

Alternatively, Java throws away anything that might be tricky, rather
than fixes it. There are object-oriented languages other than Java
and C++ whose practitioners seem to have no problems with multiple
inheritance. (In one net discussion, I mentioned Common Lisp - which
I believe is actually the first object-oriented language officially
standardized, but the person I was talking with meant Eiffel.)

>Unfortunately, Inform seems to have taken its ideas about classes from
>C++. In both languages, objects can have more than one parent class.
>This leads to conflicts.

In practice, in some languages, the conflicts don't seem to be a problem.
They do seem to be a problem in C++, but lots of things are potential
problems in C++.

In Java, you can define interfaces, which
>don't have methods, as well as classes. In "Jaform" one might have
>'supporter' and 'container' interfaces, and 'default_supporter' and
>'default_container' classes which implement those interfaces and from
>which most objects derive. But if you want to combine the two, you have
>to define new classes that potentially implement both interfaces. This
>seems like more work, but it pays off in the long run by forcing the
>author to consider the conflicts as the classes are being coded, not
>when unexpected behavior shows up much later.
>

I disagree. I see two possibilities here.

First, there could be a quick and easy way to pull both characteristics
into one class. In this case, there's essentially no win over multiple
inheritance, since authors are going to take the easy way and find out
later it may not work the way they want.

Second, the author's attention can be forcibly directed to considering
the possible conflicts, in which case there's more work for the author
to do, and, perhaps more importantly, premature decision-making, in
which the author does things one way and finds out later that (a)
the author should have done it the other way, and (b) it's going to
be a pain to fix.

This doesn't mean that conflicts should be ignored. It would be
helpful, I think, for the compiler to spit out possible conflicts
and how they are resolved, much like YACC does with shift-reduce
conflicts (normally resolvable by the compiler) and reduce-reduce
conflicts (normally considered an error in the grammar being compiled).

>When the player is in a taxi inside an aircraft hanger, the compiler
>*should* guess which rule takes precedence; however the rules it uses to
>decide need to be explicitly spelled out and easily overriden.
>Hierarchies give you this power.

No, the author's always got the power, since the language will support
hand-written special cases. What hierarchies do is cut down on how
expressive the language is. There's reasons why no non-IBM database
ever resembled IMS.


--
David H. Thornley | If you want my opinion, ask.
da...@thornley.net | If you don't, flee.
http://www.thornley.net/~thornley/david/ | O-

0 new messages