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

[I7] My first month with I7

63 views
Skip to first unread message

Andrew Plotkin

unread,
Jun 1, 2006, 1:33:45 AM6/1/06
to
I've now been using I7 (seriously) for a month. I've finished a complete
code sample -- what Graham would call a worked example: an I7 version of the
toolcase from _Spider&Web_. All gadgets complete and functional. (Although
most of the gadgets lack interesting uses in the sample game. It's just two
empty rooms, and the only reason for the second room was to test things
being out of sight.)

<http://eblong.com/zarf/if7/HandyKit/>

Warning: this inevitably has spoilers for the early segments of _S&W_. I
changed some of the gadget effects, so it's less of a spoiler than it could
be. Nonetheless, if you're in a purist mood, go play _S&W_ first. When you
get to the point where you're playing with a big pile of toys, and you want
to know how to implement them in I7, come back and look at the _Handy Kit_
source code.

Oh, before I forget: I am using the now-current release of I7 (3M43), but
some of the code was written with earlier releases. It is possible that some
comments and work-arounds refer to problem that have been fixed in 3M43.

The intent here was to put I7 through a heavy-duty (if small-scale) test: a
complicated set of gadgets, with new grammar, timers, and events triggering
other events. I wanted to use pure I7. (In fact I wound up using one line of
I6 code.) I also wanted to adhere to a tight specification of game output:
the I7 version breaks sentences and lines the same way the I6 code did.
(And, as you'll note, there are some tricky cases in there.)

I'm afraid I *haven't* posted the original I6 gadget source. It would be a
pain to clean it up, delete all the game-location specific code, and get it
working. However, I can still make some comparisons.

* The boring numbers

This is very approximate; I made a copy of the I6 code, and then went
through and deleted everything that didn't look like a feature I'd
implemented in I7. I also deleted all my verbose comments from the I7 code,
since they're not in I6. Nonetheless, good enough to sling statistics:

Lines: I6: 1386
Lines: I7: 911

(Both files stripped of comments and word-wrapped to 80 columns.)

Behold! I6 is more verbose than I7! Well, not really. My I7 code is rather
denser than my I6 code. That is: doing something may take several I6
"steps", which I tend to write at one per line. The same task in I7 is a few
sentences, which pack together as a paragraph -- just a couple of lines.

So this is a better comparison, maybe:

Words: I6: 4747
Words: I7: 6183

That's more in tune with common sense. I6 notation is concise, and a lot of
the weight is carried by punctuation rather than words. The gap looks even
larger when you realize that nearly 800 of the words in the I6 code are "{",
"}", "[", "]", and other such tiny fragments. I don't count those as
entirely void -- you do have to notice them when reading and writing I6 code
-- but they're lightweights.

Well, what about overall file size?

Characters: I6: 34366
Characters: I7: 37693

Zut alors! Mon aubergine! The I7 file is only 10% larger? Okay, wait, I
forgot to strip tabs -- my I6 code has lots of tab-indentation.

Characters except tabs: I6: 30998
Characters except tabs: I7: 37209

This is still not bad. The I7 file is 20% larger than the I6. I was
expecting much more of a gap.

* What it was like

Graham recently asked about people's perceptions of I7 coding style.

I built the I7 toolcase code by looking at the original and "doing the same
thing". But I tried to use I7 idioms as much as possible -- this was, after
all, a learning exercise. So there's a logical mapping, but you can't point
to an I7 phrase or property and say "this is that I6 function or property."

The rule system is the I7 feature that I was most immediately comfortable
with. This is because I've always *designed* my IF using rule-style
thinking. I am entirely happy to put down, for example,

Report connecting it with: Say "Those don't connect."

and then start adding special cases:

Check connecting it with when the noun is a trigger...
Check connecting it with when the noun is a module...
Carry out connecting when the noun is a trigger and the second noun is a
module...

The I6 notion that each of those rules has to be attached to a specific
object (or class) has never sat well with me. In this case, I wound up
grouping all those rules together in my source, rather than spreading them
among the "trigger" and "module" declaration sections. (In other cases, I
went the other way.)

I am not as comfortable yet with the relational/declarational features, but
I have high hopes for them.

I used a couple of 1-1 relations in the toolcase code. These were roughly
equivalent to I6 properties, in my head -- one object is associated with
another object. 1-many relations? I expect I'll find a use for them. (Beyond
the standard object-tree sorts of relations, which have always been in
Inform... which is a good argument for the general utility of that pattern.)

Object specifications are neat. What can I do with them? I'm not sure yet. I
really dig into them in just one place in the code: the perfume spray bomb,
which I wanted to spray perfume over everything in scope. My first cut at
this was:

repeat with item running through things which can be touched by the stink
pack begin;
if the item is perfumizable, now the item is perfumey;
end repeat;

This is a direct translation of what I would do in I6: iterate over scope,
and do something in the iteration. Then I looked at it, and said, what the
hell:

now each perfumizable thing which can be touched by the stink pack is
perfumey;

That's a clear win. Similarly, the ability to list objects with a simple
specification is really tremendous. At one point, I had a (debugging) line
after the above, saying:

say "### now smelly: [list of perfumey things]."

In I6, I wouldn't have even thought of checking the world state that way. It
would have taken a WriteListFrom or objectloop, and ehh, too much fiddling.

The whole "smell" section of the sample game is original I7, by the way. If
you want to know how I work when I'm not translating I6 code, look at that.
It's a very simple and tidy section of code. On the other hand, I didn't
have a particular design in mind -- I just wanted perfume to get on things.
So I may have been taking the path of least I7-resistance.

* What needs work

I am still not confident about the behavior of the rule engine. I *use* it,
but I am constantly looking at the Rules and Actions index pages to see what
the compiler has made of my rules. To some extent, this is because I've been
burned by bugs -- many of which have been fixed. But there are still unfixed
bugs.

It is clear that the I7 compiler is enormously *harder to get right* than
the I6 compiler was. I'm sure that the original Inform compiler was buggy
after its first 30 days, but it didn't have the kind of gaps in language
structure that we're still working through. (Random example: "now everything
in the Kitchen is edible" is not the same as "now every thing in the Kitchen
is edible". Probably easy to fix; but it looks like fixing *all* of that
kind of thing is going to take a while.)

I've already posted a bit about code inefficiencies. When I wrote I6, I was
very strict about *never* iterating over the entire world, if I could
possibly avoid it. In I7, this is a lost cause. That "now each perfumizable
thing..." line? It iterates over the world, doing a scope search ("...can be
touched...") for *each* perfumizable object (e.g., every takable object in
the game). In a large game, that would be pretty awful. Even in this
example, I can detect the processing delay -- it's maybe a tenth of a second
-- on my 1GHz Mac. Ick!

(But, as I also posted, this is very amenable to compiler optimization.
That's the nice thing about these super-high-level object descriptions.
Rearrange a few "and" clauses, and that loop gets *much* faster. Cache
reverse links for those 1-1 relations, and another bunch of loops collapse.
I think that all of this will come in due course.)

(And, I have to admit, a lot of the freedom of the rule-and-description
model *is* the freedom to ignore efficiency. Want to specify a rule based on
touchability? Do it! Want to add a [list] to that message? Hey, it's cheap!
Or only slightly expensive, anyway; and it makes games better. It does.)

* What I don't like

I don't know the syntax yet.

This is not a trivial complaint. I've been pounding on the code for most of
a month (okay, I took breaks) and I still don't know all of the *low-level*
syntax. I mean, like, the placement of commas and semicolons in an "if"
statement. The language has *no* flexibility in that, so I get it wrong
every time I type it. Sure, I'll learn it; I learned the equivalent
inflexible rules for Pascal, C, and I6, didn't I? But this *has* to be a
stumbling point for non-coders; and they don't have Pascal experience.

Before, instead of, check, carry out, report, after. Did I get that right?
(No.) In I6 we had: player-orders, room-before, react_before, before,
verbsub, react_after, room-after, after. I was hoping that would get
*simpler*. I am disappointed. Particularly since the guidelines for the
before/after system and the check/report system are so unclear. In my code,
I wound up flopping back and forth between those almost at random.

The carry-out/report boundary is particularly troublesome. I see the goal:
to be able to "try silently". (I.e., carry out an action, but stop before
printing successful result text.) But for complex actions, I've got a lot of
sequential checks and possible outcomes -- all of which count as "success".
See my "Instead of pushing a dial-instance..." rules, for example. Splitting
that into carry-out/report would be a nightmare; the most sensible thing I
could do would be to bung some state into global variables. And who wants to
do that?

So I wind up doing what I do in all my I6 code: ignore the problem, and
never "try silently". But then I worry that the check/carry-out parts of my
code are going to step on, or be stepped on by, the before/instead parts of
my code. Then I wonder, who benefits from all this?

(I haven't figured out the laws of action-stopping, either. I wind up
sticking in "instead" or "stop" lines until the game behaves right. It's
clearly good that you *can* return success or failure from different parts
of a rule -- I6 was crippled by this lack -- but I haven't figured out how
to do it yet.)

After reading more discussion of the action system, I appreciate that the
check/report system is discussed late in the manual, whereas
before/instead/after comes in as part of the introduction of actions. I can
see check/report as a system for fluent I7 authors, which allows cleaner
interaction between different rules. But it isn't introduced this way (I'm
looking at 11.17, "Guidelines"). It's more or less thrown at all authors
(most of whom probably aren't comfortable even with before/instead), and
it's described as "a good idea". To make this whole dance more learnable,
I'd like to see longer examples. Set up a scenario with before/instead
rules, and then redo it with action rules -- with emphasis on what clever
tricks the latter approach allows. *And* a rule of thumb: you can ignore the
action rules (just use before/instead/after) if you don't plan to... (what?)

And this leads to the big problem: too many ways to do things. I posted a
while ago about the action/activity/phrase/rule/rulebook dance. I really,
really wanted to get *away* from I6's million different mechanisms, each
with its own syntax.

I gather that I7 is *intended* to use different syntax for different
concepts. That's not per se a bad idea. But when the concepts are related,
man, it starts to hurt. The example I wrote down a while ago:

Instead of praying:
the foo occurs;
the bar occurs in one turn from now.
To the foo occurs: say "Foo."
When the bar occurs: say "Bar."

So tell me, why does the "Foo" definition start "to" and the "Bar"
definition start "when"? Get either wrong and the compiler bites you. Events
are "when"; phrases are "to". But what is an event if not a phrase which
will get executed later on? Why not, in fact, allow "say 'Baz' in two turns
from now"? The system seems set up to keep clear a distinction which
shouldn't exist in the first place.

That, writ larger, is how I feel about the activities and rulebooks and
phrases and so on. See post from a couple of weeks ago -- I've got nothing
to add there.

Other than that... I have vague intimations that some I7 constructs need
another round of being torn out and redesigned. There's some design baggage
hanging on.

This is vague because my initial example is not as baggage-laden as I
thought it was. I was thinking of the distinction between either/or
properties ("A fruit can be alpha or beta") and value properties ("A fruit
can be harpo, groucho, or chico"). Internally, of course, these are handled
as Z-code object attributes and Z-code object properties: attributes are
one-bit flags, whereas properies can store any scalar value.

I was set to complain that the language handles these differently, for no
better reason than that the Z-machine handles them differently. But in fact
the language handles them very nearly the same! As an author, I can more or
less ignore the difference, except for a few quirks. (E.g., you can say
"*either* alpha or beta", but the word "either" is not recognized correctly
in three-value properties.) There are some special semantics to the
two-value case -- "not alpha" is the same as "beta" -- but this follows
common sense.

So what else seems clumsy? I am not entirely happy with the use of
properties for customization. It seems like an I6 leftover to have initial
appearance, description, and inventory listing be properties. Most of the
other customizations of that sort are activities or rules.

In fact, I'd say that the I6 "description" property is an *implementation*
of a (notional) activity. The default activity is "You see nothing special";
then different objects customize it. The only reason to stick the
customizations into a Z-machine property is efficiency. And the point of I7
is to have a high-level description; the *compiler* should be able to
optimize it. An activity like "description", which has a wide, flat
condition-tree, should be implemented as a property check behind our backs!
(Just as a two-value "can be..." property gets implemented as a Z-machine
attribute.)

(This is a separate issue from *source* efficiency. I7 has an abbreviated
syntax for room-description, which is fine. The description-property syntax
is also terse. And I certainly don't want to have to type "Rule for
describing the X: say ..." on every object. But I'd rather see description
handled *as* an activity, and then maybe some terse way of specifying
activity cases. That would benefit other parts of the system as well.)

Also on properties: section 12.14 of the manual introduces relations
involving values, and then says "Of course, this does no more than to wrap
up a property in the language of relations..." This makes me wonder if it
should be the other way around: I7 should *primarily* deal with values in
terms of relations, and allow object properties to be a special case of
that. I know, I'm not being specific here. But again, this seems like a
low-level construct is being allowed to steer the design.

Then there's the scene system, which I haven't used yet -- but I've seen
some ferocious discussion go 'round about. The discussion usually ends with
either "I can't make it do what I want," or "I can make it do what I want,
but only by an ugly workaround." So I'm going to venture a guess that scenes
need work. Whether there *is* a redesign that would suit everyone's needs, I
have no idea.

(Do scenes have to be in the I7 language at all? It seems like you could
build the whole scenery model with relations and an "every turn" rule. Yank
it out of the compiler and put it into an extension? Mind you, I'm waving my
hands hard enough to achieve orbit here; I haven't tried *doing* this. But
if you could, it would solve the problem of not meeting people's needs.)

Okay, long post and getting late. (And the subject line is getting less
accurate by the minute.)

So, *summary*: I like I7. I can write IF in it. I feel that I can write
quality IF without dropping into I6. (The toolcase code contains just one
line of I6, and that's a hack in the paragraph-breaking model which would
make a simple extension.)

There are several areas which I7 does not address yet. They've come up in
newsgroup discussion: a ChooseObjects equivalent, better name-parsing
support, etc. I am disregarding those areas when I say "I can write quality
IF..." They are clearly necessary, but the holes will be filled as I7 moves
through beta.

More importantly, I7 is way more fun than I6.

If I were to start working on a small IF work tomorrow, I'd use I7. If I
were to start working on a *large* IF work, I'd use I6. I do not say this
because of the complaints I've detailed in this post. It's merely because I7
is evolving rapidly. If I were to start working on a large IF work *a few
months from now*, I'd probably go with I7.

(And that uncertainty is really just a matter of how many months is "a few".
We've had four releases in the first month, but I don't have a feel for how
quickly that will decelerate.)

--Z

--
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*
It used to be that "conservatives" were in favor of smaller government,
fiscal responsibility, and tighter constraints on the Man's ability to
monitor you, arrest you, and control your life.

Daryl McCullough

unread,
Jun 1, 2006, 7:50:05 AM6/1/06
to
Andrew Plotkin says...

>I've already posted a bit about code inefficiencies. When I wrote I6, I was
>very strict about *never* iterating over the entire world, if I could
>possibly avoid it. In I7, this is a lost cause. That "now each perfumizable
>thing..." line? It iterates over the world, doing a scope search ("...can be
>touched...") for *each* perfumizable object (e.g., every takable object in
>the game). In a large game, that would be pretty awful. Even in this
>example, I can detect the processing delay -- it's maybe a tenth of a second
>-- on my 1GHz Mac. Ick!
>
>(But, as I also posted, this is very amenable to compiler optimization.
>That's the nice thing about these super-high-level object descriptions.
>Rearrange a few "and" clauses, and that loop gets *much* faster. Cache
>reverse links for those 1-1 relations, and another bunch of loops collapse.
>I think that all of this will come in due course.)

Something that I've thought about for programming in general,
and Inform 7 in particular, is this:

There is often a tension between writing code that is
clear and writing code that is efficient. In some
cases, the compiler can figure out a faster way to
do things, but I've wondered whether it would be
possible to have two separate programming
declarations, the first giving the intended effect
in the clearest way possible, and the second giving
helpful hints about how to do it efficiently. In
Inform 7, you could do it this way:

Now each perfumizable thing is ....
(Try caching reverse links.)

The advantage to separating the what from the how
is that it would make it much easier to recover to
an inefficient but correct version if a bug is found
in the more efficient version.

>* What I don't like
>
>I don't know the syntax yet.

My complaint about the syntax is that it is very
unclear what language tokens are meaningful and
which ones are "syntactic sugar". It's not clear
when a sequence of words are conceptually taken
as a unit, and when the parts have meaning.

The sort of thing I'm talking about is stuff like

When the bomb explodes, say "Kaboom".

Is that an "explode" action that happens to have "the bomb"
as its subject? Or is the entire expression "the bomb explodes"
just a name for an event? If I say

A red balloon is in the big room.

are the strings "red" and "big" understood by the program
as adjectives, or does the program just understand
"red balloon" (or even "the red balloon") as a whole?
In more traditional programming languages, it is obvious
what are considered undecomposable tokens (usually because
you have to say "the_red_balloon" to clue the program in).

In many cases, Inform 7 does the right thing and you don't
have to worry about exactly how your code is being parsed,
but when something *doesn't* parse, it can be mysterious
as to why not.

>...Particularly since the guidelines for the before/after system


>and the check/report system are so unclear. In my code,
>I wound up flopping back and forth between those almost at random.

What I thought was the pattern was that check/carry-out/report
is to be used when defining *new* actions, and instead/before/after
is to be used when modifying existing actions.

--
Daryl McCullough
Ithaca, NY

Andrew Plotkin

unread,
Jun 1, 2006, 12:56:22 PM6/1/06
to

I like that idea.

For this case you're applying the hint to the wrong bit. Reverse links
(for a 1-1 relation) make it more efficient to evaluate conditions
like:

If mod [module] interfaces something (called trig)...

Currently, that works by looping over all the tools and seeing which
one is interfaced by mod. So the hint would be more like, maybe:

Connectivity relates one tool to another (called the partner). The
verb to interface (it interfaces, they interface, they interfaced, it
is interfaced, it is interfacing) implies the connectivity relation.
(Use two-way storage for connectivity.)

> >I don't know the syntax yet.
>
> My complaint about the syntax is that it is very
> unclear what language tokens are meaningful and
> which ones are "syntactic sugar". It's not clear
> when a sequence of words are conceptually taken
> as a unit, and when the parts have meaning.

See the better-syntax-coloring/underlining/whatever thread. I am
growing more and more convinced that it's necessary.



> >...Particularly since the guidelines for the before/after system
> >and the check/report system are so unclear. In my code,
> >I wound up flopping back and forth between those almost at random.
>
> What I thought was the pattern was that check/carry-out/report
> is to be used when defining *new* actions, and instead/before/after
> is to be used when modifying existing actions.

No, that's definitely not the right. Changing the "report" rules is an
easy way to change what existing actions print without changing how
they *work*. For example, I did this:

Report taking a module when the noun is connected:
instead say "You take [the noun] (and [the partner of the
noun] connected to it)."

--Z

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

If the Bush administration hasn't shipped you to Syria for interrogation,
it's for one reason: they don't feel like it. Not because you're patriotic.

Mark Borok

unread,
Jun 1, 2006, 2:02:25 PM6/1/06
to
I have no problem with the punctuation syntax. Seems to me to follow
rules of standard English punctuation: colons to present a sequence of
phrases; semicolons to separate those phrases; commas to separate
other, more unified phrases.

I may not be stating that correctly, but basically my knowledge of the
English language helps here is what I'm trying to say.

What I find somewhat annoying, as a programming dilettante, is that
certain common programming functions lose their conciseness without
adding much to readability in the NL model. There are things I expect
to do, like being able to concatenate strings with a + sign, or writing
common equations with parentheses like so: X * (Y + Z) that can't be
done in I7. Not even sure if they ever need to be done in an IF
context, but who knows? There might be a use for them.

I would vote for user-friendly abbreviations, the way I remember BASIC
using ? as an abbreviation for the PRINT command. As I recall, the
intepreter would expand the abbreviation, which makes for a maximum of
speed plus readability. I think I mentioned this elsewhere.

I would also add a chapter to the manual explaining the difference
between similar commands. It took me a while to figure out where to use
"To..." and I also found myself able to interchangeably write (the
noun) and (Bob - a man) in one piece of code. I suspect, even though
both worked, one was optimal and proper and I would like to know which
one (I'm starting to understand, actually).

Daryl McCullough

unread,
Jun 1, 2006, 2:18:33 PM6/1/06
to
Andrew Plotkin says...

So is a change to the "report" rules exactly equivalent to
adding an "after" rule? I had the idea that "after" just
inserts additional rules between the "carry-out" rules and the
"report" rule.

Andrew Plotkin

unread,
Jun 1, 2006, 2:44:05 PM6/1/06
to
Here, Daryl McCullough <stevend...@yahoo.com> wrote:
> Andrew Plotkin says...
> >
> >Here, Daryl McCullough <stevend...@yahoo.com> wrote:
>
> >> What I thought was the pattern was that check/carry-out/report
> >> is to be used when defining *new* actions, and instead/before/after
> >> is to be used when modifying existing actions.
> >
> >No, that's definitely not the right. Changing the "report" rules is an
> >easy way to change what existing actions print without changing how
> >they *work*. For example, I did this:
> >
> >Report taking a module when the noun is connected:
> > instead say "You take [the noun] (and [the partner of the
> > noun] connected to it)."
>
> So is a change to the "report" rules exactly equivalent to
> adding an "after" rule?

No.

> I had the idea that "after" just inserts additional rules between
> the "carry-out" rules and the "report" rule.

That's right. The point of using the "report" rule is to change
the output message without interfering with any "after" rules.

An "after" rule is some world-state change which is caused by the
action (and follows the action, and may (or may not) change the
standard report of the action.) A "report" rule *is* the standard
report of the action.

Which sounds more confident than I sounded in my original post. I am
less confident about when to use "check", "before", and "instead.

mikegentry

unread,
Jun 1, 2006, 3:26:05 PM6/1/06
to
Andrew Plotkin wrote:
> Which sounds more confident than I sounded in my original post. I am
> less confident about when to use "check", "before", and "instead.

The main difference between Before and Instead seems to be that a
Before rule always lets the action continue after executing (unless you
tell it otherwise) while an Instead rule prevents the action from
happening (unless you tell it otherwise)*. Before rules also trigger
before checking for visibility/touchability, so you could, for example
write a "Before taking..." rule for something inside an enclosed glass
box.

I only use "check" when creating new verbs or modifying the default
behavior of existing verbs. I usually think of them as the "baseline
requirements" (aside from visibility and touchability) for an action to
succeed -- e.g., checking to see if you're holding something before
putting it inside something else, etc.

duo...@gmail.com

unread,
Jun 1, 2006, 6:59:13 PM6/1/06
to
Wow, Z. That's some post. Thanks for the in-depth article. I'm
personally hoping that I7 will improve dramatically in the next few
months, but I think that code we write today won't be invalidated by
future versions.

-dave

na...@natecull.org

unread,
Jun 1, 2006, 8:45:02 PM6/1/06
to

> An "after" rule is some world-state change which is caused by the
> action (and follows the action, and may (or may not) change the
> standard report of the action.) A "report" rule *is* the standard
> report of the action.

What I find counterintuitive is that 'After' rules actually run
*before* 'Report' rules.

I would like a 'real-after' rule, like the I6 react_after or the
Platypus respond_late_late, which runs after the entire sequence of
before/instead/check/carry out/after/report, but only if the action
succeeded. For implementing NPC and/or machinery reactions to actions.

Or can you do that with 'every turn <action>'?

vaporware

unread,
Jun 1, 2006, 9:15:05 PM6/1/06
to
na...@natecull.org wrote:
> I would like a 'real-after' rule, like the I6 react_after or the
> Platypus respond_late_late, which runs after the entire sequence of
> before/instead/check/carry out/after/report, but only if the action
> succeeded. For implementing NPC and/or machinery reactions to actions.
>
> Or can you do that with 'every turn <action>'?

Yes, I believe you can.

vw

Andrew Plotkin

unread,
Jun 1, 2006, 11:20:51 PM6/1/06
to

Yes, I see that would be desirable in some situations.

I guess I go back to my old assertion that no predefined sequence of
phases is ever good enough. You need a generalized system to talk
about rule-ordering directly.

And whenever I try to think about that, my brain melts. Your
requirement of "only if the action succeeded" is a nice example. How
do you say *that*? How do you say "do this but silently" (i.e.,
suppress all the reporting steps)? In a general way? Oy.

--Z

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

If the Bush administration hasn't subjected you to searches without a warrant,
it's for one reason: they don't feel like it. Not because you're innocent.

Philippa Cowderoy

unread,
Jun 1, 2006, 11:37:41 PM6/1/06
to
On Fri, 2 Jun 2006, Andrew Plotkin wrote:

> I guess I go back to my old assertion that no predefined sequence of
> phases is ever good enough. You need a generalized system to talk
> about rule-ordering directly.
>
> And whenever I try to think about that, my brain melts. Your
> requirement of "only if the action succeeded" is a nice example. How
> do you say *that*? How do you say "do this but silently" (i.e.,
> suppress all the reporting steps)? In a general way? Oy.
>

This sounds somewhat analogous to a situation I might use monads for in
Haskell: the monad would define the phases, and individual operations
(with their types hopefully parameterised so as to apply in all monads
with relevant phases) in it would supply "but silently" and the like.

I don't know that thought's well-formed enough to sit down and code up,
it might hit a functional vs logical problem, but I figure there're other
haskellers here who might want to pick up the ball and run with it?

--
fli...@flippac.org

A problem that's all in your head is still a problem.
Brain damage is but one form of mind damage.

na...@natecull.org

unread,
Jun 2, 2006, 1:15:33 AM6/2/06
to

> And whenever I try to think about that, my brain melts. Your
> requirement of "only if the action succeeded" is a nice example. How
> do you say *that*? How do you say "do this but silently" (i.e.,
> suppress all the reporting steps)? In a general way? Oy.

I suppose I was thinking at a fairly basic level that there's always a
case where we can say an action 'succeeded' or 'failed'... if it
succeeds then the actor is taken to have done the action and any other
processes (ie, rules) observing the events get their chance to respond
to it. And there's presumably a global flag set somewhere saying
'status of current action: processing | succeeded | failed'.

Am I thinking too literally here? Are there cases with your toolkit
where you <push button> and the button does not get pushed but
something significant happens that changes the world state?

Andrew Plotkin

unread,
Jun 2, 2006, 2:01:39 AM6/2/06
to
Here, na...@natecull.org wrote:
>
> > And whenever I try to think about that, my brain melts. Your
> > requirement of "only if the action succeeded" is a nice example. How
> > do you say *that*? How do you say "do this but silently" (i.e.,
> > suppress all the reporting steps)? In a general way? Oy.
>
> I suppose I was thinking at a fairly basic level that there's always a
> case where we can say an action 'succeeded' or 'failed'... if it
> succeeds then the actor is taken to have done the action and any other
> processes (ie, rules) observing the events get their chance to respond
> to it. And there's presumably a global flag set somewhere saying
> 'status of current action: processing | succeeded | failed'.

What I'm trying to express, at a very abstract level, is this problem:
you have some rule R. In certain cases ("if condition C"), rule S
replaces rule R.

Now, rule T should occur if R succeeds. Question: does the S case
count as R (because S is replacing R) or not? Answer: there is no
right answer, because in some cases you mean it to count, and in other
cases you mean it to not count.

So what is the logical structure of the language in which you can
*say* which way you mean it?

This is unfortunately not amenable to simple examples. It's trivial to
write down pseudocode (or NL-like) statements that express this
example (R, S-when-C, T) and provide an option for whether T considers
S to be R or not. I have pages of damn pseudocode. What I don't have a
model that expressed all of them consistently.

--Z

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

If the Bush administration hasn't shipped you to Syria for interrogation, it's

greg

unread,
Jun 2, 2006, 3:00:01 AM6/2/06
to
Andrew Plotkin wrote:

> I've already posted a bit about code inefficiencies. When I wrote I6, I was
> very strict about *never* iterating over the entire world, if I could
> possibly avoid it. In I7, this is a lost cause. That "now each perfumizable
> thing..." line? It iterates over the world, doing a scope search ("...can be
> touched...") for *each* perfumizable object (e.g., every takable object in
> the game).

Maybe if the world model were stored in an RDBMS, and
I7 generated SQL instead of I6...

--
Greg

greg

unread,
Jun 2, 2006, 3:06:32 AM6/2/06
to
Andrew Plotkin wrote:

> Connectivity relates one tool to another (called the partner). The
> verb to interface (it interfaces, they interface, they interfaced, it
> is interfaced, it is interfacing) implies the connectivity relation.
> (Use two-way storage for connectivity.)

But shouldn't the compiler be able to work this out for
itself by considering the ways in which the relation
is used in the code?

--
Greg

greg

unread,
Jun 2, 2006, 5:25:48 AM6/2/06
to
Andrew Plotkin wrote:

> What I'm trying to express, at a very abstract level, is this problem:
> you have some rule R. In certain cases ("if condition C"), rule S
> replaces rule R.
>
> Now, rule T should occur if R succeeds. Question: does the S case
> count as R (because S is replacing R) or not?

I'm wondering whether having rules replace other rules is
even a good idea in the first place.

The big-bag-of-rules model of programming, with rules
scattered all over the source, is worrying enough, because
it's spaghetti code. Rules being able to manipulate other
rules is even worse, because it's *self-modifying*
spaghetti code.

Have you considered whether there is some way of
expressing these kinds of things without resorting
to a self-modifying rule base?

The particular case of wanting to do things silently
seems simple enough -- just have a global flag for
suppressing output, and a way of invoking another
action with that flag set for the duration.

Do you have use cases which wouldn't be amenable to
this kind of technique?

> I have pages of damn pseudocode. What I don't have a
> model that expressed all of them consistently.

I think we definitely need a formalism that lets us
discuss the mechanics without the ambiguities of the
NL getting in the way. Maybe something resembling
Prolog, Haskell?

Or maybe an S-expression representation of I7's internal
parse tree, whatever the heck that's like...

--
Greg

JDC

unread,
Jun 2, 2006, 6:26:39 AM6/2/06
to
I'll throw in a few random disjointed responses here, having now myself
played around enough to finish a small test project.

Andrew Plotkin wrote:
> * The boring numbers

Although the I7 code is a bit more verbose, I find I can actually
_type_ it faster than I can I6. I can simply type English faster than I
can type code (which is a bit odd, since most of the "typing" I do is
TeX). So I find I can actually write faster in I7.

> * What it was like

> The rule system is the I7 feature that I was most immediately comfortable


> with. This is because I've always *designed* my IF using rule-style
> thinking. I am entirely happy to put down, for example,

I find the rule-based system makes interactions between objects easier
to deal with. I have found it easier to add new things without breaking
the code I have set up already. I find this makes debugging a bit
easier, too, albeit different. Some of the most difficult problems for
me are caused by imporoper ordering of my rules; it is rarer to have
some apparently isolated piece of code breaking something elsewhere.

> I am not as comfortable yet with the relational/declarational features, but
> I have high hopes for them.

I have only played with relations a bit, but the new features I like
most are the imposed symmetry for reflexive relations and equivalence
relations and the ability to attach succinct names to the corresponding
objects. The current problems with unsetting relations have kept me
from really using relations dynamically so far.

> Object specifications are neat.

Definitely. I sometimes worry that they will lead me to write horribly
computationally expensive code by accident, though.

> * What I don't like
>
> I don't know the syntax yet.

I still confuse when/while/if/during (and other similar things) and
find myself referring to the documentation. This would probably bother
me more if it weren't so easy to look in the documentation. The commas
in if statements are one of my worst problems, particularly when I need
to expand an "if (condition), (phrase);" into an "if (condition) begin;
... end;" and forget to remove the comma.

> Before, instead of, check, carry out, report, after. Did I get that right?

This also still confuses me, although I'm getting a better sense of how
I want to use them. One of the problems I find is when I want some rule
to intercede before, say, all actions. I haven't gotten fully adept at
ordering rules, so I end up doing things like converting all the other
"before" rules I want into "instead" rules. I think a lot of this is
just inexperience with the system, though.

The success/failure of actions also trips me up. My instinct is to
handle special cases with "instead" rules, which is fine until I want
to use a "if we have ..." phrase, where this is now treated as failure.
I also get confused by the fact that the "for the nth time" condition
counts trying, as opposed to success.

But I think I will eventually get used to this system.

> Then there's the scene system, which I haven't used yet -- but I've seen
> some ferocious discussion go 'round about. The discussion usually ends with
> either "I can't make it do what I want," or "I can make it do what I want,
> but only by an ugly workaround." So I'm going to venture a guess that scenes
> need work. Whether there *is* a redesign that would suit everyone's needs, I
> have no idea.

I actually like the scene system a lot, although sometimes I find it
more convenient to test some either/or property (e.g. giving a machine
an active condition and saying "every turn when the machine is active"
vs. having a scene called "Machine Activity" and saying "every turn
during Machine Activity"). I find the scenes work best for one-use time
periods, since the "when scene begins" and "when scene ends" are
convenient, and I like the ability to connect scenes using these. Many
of the problems I have seen reported with scenes seem to be with
accidentally looping them, and I'm not sure another system is going to
prevent that.

> More importantly, I7 is way more fun than I6.

I wholeheartedly agree. I particularly like the fact that you can
(sometimes unintentionally) make your code amusing to read.

One thing that occurred to me is that I7 will probably allow much
better speed IF. I have never tried speed IF myself, and have only
looked at a couple of examples of it, but my impression is that you can
create a nice single puzzle or one-act game quickly in I7 and still
have it feel
pretty smooth.

I also really like the text substitutions, which make modifying
descriptions based on conditions much simpler than in I6.

Well, those are a few of my (belated) first impression,
-JDC

Daryl McCullough

unread,
Jun 2, 2006, 7:10:56 AM6/2/06
to
Andrew Plotkin says...

>What I'm trying to express, at a very abstract level, is this problem:
>you have some rule R. In certain cases ("if condition C"), rule S
>replaces rule R.
>
>Now, rule T should occur if R succeeds. Question: does the S case
>count as R (because S is replacing R) or not? Answer: there is no
>right answer, because in some cases you mean it to count, and in other
>cases you mean it to not count.

Maybe it would help to have a broader notion of the completion
status of a rule. Rather than just succeed/fail, there would be
a return code associated with a rule to describe *how* it completed.
For example, "completes normally", "completes silently", etc.
Then rather than saying that T happens if R succeeds, you could
say more specifically which return code(s) of R count as triggers
for T. If S returns one of those code(s), then that counts as
a trigger for T, as well.

Neil Cerutti

unread,
Jun 2, 2006, 10:01:30 AM6/2/06
to
On 2006-06-01, Andrew Plotkin <erky...@eblong.com> wrote:
> That's right. The point of using the "report" rule is to change
> the output message without interfering with any "after" rules.
>
> An "after" rule is some world-state change which is caused by
> the action (and follows the action, and may (or may not) change
> the standard report of the action.) A "report" rule *is* the
> standard report of the action.
>
> Which sounds more confident than I sounded in my original post.
> I am less confident about when to use "check", "before", and
> "instead.

I think Instead is a more convenient Before, for use when you
know you want to stop the action.

Before [condition]: [[phrase].*] Stop the action. [or "instead"
if it's one sentence]

So I think of the above as equivalent to:

Instead of [condition]: [[phrase].*]

But I could be mistaken.

--
Neil Cerutti
Due to the Rector's illness, Wednesday's healing services will
be discontinued until further notice. --Church Bulletin Blooper


Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php

Neil Cerutti

unread,
Jun 2, 2006, 11:15:07 AM6/2/06
to
On 2006-06-02, Neil Cerutti <lead...@email.com> wrote:
> I think Instead is a more convenient Before, for use when you
> know you want to stop the action.
>
> Before [condition]: [[phrase].*] Stop the action. [or "instead"
> if it's one sentence]
>
> So I think of the above as equivalent to:
>
> Instead of [condition]: [[phrase].*]
>
> But I could be mistaken.

I'm mistaken. Check out the current sections 6.4 and 6.5.

Before rules are carried out before anything else. Specifically,
visibility and touchability are not considered yet when a Before
rule is considered. Instead rules take place specifically right
after touchabilty and visibility have been decided, but before
any check rules.

See the diagram in 11.2.

So it seems to me that Before rules won't be the right choice
very often, particularly when visibility and touchability will be
a common issue in your game. If there are transparent containers,
darkness, or weird visibility rules, then liberally using Before
seems likely cause bugs.

To critique an example in the documentation:

Before taking the napkin, say "(first unfolding its delicate
origami swan)".

This a bug when the napkin is not visible, and perhaps misleading
when its not touchable.

You are in the dining hall. The long dining table extends from
end to end.

Resting on the table, underneath a glass cover, is a napkin,
folded cleverly into the shape of a swan.

>TAKE NAPKIN
(first unfolding its delicate origami swan)
The glass cover is in the way.

Using an instead rule:

Instead of taking the napkin: say "(first unfolding its delicate
origami swan)"; continue the action.

>TAKE NAPKIN
The glass cover is in the way.

>TAKE GLASS COVER
Taken.

>TAKE NAPKIN
(first unfolding its delicate origami swan)
Taken.

Anyhow, even if you don't agree the Before rule is a bug, this
still demonstrates the major difference between Before and
Instead rules.

--
Neil Cerutti

Andrew Plotkin

unread,
Jun 2, 2006, 12:25:11 PM6/2/06
to

Maybe. There's always tradeoff between memory and speed, and I'm not
willing to say that the answer will always be obvious to the compiler.
(In a many-many relation, or even a many-one relation, the cost of
storing the reverse relation is very high.)

--Z

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

If the Bush administration hasn't subjected you to searches without a warrant,

it's for one reason: they don't feel like it. Not because you're innocent.

Andrew Plotkin

unread,
Jun 2, 2006, 12:45:27 PM6/2/06
to
Here, Neil Cerutti <lead...@email.com> wrote:
>
> See the diagram in 11.2.
>
> So it seems to me that Before rules won't be the right choice
> very often, particularly when visibility and touchability will be
> a common issue in your game. If there are transparent containers,
> darkness, or weird visibility rules, then liberally using Before
> seems likely cause bugs.

A reasonable use of "before" rules is to change the player's command
to what he really meant:

Before examining the conversation:
say "(listening to that)";
instead try listening to the conversation.

If you have a listen-only reachability rule on the conversation, this
will correctly bypass it in the "examine" case.

But this is a rather exotic example. I used both "check" and "instead"
rules to accomplish this redirection in HandyKit, and they work
adequately.

--Z

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

If the Bush administration hasn't subjected you to searches without a warrant,

it's for one reason: they don't feel like it. Not because you're innocent.

Jon Ingold

unread,
Jun 2, 2006, 1:54:16 PM6/2/06
to

> What I find counterintuitive is that 'After' rules actually run
> *before* 'Report' rules.

I've always avoided After rules completely, even in I6. They run after
some actions, and replace the output of the game sometimes (I think).
They just didn't seem very stable for anything apart from replacing "Taken".

It seems, in I7, since "Report" exists, that After shouldn't be used for
replacing messages any more. It should be for things that occur as a
consequence (but before Every Turn rules, in case of conflict).

Jon

Andrew Plotkin

unread,
Jun 2, 2006, 2:03:28 PM6/2/06
to
Here, greg <gr...@cosc.canterbury.ac.nz> wrote:
> Andrew Plotkin wrote:
>
> > What I'm trying to express, at a very abstract level, is this problem:
> > you have some rule R. In certain cases ("if condition C"), rule S
> > replaces rule R.
> >
> > Now, rule T should occur if R succeeds. Question: does the S case
> > count as R (because S is replacing R) or not?
>
> I'm wondering whether having rules replace other rules is
> even a good idea in the first place.

So am I, but the reason I don't know is because nobody's tried it.


> The big-bag-of-rules model of programming, with rules
> scattered all over the source, is worrying enough, because
> it's spaghetti code.

I7 is not a bag of rules in the sense that I really want, but it
*does* allow you to scatter rule declarations (and other assertions)
all over your source. I think this is a great improvement over I6. In
my sample I7 game, I was able to organize my code in a *more* logical
(and readable) arrangement than I6 did.

Anyway, if you think the author is unable to organize his code without
falling into spaghetti, you have to reject I6 also. Nothing in I6
forces you to group related objects near each other.

My hypothetical ideal system would give you tools for considering
a "bag of rules" as a *closed* bag -- ie, "I know that chapter of the
source works, so do that, but after each action do the following." Or
"before each action, make the following check."

This is what I7's before/after rules are intended to do. They work for
simple cases, but I don't think they scale well. If you accidentally
stick two "before" rules on something, the compiler doesn't register a
conflict and ask you to resolve it; it just picks a precedence order.
This leaves you with the job of finding and resolving all the
conflicts yourself. And you have no tools to make that easier; you
can't say "darkness trumps all the can't-read-foreign-language reading
rules, but glowing runes trump darkness" in any convenient way.

> Rules being able to manipulate other rules is even worse, because
> it's *self-modifying* spaghetti code.

I am not in fact partial to the idea of rules *modifying* rules at all
-- not at runtime. What I want is for *me* to modify the rules, based
on expressed conditions. I7 allows this for many cases, but then
lapses into procedural rules for many more cases. I think that nearly
all of what I7 does in procedural rules could be satisfactorily
handled at compile-time.

> The particular case of wanting to do things silently
> seems simple enough -- just have a global flag for
> suppressing output, and a way of invoking another
> action with that flag set for the duration.

That's exactly the kind of special-case hack which we've been using
all along, to avoid solving the problem. What if we want an output
message that trumps silence? What if we then want even-silenter? What
about "try this action, but report all the output in the third
person"?

It is, again, trivial to solve each of these problem with its own
hack.

--Z

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

If the Bush administration hasn't thrown you in military prison without trial,
it's for one reason: they don't feel like it. Not because you're an American.

Shadow Wolf

unread,
Jun 2, 2006, 2:13:06 PM6/2/06
to
"JDC" <jd...@psu.edu> wrote in news:1149243999.092170.151130
@u72g2000cwu.googlegroups.com:

> The success/failure of actions also trips me up. My instinct is to
> handle special cases with "instead" rules, which is fine until I want
> to use a "if we have ..." phrase, where this is now treated as failure.

If you want to write an Instead rule for a special case, and have the
action counted as a success, simply end the Instead rule with "rule
succeeds."

--
Shadow Wolf
shadowolf3400 at yahoo dot com
Stories at http://www.asstr.org/~Shadow_Wolf
AIF at http://www.geocities.com/shadowolf3400

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----

Jon Ingold

unread,
Jun 2, 2006, 2:16:59 PM6/2/06
to
On scenes --

I don't feel very comfortable with these: I remember when Emily released
Moderator.h: I took a look and thought, no, this isn't going to make my
life easier. I've always hated daemons; they interface badly with the
action-processing part of the code. Taking them off objects is nice, but
the scene mechanism doesn't do anything else. I want something more
script-like, since my I6 daemons always looked the same:

switch(self.count++) {
1:
2:
3:
4: if (something) self.count = 10; else self.count = 4;

10:
11: etc.

So I guess I want a script-layout of some kind:

Every turn while Entering the Volcano is happening:
1:
2:
3:
last:

and so forth for each section of my original daemon. I could do this
with a table, maybe, and some mechanics (can I store phrasenames/rules
in tables? so "follow the rule in Row N of the Volcano Script Table)?

Actually, I want to be able to define "kinds of scene", such as
"one-off" (only happens once), etc.

On syntax --

I don't get it. I don't know the fundamental rules for compounding
stuff. Things like:

Instead of attacking or pulling or pushing the door for the second time...

Instead of pulling or battering the door or the handle with something
for the third time...

Instead of examining the lantern when it has been examined...
(or we have examined ... )

...fail and succeed in a way that seems to be arbitrary, preventing me
from really learning the syntax. The desire for fluid NL hides the
margins of the compilers understanding.

Then there's "it", which really ought to work in sentences with only one
noun where it's unambigious, to prevent

Instead of taking the lantern when the lantern is alight, say "Ouch! Hot!".

---

I love the past tense handling, but I can't get it to stay alive. The
worst example of this is:

say "[position of the statue]"

To say position of (the artwork - a thing):
if the artwork has been handled, say "It looks slightly out of place.";
otherwise say "It looks pristine".

but temporary variables, we are told, have no history...

---

In short, I love it, and I'm really hoping that it's at a place where I
can stick my oar in and make it do the little things I wish it would. If
I can only pin down what they are...

Jon

Reiko

unread,
Jun 2, 2006, 5:43:07 PM6/2/06
to

Andrew Plotkin wrote:

> This is what I7's before/after rules are intended to do. They work for
> simple cases, but I don't think they scale well. If you accidentally
> stick two "before" rules on something, the compiler doesn't register a
> conflict and ask you to resolve it; it just picks a precedence order.
> This leaves you with the job of finding and resolving all the
> conflicts yourself. And you have no tools to make that easier; you
> can't say "darkness trumps all the can't-read-foreign-language reading
> rules, but glowing runes trump darkness" in any convenient way.

Isn't that what rulebooks are for? I haven't used them much yet, but
according to the documentation, you can set an order for rules. I'm not
sure if you can *change* that order in response to certain game
conditions, but that doesn't sound like it'd be necessary.

Andrew Plotkin

unread,
Jun 2, 2006, 6:36:09 PM6/2/06
to
Here, Reiko <tel...@gmail.com> wrote:
>
> Andrew Plotkin wrote:
>
> > This is what I7's before/after rules are intended to do. They work for
> > simple cases, but I don't think they scale well. If you accidentally
> > stick two "before" rules on something, the compiler doesn't register a
> > conflict and ask you to resolve it; it just picks a precedence order.
> > This leaves you with the job of finding and resolving all the
> > conflicts yourself. And you have no tools to make that easier; you
> > can't say "darkness trumps all the can't-read-foreign-language reading
> > rules, but glowing runes trump darkness" in any convenient way.
>
> Isn't that what rulebooks are for?

That's what they're for, but -- as I said -- I don't think they scale
well (as your game becomes more complicated). There's a notion of a
"first rule" for a rulebook, but you can only do that *once* per
rulebook; that's an obvious failure of scaling.

And, more generally, the mechanisms for ordering a new rule require
you to look at, and think about, all the existing rules. That's what I
mean by "no tools to make that easier". The only clumping mechanism is
to put a bunch of rules together into a sub-rulebook, but then that's
impenetrable -- you can't *de*-clump them.

--Z

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

It used to be that "conservatives" were in favor of smaller government,
fiscal responsibility, and tighter constraints on the Man's ability to
monitor you, arrest you, and control your life.

Jon Ingold

unread,
Jun 2, 2006, 7:20:52 PM6/2/06
to

> And, more generally, the mechanisms for ordering a new rule require
> you to look at, and think about, all the existing rules. That's what I
> mean by "no tools to make that easier".

Clearly what's needed here is something in the IDE, that allows one to
drag and drop rules into the correct order, and then have the program
insert the appropriate ordering statements into the source code. ;)

I have a hobby horse, ladies and gentlemen.

Jon

Richard Bos

unread,
Jun 2, 2006, 8:14:50 PM6/2/06
to
"vaporware" <jmc...@gmail.com> wrote:

Possibly, but wouldn't that be horrendously expensive? Having a rule
checked every turn just for what is basically a react_after... ugh.

Richard

greg

unread,
Jun 2, 2006, 10:08:20 PM6/2/06
to
Andrew Plotkin wrote:

> And, more generally, the mechanisms for ordering a new rule require
> you to look at, and think about, all the existing rules.

I don't see how that can be avoided in any system that
relies on an ordering to disambiguate rules.

--
Greg

Andrew Plotkin

unread,
Jun 2, 2006, 10:21:03 PM6/2/06
to

Clumping is one useful concept. You categorize rules. Then you have to
worry about the inside of each category, and how the categories relate
to each other; but not how every rule relates to every other rule.

(You can think of "phases" in action processing -- before/during/
after, etc -- as a specific, hardwired form of categorization.)

Another concept is to have more *ways* to declare rules. I might say
"A comes before B, and please consider this new A-B sequence to be the
new B"; or I might say "A comes before B, but the old B is still B."
Those then give two different natural interpretations to the statement
"C comes before B." Of course this is an incomplete concept -- I
haven't explained how to handle these two variations on the "C" rule
-- but it might be *extended* into a useful mechanism.

(By the way, I'm not sure that we *should* rely on an ordering to
disambiguate rules! The natural form of expression would seem to be a
*partial* ordering, which is not the same thing; it's a list of
(implied or expressed) declarations of the form "Rule R1 takes
predecence over rule R2." That's what's in my head when I think about
the game design, at least. But doing something useful with a partial
order is tricky, and the "right answer" may not involve creating a
total order that satisfies it.)

--Z

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

You don't become a tyranny by committing torture. If you plan for torture,
argue in favor of torture, set up legal justifications for torturing
someday, then the moral rot has *already* set in.

vaporware

unread,
Jun 2, 2006, 10:45:27 PM6/2/06
to

No more expensive than writing a before, instead, or after rule, which
are also checked every turn (!)... or the cascade of objectloops, class
tests, and routine calls that happen when you write expressions like "a
random unexplored toy which the player can touch". Inform 7's attitude
seems to be "screw it, it's the year 2006 and we're all running on
GHz-level processors anyway", and I can't entirely disagree.

vw

greg

unread,
Jun 3, 2006, 3:31:54 AM6/3/06
to
Andrew Plotkin wrote:

> Clumping is one useful concept. You categorize rules. Then you have to
> worry about the inside of each category, and how the categories relate
> to each other; but not how every rule relates to every other rule.

Certainly that helps, but as long as the rules belonging
to a clump can be scattered about, the problem is still
there to some extent.

I think the problem still exists whether ordering is
important or not, too. There is *some* algorithm
that decides which rule matches a given situation, and
to simulate that algorithm in your head, you need to
know what rules are in existence.

I fully appreciate the reasons for wanting a rule-based
system, and I mostly agree with them. I can't help
feeling somewhat uncomfortable about it, though.

Techniques for dealing with complexity in programming
mostly involve drawing a box around something, forgetting
about its internals and keeping a concise mental summary
of what it accomplishes. With the rule-based system
and all the before/after/instead type stuff, it seems
we can't do that -- we're always wanting to open up
the box and tinker with its insides. And that requires
keeping detailed knowledge in mind of how the insides
work.

Without such knowledge, it's hard to have confidence
that when you write a "before taking the untouchable
banana" type of rule, that it will catch *all* the
possible ways the banana could get moved. People
seem to have had trouble with this, e.g. the recent
thread about implementing secret doors.

> (By the way, I'm not sure that we *should* rely on an ordering to
> disambiguate rules! The natural form of expression would seem to be a
> *partial* ordering,

Something that's maybe confusing things a bit is
that I think there are really two different kinds of
"ordering" involved.

One is, as you say, an order of precedence for
disambiguating rules with overlapping conditions.
This is implied to some extent by the inheritance
hierarchy of kinds, so that a rule for an apple
takes precedence over a rule for any kind of thing.

The other is a temporal ordering implied by such
statements as "Before doing A, do B", which means
that you do *both* B and A, in that order.

These two orderings get conflated when you have a
statement such as "Before doing A to an apple, do
B to it". This implies both an order of precedence
(apples over things) and an order of execution
(do B, then do whatever you would have done otherwise,
i.e. A).

I'm not sure what this all means, but I thought it
might help untangle some thoughts to keep it in
mind.

--

Greg

ChicagoDave

unread,
Jun 3, 2006, 10:29:59 AM6/3/06
to
> greg wrote:
> Andrew Plotkin wrote:
>
> > Clumping is one useful concept. You categorize rules. Then you have to
> > worry about the inside of each category, and how the categories relate
> > to each other; but not how every rule relates to every other rule.
>
> Certainly that helps, but as long as the rules belonging
> to a clump can be scattered about, the problem is still
> there to some extent.
>
> I think the problem still exists whether ordering is
> important or not, too. There is *some* algorithm
> that decides which rule matches a given situation, and
> to simulate that algorithm in your head, you need to
> know what rules are in existence.
>
> I fully appreciate the reasons for wanting a rule-based
> system, and I mostly agree with them. I can't help
> feeling somewhat uncomfortable about it, though.
>
> Techniques for dealing with complexity in programming
> mostly involve drawing a box around something

This thread has put in mind a few blog entries I've run across recently
about Continuations and about how the stack is a bad thing.
(http://url123.com/dc9zq).

So are the Rulebooks similar to a stack in this case and would it be
better if there were some parallel processing mechanism to order and
process them?

David C.

Andrew Plotkin

unread,
Jun 3, 2006, 11:54:39 AM6/3/06
to
Here, greg <gr...@cosc.canterbury.ac.nz> wrote:
> Andrew Plotkin wrote:
>
> > Clumping is one useful concept. You categorize rules. Then you have to
> > worry about the inside of each category, and how the categories relate
> > to each other; but not how every rule relates to every other rule.
>
> Certainly that helps, but as long as the rules belonging
> to a clump can be scattered about, the problem is still
> there to some extent.
>
> I think the problem still exists whether ordering is
> important or not, too. There is *some* algorithm
> that decides which rule matches a given situation, and
> to simulate that algorithm in your head, you need to
> know what rules are in existence.

You ultimately know, if only because you wrote them all. (I am not
currently considering multi-author rule systems!) But I think it's
possible to design a system where you *usually* don't have to think
about them all.



> Techniques for dealing with complexity in programming
> mostly involve drawing a box around something, forgetting
> about its internals and keeping a concise mental summary
> of what it accomplishes.

Agreed.

> With the rule-based system
> and all the before/after/instead type stuff, it seems
> we can't do that -- we're always wanting to open up
> the box and tinker with its insides.

Disagree; what I find is that I usually *don't* want to, but
occasionally I need to.

The existing I7 setup does this up to a certain point. You don't have
to look at the standard library's rules for taking. You can write a
heavy or magnetic object without doing that. Then one day you find
that you need a hack -- you need to modify one of the standard rules,
so you do that; then you forget about it again.

The reasons I'm not satisfied is that, one, it feels like a hack when
you do that. (Modifying an action is easy: "instead of taking..." But
modifying a rule is not that easy -- despite being notionally just
another "instead of" decision. Should those not be examples of a
general language mechanism?)

Two, it doesn't seem like you can apply N hacks with only N
brainpower. I don't have a case study of this, but there is the fact I
noted earlier, about a rulebook having exactly one "first" or "last"
rule. Similarly, the before/instead/check/carryout/after/report phase
system is great if you have six phases' worth of customization, but it
gets brittle after that. (And if your task is *simpler*, then your
choice is underdetermined, which is confusing.)

Third, the ordering mechanisms that I7 provides are all phrased in
terms of specifics: "The X rule is listed before the Y rule in the Z
rulebook". This certainly covers the case where you need to look at
all the details, but has no provision for what are (hopefully) the
more common, simpler cases.

Basically, I see two different kinds of rule specification in I7:
simple, rigid boxes, or places where you need to open the box and grub
around. This is Unsatisfying Geekery. :)

> > (By the way, I'm not sure that we *should* rely on an ordering to
> > disambiguate rules! The natural form of expression would seem to be a
> > *partial* ordering,
>
> Something that's maybe confusing things a bit is
> that I think there are really two different kinds of
> "ordering" involved.
>
> One is, as you say, an order of precedence for
> disambiguating rules with overlapping conditions.
> This is implied to some extent by the inheritance
> hierarchy of kinds, so that a rule for an apple
> takes precedence over a rule for any kind of thing.
>
> The other is a temporal ordering implied by such
> statements as "Before doing A, do B", which means
> that you do *both* B and A, in that order.

You are entirely right, and I have been keeping both in mind. (One
amusing point is that "A takes precedence over B" for "before" rules
means A is before B; but for "after" rules, it means A is after B. :)

My impulse, which I have not yet found cause to repudiate, is to
declare that "do A before X" is shorthand for "Instead of X, do {A,X}."
And "do A after X" is shorthand for "Instead of X, do {X,A}." Then you
forget about temporal ordering, and design the entire system in terms
of "instead" rules.

na...@natecull.org

unread,
Jun 4, 2006, 1:45:01 AM6/4/06
to
> You ultimately know, if only because you wrote them all. (I am not
> currently considering multi-author rule systems!)

But isn't the multi-author case always the case, even in the simplest
of games? There's always the rules provided by the core library, and
rules provided by extensions, and then the rules provided by the
player.

That's where a large part of this complexity comes from, I think - the
fact that when we write IF we *don't* write all the rules ourselves.
We're always having to deal with / work around a default standard
library which never does *quite* what we want, but does do 90% of what
we need and which is unpleasant enough to code from scratch that we
want to reuse it. Mostly.

Throw out that requirement and the problem becomes trivial, or a lot
more so. One file, no includes. Rules in whatever order the compiler
needs them, because you get to reorder everything in your source file
and can delete/change stuff at will. Cut and paste the default stuff
you want from your previous project, like Infocom did, and hack what's
new.

But we don't work like that anymore. Especially not so in I7 where we
*can't* rip and replace the Standard Rules like we could the Grammar.h.
Or at least, doing so is a lot more problematic and undocumented and
gives much more impression of Voiding The Warranty (tm). And the
sealed-IDE environment system seems to be a favourite. So any rule /
inclusion system would seem to have to cope with this kind of usage
model as an absolute baseline.

Which I guess is what you're saying, but if so I'm not sure I follow
what you mean by 'you wrote them all'.

greg

unread,
Jun 4, 2006, 5:16:19 AM6/4/06
to
na...@natecull.org wrote:

> That's where a large part of this complexity comes from, I think - the
> fact that when we write IF we *don't* write all the rules ourselves.

This is an interesting point. One of the reasons I think
the original ALAN system was so appealing, despite its
limitations, was that it came with *no* standard library
at all. There were a few very general mechanisms built
into the language, and you built everything yourself on
top of that. Having done so, you then had a very good
idea of how it all worked.

I gather that ALAN 3 does come with a library of sorts
now, but I expect it's very much simpler than the likes
of TADS or I6, and could be read very easily to learn
what it does and how.

That's what I think the Standard Rules should be like --
written entirely in I7, and small enough to understand
entirely so that you can be confident about overriding
parts of them.

> One file, no includes. Rules in whatever order the compiler
> needs them, because you get to reorder everything in your source file
> and can delete/change stuff at will. Cut and paste the default stuff
> you want from your previous project, like Infocom did, and hack what's
> new.

Here's an idea: The source is stored as a diff from the
library. But in the IDE, what you see is the result of
applying the diff, with the parts that you've changed
highlighted. You edit as usual, and the diff is maintained
automatically behind the scenes. So you get the benefits
of cut-and-paste programming without the guilt. :-)

--
Greg

Gene Wirchenko

unread,
Jun 4, 2006, 10:30:34 AM6/4/06
to
"vaporware" <jmc...@gmail.com> wrote:

[snip]

>random unexplored toy which the player can touch". Inform 7's attitude
>seems to be "screw it, it's the year 2006 and we're all running on
>GHz-level processors anyway", and I can't entirely disagree.

My system is a 400 MHz box. So I need to upgrade my hardware to
run a text game? That is something new.

Sincerely,

Gene Wirchenko

Computerese Irregular Verb Conjugation:
I have preferences.
You have biases.
He/She has prejudices.

Gene Wirchenko

unread,
Jun 4, 2006, 10:30:34 AM6/4/06
to
stevend...@yahoo.com (Daryl McCullough) wrote:

[snip]

>Something that I've thought about for programming in general,
>and Inform 7 in particular, is this:
>
>There is often a tension between writing code that is
>clear and writing code that is efficient. In some
>cases, the compiler can figure out a faster way to
>do things, but I've wondered whether it would be
>possible to have two separate programming
>declarations, the first giving the intended effect
>in the clearest way possible, and the second giving
>helpful hints about how to do it efficiently. In
>Inform 7, you could do it this way:
>
> Now each perfumizable thing is ....
> (Try caching reverse links.)
>
>The advantage to separating the what from the how
>is that it would make it much easier to recover to
>an inefficient but correct version if a bug is found
>in the more efficient version.

A common saw in the industry is that programmers are often quite
wrong about where the inefficiences are. 1) Unless you test, you
really do not know. 2) Some other change may make your formerly
correct determination wrong (or the vice versa for that matter). 3)
What if your two versions are not identical in effect?

[snip]

Andrew Plotkin

unread,
Jun 4, 2006, 10:50:41 AM6/4/06
to
Here, na...@natecull.org wrote:
> > You ultimately know, if only because you wrote them all. (I am not
> > currently considering multi-author rule systems!)
>
> But isn't the multi-author case always the case, even in the simplest
> of games? There's always the rules provided by the core library, and
> rules provided by extensions, and then the rules provided by the
> player.

I take the point, although there's still one person who decides the
disposition of everything for a given game.

As an author, I want to be able to pull in the standard rules -- or an
extension -- as a "closed box"; I should only have to look at its
workings for exceptional cases. But I *also* want to treat parts of my
*own* code that way. I want to be able to take that toolcase code I
just wrote and encase it in "Spider and Web" (the nonexistent I7
version) and not have to look at its details any more.

That's an unspoken assumption of mine, I think; I want the same
mechanisms for dealing with extension code and (sections of) my own
code. I don't know if Graham took that goal deliberately, but I7
succeeds at it.

In any case, I was including extensions and the standard library as
"not multi-author IF". I'll use a more accurate term next time. :)



> So any rule / inclusion system would seem to have to cope with this
> kind of usage model as an absolute baseline.

Yes.

Mind you, the I7 standard rules need a bit more rearranging before
they allow this *fully* -- see David Fisher's "library messages"
thread.

--Z

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

Bush's biggest lie is his claim that it's okay to disagree with him. As soon as
you *actually* disagree with him, he sadly explains that you're undermining
America, that you're giving comfort to the enemy. That you need to be silent.

Andrew Plotkin

unread,
Jun 4, 2006, 10:55:36 AM6/4/06
to
Here, Gene Wirchenko <ge...@abhost.us> wrote:

> stevend...@yahoo.com (Daryl McCullough) wrote:
>
> >The advantage to separating the what from the how
> >is that it would make it much easier to recover to
> >an inefficient but correct version if a bug is found
> >in the more efficient version.
>
> A common saw in the industry is that programmers are often quite
> wrong about where the inefficiences are. 1) Unless you test, you
> really do not know. 2) Some other change may make your formerly
> correct determination wrong (or the vice versa for that matter). 3)
> What if your two versions are not identical in effect?

Those concerns apply to any decision the author makes when writing his
code. They are not per se a reason to reduce the expressive power of a
language. (Or, in this case, to fail to increase it.)

Kevin Forchione

unread,
Jun 4, 2006, 5:16:05 PM6/4/06
to
"Gene Wirchenko" <ge...@abhost.us> wrote in message
news:vhp5821iefnr6qp2l...@4ax.com...

> My system is a 400 MHz box. So I need to upgrade my hardware to
> run a text game? That is something new.

You're implying that text games are somehow less sophisticated than some
other kind of game? Not anymore. Don't let the word "text" bias you. These
aren't the systems of the 90s... these guys give you (as author) a more
complex game world and parser, but the trade-off is that they need to do a
far greater amount of computation to give you that extra margin of
sophistication than you'd ever have imagined with the older development
systems.

--Kevin


vaporware

unread,
Jun 4, 2006, 8:35:49 PM6/4/06
to
Gene Wirchenko wrote:

> "vaporware" <jmc...@gmail.com> wrote:
> >random unexplored toy which the player can touch". Inform 7's attitude
> >seems to be "screw it, it's the year 2006 and we're all running on
> >GHz-level processors anyway", and I can't entirely disagree.
>
> My system is a 400 MHz box. So I need to upgrade my hardware to
> run a text game? That is something new.

I doubt that running an actor's response rule every turn is going to
make much difference on a 400 MHz box either. I had in mind the antique
systems like C64, Spectrum, and maybe the slower PDAs.

vw

Daryl McCullough

unread,
Jun 4, 2006, 9:39:29 PM6/4/06
to
Gene Wirchenko says...

> A common saw in the industry is that programmers are often quite
>wrong about where the inefficiences are. 1) Unless you test, you
>really do not know. 2) Some other change may make your formerly
>correct determination wrong (or the vice versa for that matter).

I think that's an argument in favor of trying to get the code
correct, rather than worrying about making it efficient. The
"efficient" version will likely be more complicated, harder
maintain, buggier, and it may very well not be significantly
more efficient, either.

>3) What if your two versions are not identical in effect?

Chances are, they *aren't* identical, which is the reason that
it's nice to have a manifestly correct (if inefficient) version
to fall back on.

--
Daryl McCullough
Ithaca, NY

Gene Wirchenko

unread,
Jun 5, 2006, 2:06:42 AM6/5/06
to
stevend...@yahoo.com (Daryl McCullough) wrote:

>Gene Wirchenko says...
>
>> A common saw in the industry is that programmers are often quite
>>wrong about where the inefficiences are. 1) Unless you test, you
>>really do not know. 2) Some other change may make your formerly
>>correct determination wrong (or the vice versa for that matter).
>
>I think that's an argument in favor of trying to get the code
>correct, rather than worrying about making it efficient. The

Yes.

>"efficient" version will likely be more complicated, harder
>maintain, buggier, and it may very well not be significantly

Usually so, but sometimes, a better algorithm is simpler. You
might only figure it out the second time around.

>more efficient, either.

That is why you test.

>>3) What if your two versions are not identical in effect?
>
>Chances are, they *aren't* identical, which is the reason that
>it's nice to have a manifestly correct (if inefficient) version
>to fall back on.

Exactly. Write the code in a straightforward manner. If you
find *then* that you need it to be faster, *then* (and only then) look
at optimisations. Test to be sure they are optimisations.

Sincerely,

Gene Wrichenko

Neil Cerutti

unread,
Jun 5, 2006, 8:30:10 AM6/5/06
to
On 2006-06-03, greg <gr...@cosc.canterbury.ac.nz> wrote:
> Andrew Plotkin wrote:
>> Clumping is one useful concept. You categorize rules. Then you
>> have to worry about the inside of each category, and how the
>> categories relate to each other; but not how every rule
>> relates to every other rule.
>
> Certainly that helps, but as long as the rules belonging
> to a clump can be scattered about, the problem is still
> there to some extent.
>
> I think the problem still exists whether ordering is important
> or not, too. There is *some* algorithm that decides which rule
> matches a given situation, and to simulate that algorithm in
> your head, you need to know what rules are in existence.
>
> I fully appreciate the reasons for wanting a rule-based system,
> and I mostly agree with them. I can't help feeling somewhat
> uncomfortable about it, though.
>
> Techniques for dealing with complexity in programming mostly
> involve drawing a box around something, forgetting about its
> internals and keeping a concise mental summary of what it
> accomplishes. With the rule-based system and all the
> before/after/instead type stuff, it seems we can't do that --
> we're always wanting to open up the box and tinker with its
> insides. And that requires keeping detailed knowledge in mind
> of how the insides work.

But that problem pertains only when rules conflict, which I admit
is the most interesting situation.

Rule-based programming seems to take the opposite view; it seems
to suppose that a sensible simulation will emerge from a bunch of
rules, without the programmer having to understand precisely how
they interact. This has a chance to work since conflicting rules
have a sensible mechanism for resolution.

I agree that conflicting rules that can't be resolved by means of
specificity ought optionaly be an error instead of silently
defaulting to a textual order. I appreciate that this would
likely break the standard rules.

> Without such knowledge, it's hard to have confidence that when
> you write a "before taking the untouchable banana" type of
> rule, that it will catch *all* the possible ways the banana
> could get moved. People seem to have had trouble with this,
> e.g. the recent thread about implementing secret doors.

That problem is an artifact of the action lexicon, not the rules
system for action resolution. In Inform 6, you had to trap both
Take and Remove to prevent the banana from being picked up by the
player.

>> (By the way, I'm not sure that we *should* rely on an ordering
>> to disambiguate rules! The natural form of expression would
>> seem to be a *partial* ordering,
>
> Something that's maybe confusing things a bit is that I think
> there are really two different kinds of "ordering" involved.
>
> One is, as you say, an order of precedence for disambiguating
> rules with overlapping conditions. This is implied to some
> extent by the inheritance hierarchy of kinds, so that a rule
> for an apple takes precedence over a rule for any kind of
> thing.
>
> The other is a temporal ordering implied by such statements as
> "Before doing A, do B", which means that you do *both* B and A,
> in that order.

The phased nature of action resolution actually minimizes the
complexity, I think. I can consider the Before rules for an
action in isolation, without reference to anything else. In other
words, all the other phases of action resolution can potentially
be ignored while I'm working on Before rules.

It's the general rules that seem to create massive complexity.

Before eating ...

is simple. But

Before doing something to something that is held ...

could become quite hard to understand fully. But since the most
general rules are perforce the weakest, complexity is again
minimized.

In order to *fully* understand my own code, I'm likely to need to
put every rule in order of precedence in the source. I'm guessing
this is how the standard rules are put together (I have not fully
checked).

--
Neil Cerutti
Facts are stupid things. --Ronald Reagan

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php

greg

unread,
Jun 5, 2006, 9:25:39 PM6/5/06
to
Neil Cerutti wrote:
> On 2006-06-03, greg <gr...@cosc.canterbury.ac.nz> wrote:
>
> > we're always wanting to open up the box and tinker with its
> > insides. And that requires keeping detailed knowledge in mind
> > of how the insides work.
>
> But that problem pertains only when rules conflict,

My problem is that I don't *know* whether my rules are
going to conflict with existing ones, without knowing
what all the existing rules are.

There seems to be a fundamental conflict here. We're
not satisfied with a predefined library unless everything
in it is open for change. But if everything is open
to change, there's the possibility of accidentally
changing something when you didn't mean to.

Traditional programming systems deal with this problem
by means of namespaces. Entities are grouped into
modules, classes, etc., and you know that stuff of
your own that you define won't override anything
else unless you explicitly say so. And normally you
extend a library by adding stuff around it rather than
tweaking what's inside it.

But in I7, it seems that the normal way of extending
the library is by sticking things into the middle of
it. Maybe it's just a lack of familiarity with the
paradigm, but that makes me nervous.

--
Greg

na...@natecull.org

unread,
Jun 5, 2006, 9:53:14 PM6/5/06
to
greg wrote:

> Traditional programming systems deal with this problem
> by means of namespaces. Entities are grouped into
> modules, classes, etc., and you know that stuff of
> your own that you define won't override anything
> else unless you explicitly say so. And normally you
> extend a library by adding stuff around it rather than
> tweaking what's inside it.
>
> But in I7, it seems that the normal way of extending
> the library is by sticking things into the middle of
> it. Maybe it's just a lack of familiarity with the
> paradigm, but that makes me nervous.

I think that describes the problem well, but I don't think there's any
way of getting around it. Needing to 'stick things into the middle' of
the library is exactly what the problem domain of IF world simulation
is all about. Each game is essentially a completely new universe: very
few assumptions about *anything*, from physics to social interactions,
are likely to hold in 100% of cases.

For example: I find the Inform standard library assumption that 'you
can only talk to something animate' to be mostly unhelpful for me,
since I tend to like science fiction / fantasy universes in which there
is no clear distinction between 'animate' and 'inanimate' objects or
beings. Is HAL 9000 animate? Talkie Toaster? So the first thing I
generally need to do when implementing ask/tell is to completely rip
and replace the whole conversation grammar, because it starts from what
is, for me, a flawed assumption right down at the token-parsing level.
'A conversation partner must be a person' may be correct 'common sense'
for 99% of real-world cases, but storytelling is all about judicious
violations of common sense. Which means *everything* in the world model
- from the parser, semantics, simulation, plot, screen layout - is up
for grabs. This is a problem that, eg, building software to simulate
physical stress loads on bridges possibly doesn't have to deal with,
and where the 'sealed box' software component methodology possibly
works a lot better.

ChicagoDave

unread,
Jun 5, 2006, 11:04:41 PM6/5/06
to

na...@natecull.org wrote:

> greg wrote:
>
> > But in I7, it seems that the normal way of extending
> > the library is by sticking things into the middle of
> > it. Maybe it's just a lack of familiarity with the
> > paradigm, but that makes me nervous.
>
> I think that describes the problem well, but I don't think there's any
> way of getting around it. Needing to 'stick things into the middle' of
> the library is exactly what the problem domain of IF world simulation
> is all about. Each game is essentially a completely new universe: very
> few assumptions about *anything*, from physics to social interactions,
> are likely to hold in 100% of cases.

I've been pondering this whole rules discussion and it seems to me that
we're looking for some artificial means to order the consequences of a
group of rules at execution time. We can order the rules at design time
to our hearts content, but at execution time the rules will do what we
tell them to, not what a concscious entity would do when faced with a
set of rules that don't quite do the right thing. As one of these so
called conscious entities, I might take the set of rules and re-order
them at the last second or I might add a new rule or I might toss the
whole thing out and react completely aside of these rules.

So we're back to how we implement interactive fiction as authors. The
goal is to entertain, move, educate, anger, or make someone laugh out
loud.

The best rules engine in the world isn't going to do that for us. Well,
unless you consider members of Monty Python to be the best rules engine
in the world.

David C.

na...@natecull.org

unread,
Jun 6, 2006, 1:37:05 AM6/6/06
to

> I've been pondering this whole rules discussion and it seems to me that
> we're looking for some artificial means to order the consequences of a
> group of rules at execution time. We can order the rules at design time
> to our hearts content, but at execution time the rules will do what we
> tell them to, not what a concscious entity would do when faced with a
> set of rules that don't quite do the right thing. As one of these so
> called conscious entities, I might take the set of rules and re-order
> them at the last second or I might add a new rule or I might toss the
> whole thing out and react completely aside of these rules.

Right, which is where IF diverges from designing tabletop roleplaying
game scenarios. The 'rules' there can be much more vague and flexible
because a smart Game Master (and creative players) can fill in the gaps
and interpolate on the fly.I imagine a similar thing is true for
scenarios run in MMORPGs where they have live GMs available.

But IF is more of a potted bonsai tree, at least at the moment - we're
still dealing with a fairly simplistic machine doing the actual runtime
work of refereeing. That seems to be one of the defining features of
the genre to me: how much illusion of runtime creativity and
flexibility can you squeeze out of a small machine?


> So we're back to how we implement interactive fiction as authors. The
> goal is to entertain, move, educate, anger, or make someone laugh out
> loud.
>
> The best rules engine in the world isn't going to do that for us.

No, nor should it - but if we don't have any kind of rules engine or
world model simulation layer, we're back at being a CYOA. Or coding up
an entire parser and sim from whole cloth in C. We want somewhere in
between. So the trick is to make the mechanical simulation layer close
enough to the effect that we want to produce that we don't have to
paper too much over with static 'cutscenes' or other diversionary
tricks.

The 'rules' of IF are like, hmm. A bit more solid than tropes and
conventions in other genres. A shared library of props, perhaps, in a
travelling stage show? Elements that keep recurring - and part of the
charm of the genre *is* the recurrance of known elements and the sheer
Victorian-clockwork mechanicality of it - but whose meaning may be
tweaked a little each time they appear.

So we want them be both robust and malleable, and a design for using
and reusing them that minimises the artistic pain to the author. One of
those good aspects, it seems to me, should be fairly easy
*predictability* for the author of what effect changing a given rule
will have. It's all very well having an ultra-smart engine which does
all sorts of spooky AI magic behind the scenes, but if you can't quite
ever figure out how it's going to act, it's going to be hard to
customise it to get exactly the game you want to write.

Kevin Forchione

unread,
Jun 6, 2006, 3:21:33 AM6/6/06
to
"greg" <gr...@cosc.canterbury.ac.nz> wrote in message
news:4ek3sdF...@individual.net...

You've put your finger on what seems to me to be an interesting aspect of
the declaritive programming paradigm -- and perhaps an essential conundrum
of rule-based programming. Using that paradigm you are describing *what* the
world is like, rather than *how* to create it. To quote from Wikipedia,
"imperative programs make the algorithm explicit and leave the goal
implicit, while declarative programs make the goal explicit and leave the
algorithm implicit."

What you're referring to as "traditional" programming is an imperative (and
object-oritented) paradigm. In that model you can do just as you suggest
through inheritance, encapsulation, abstraction, and polymorphism. Through
the use of libraries that encapsulate implementation details, imperative
programming attains a degree of declarative programming style.

That's the psychological flip -- and fundamentally the chief distinction, I
believe, between the flavors of the I7 and TADS approaches. I7, of course,
stresses the elements of declarative programming, while allowing the
programmer to implement to a certain degree, algorithms composing "how" this
is to be done. The TADS 3 approach attains a degree of declarative
programming by use of its library, though almost immediately an author must
resort to explicit programming details within the methods of library class
derivations (and other modifications) in order to provide the uniqueness of
simulation required to make stories drammatically interesting.

It is the ability to access and modify the algorithm(s) that determines the
*how* of the model world that appears to be at issue -- the lack of explicit
control that is causing some anxiety among I7 authors. Of course, the
descent into imperative programming, the necessity to provide implementation
details, appears to muddy the waters and soil the purity of the artistic
creation, but the question is whether such purity can realistically be
achieved in this problem domain.

--Kevin


Neil Cerutti

unread,
Jun 6, 2006, 9:13:34 AM6/6/06
to
On 2006-06-06, greg <gr...@cosc.canterbury.ac.nz> wrote:
> Neil Cerutti wrote:
>> On 2006-06-03, greg <gr...@cosc.canterbury.ac.nz> wrote:
>> > we're always wanting to open up the box and tinker with its
>> > insides. And that requires keeping detailed knowledge in
>> > mind of how the insides work.
>>
>> But that problem pertains only when rules conflict,
>
> My problem is that I don't *know* whether my rules are going to
> conflict with existing ones, without knowing what all the
> existing rules are.

Perhaps a conceptual leap of faith is required here.

A non-rules-based approach doesn't shield you from the
complexity, either.

Here's the Check rules for a pouring into action I'm working on
in I7:

Pouring it into is an action applying to two things.

Understand "pour [something] into/in/down/through [something]" as pouring it into.

Understand the commands "spill" and "dump" as "pour".

Check pouring into (this is the reroute to contained liquids rule): if the noun contains liquid begin;
let child be the first thing held by the noun;
say "(pouring [the child] into [the second noun])";
try pouring the child into the second noun instead;
end if.

Check pouring into (this is the non-liquid rule): if the noun is not a liquid, say "You can pour only liquids." instead.

Check pouring into (this is the reroute to drinking rule): if the second noun is the player begin;
say "(drinking [the noun])"; try drinking the noun instead;
end if.

Check pouring into (this is the into itself rule): if the noun is the second noun, say "Nothing happens." instead.

[Snipped another 5 for so rules]

Converting these rules back into I6 requires *manually* placing
them in a a logical order, and placing them all in PourIntoSub.

I can create an immutable Check rule duplicating the
functionality of the start of an I6 action subroutine:

Check pouring into (this is the all-encompassing rule):
if the noun contains a liquid begin;
let child be the first thing held by the noun;
say "(pouring [the child] into [the second noun].";
try pouring the child into the second noun instead;
end if;
if the noun is not a liquid, say "You can pour only liquids." instead;
if the second noun is the player begin;
say "(drinking [the noun])";
try drinking the noun instead;
end if;
[ Etc... ]

Which version is better?

> There seems to be a fundamental conflict here. We're not
> satisfied with a predefined library unless everything in it is
> open for change. But if everything is open to change, there's
> the possibility of accidentally changing something when you
> didn't mean to.

I don't agree. You might accidentally break something, or cause a
situation you didn't anticipate, but you cannot change the way an
object will behave without meaning to.

> Traditional programming systems deal with this problem by means
> of namespaces. Entities are grouped into modules, classes,
> etc., and you know that stuff of your own that you define won't
> override anything else unless you explicitly say so. And
> normally you extend a library by adding stuff around it rather
> than tweaking what's inside it.
>
> But in I7, it seems that the normal way of extending the
> library is by sticking things into the middle of it. Maybe it's
> just a lack of familiarity with the paradigm, but that makes me
> nervous.

You will only rarely sticking things into the library. Before,
Instead, and After are your main tools.

--
Neil Cerutti
I've had a wonderful evening, but this wasn't it. --Groucho Marx

Andrew Plotkin

unread,
Jun 6, 2006, 2:24:42 PM6/6/06
to
Here, greg <gr...@cosc.canterbury.ac.nz> wrote:
> Neil Cerutti wrote:
> > On 2006-06-03, greg <gr...@cosc.canterbury.ac.nz> wrote:
> >
> > > we're always wanting to open up the box and tinker with its
> > > insides. And that requires keeping detailed knowledge in mind
> > > of how the insides work.
> >
> > But that problem pertains only when rules conflict,
>
> My problem is that I don't *know* whether my rules are
> going to conflict with existing ones, without knowing
> what all the existing rules are.

I note that the compiler is in an excellent position to *discover*
conflicts. It can then either ask the author for a resolution, or
resolve the conflict itself and report what it did.

I7 does a good job of the latter -- after compiling, you can look at
the list of rules for an action and see what order they're in. It does
not try to do the former.

(This design certainly has advantages. A compiler which asked you
about every conflict might wind up drowning you in a never-ending
series of conflict reports.)

--Z

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

If the Bush administration hasn't thrown you in military prison without trial,
it's for one reason: they don't feel like it. Not because you're patriotic.

Mark Norton

unread,
Jun 6, 2006, 3:06:51 PM6/6/06
to
Andrew Plotkin wrote:
> I note that the compiler is in an excellent position to *discover*
> conflicts. It can then either ask the author for a resolution, or
> resolve the conflict itself and report what it did.
>
> I7 does a good job of the latter -- after compiling, you can look at
> the list of rules for an action and see what order they're in. It does
> not try to do the former.
>
> (This design certainly has advantages. A compiler which asked you
> about every conflict might wind up drowning you in a never-ending
> series of conflict reports.)

This is not unlike programming in a hardware description language. A
hardware description language, like VHDL and Verilog, takes the source
files and synthesizes the abstract concepts into physical objects (or
what will eventually become physical objects or physical configuration).
A fundamental part of coding hardware is to look at the synthesis
report very closely and make certain that it decided to do what you
desired with your code. If it didn't, you might have to change the
coding structure somewhat.

Perhaps I7 could create a report of the actions its taking with rules
would be useful. Maybe it does this already, I'm still taking baby
steps through the process :)

Best regards,
Mark Norton

--
==============================
Mark Norton <ma...@cdvinc.com>
Concept Development, Inc.
Irvine, CA, USA

greg

unread,
Jun 6, 2006, 9:36:35 PM6/6/06
to
Mark Norton wrote:

> A fundamental part of coding hardware is to look at the synthesis
> report very closely and make certain that it decided to do what you
> desired with your code. If it didn't, you might have to change the
> coding structure somewhat.

I'm not familiar with that kind of coding, but if that's
really what you have to do, it sounds like there's something
very badly wrong with the design of the language and/or
compiling technology.

If you have a C program that produces compiler warnings,
you don't put up with having to read through them every
time and decide whether there are any real problems.
Instead, you rewrite the code so that it compiles
silently.

--
Greg

na...@natecull.org

unread,
Jun 6, 2006, 10:48:57 PM6/6/06
to
greg wrote:
> If you have a C program that produces compiler warnings,
> you don't put up with having to read through them every
> time and decide whether there are any real problems.
> Instead, you rewrite the code so that it compiles
> silently.

*Cough* Yes, and if every major open-source program I've recompiled
from source produced no gcc warnings, I have a nice large bridge you
might be interested in.

Also Inform 6 produces an amusing collection of warnings if, for
instance, you have the temerity to include a library and then *gasp*
not actually call every single one of its functions!

greg

unread,
Jun 7, 2006, 12:36:55 AM6/7/06
to
na...@natecull.org wrote:

> *Cough* Yes, and if every major open-source program I've recompiled
> from source produced no gcc warnings, I have a nice large bridge you
> might be interested in.

All that shows is that people aren't perfect. I'm
not saying that no C program produces warnings, only
that it's good practice to strive to eliminate them.

If a particular compiler made it *impossible* to
remove certain kinds of warning by correcting the
code, I would consider that compiler broken.

> Also Inform 6 produces an amusing collection of warnings if, for
> instance, you have the temerity to include a library and then *gasp*
> not actually call every single one of its functions!

Really? That *does* sound broken...

--
Greg

Alexandre Owen Muniz

unread,
Jun 7, 2006, 1:38:45 AM6/7/06
to
greg wrote:
> na...@natecull.org wrote:

>> Also Inform 6 produces an amusing collection of warnings if, for
>> instance, you have the temerity to include a library and then *gasp*
>> not actually call every single one of its functions!
>
>
> Really? That *does* sound broken...

No, not really. Putting the "System_File;" directive at the top of your
Inform 6 library causes those to be suppressed.

Owen

Michael Martin

unread,
Jun 7, 2006, 7:39:41 PM6/7/06
to

He's talking here about doing the Inform-7 equivalent of checking the
index. Back when I was an undergrad, we did logic design on Xilinx
boards. Optimal hardware compilation, if I remember correctly, takes
exponential time, so randomized algorithms are used. It was not at all
uncommon for projects nearing the limits of the board's representation
capacity to need to try to compile several times before it came upon a
solution that fit.

The closest parallel I can think of is the initialization of global or
static objects in C++, and in that world, this is solved by claiming
that making assumptions about initialization order is an error. (And
an unchecked one, at that, at least the last time I saw someone bit by
it by g++.) There are easy enough workarounds for these, of course.
It's a bit messier when you've got a set of rules that need to have a
partial order placed on them, and so, as I7 puts a *total* order on
them, it's sensible to check that the total order it selected was
correct. If it's not, then that means you have a semantic bug relating
to rule ordering.

--Michael

Mark Norton

unread,
Jun 8, 2006, 1:47:43 PM6/8/06
to
greg wrote:
> Mark Norton wrote:
>
>> A fundamental part of coding hardware is to look at the synthesis
>> report very closely and make certain that it decided to do what you
>> desired with your code. If it didn't, you might have to change the
>> coding structure somewhat.
>
> I'm not familiar with that kind of coding, but if that's
> really what you have to do, it sounds like there's something
> very badly wrong with the design of the language and/or
> compiling technology.

Well, Michael Martin answered to some degree below, but I thought I
would elaborate here.

The problem is that it is not really compilation. Compilation is simply
taking the code and condensing it into the machine instructions. The
instructions are really similar to the original code in structure, just
elaborated somewhat. With VHDL/Verilog, it's not compiling, it's
synthesizing a completely different structure (wires, gates, flops) that
have to work concurrently as well as sequentially (i.e. there are parts
of the code that execute simultaneously in the time domain, it's NOT
just one-thing-after-another). Take a basic selection process as an
example.

Suppose I have to select from 4 things. I could do something like this:
if (a = 1) then
-- a things
elsif (a = 2) then
-- b things
elsif (a = 3) then
-- c things
... etc. you get the idea.

Or I could do this:

case a is
when 1 => -- a things
when 2 => -- b things
when 3 => -- c things
when 4 => -- d things
end case

In C, these would be pretty much synonymous. Performing actions based
on a selection. However in the hardware world, these can be very
different. The case statement will produce a multiplexer. The if/then
structure might produce a priority encoder. In hardware, these are
significantly different constructs.

So, it's very important to make certain the synthesizer did what you
wanted it to do. Creation of hardware logic blocks abstracted through a
language interface (as opposed to using a schematic and plunking down an
OR gate here or a flip-flop there) seems to me to be similar in a lot of
aspects to creation of z-machine objects abstracted even further from
the underlying level through the natural language. With each level of
abstraction, you are removed from the physical act of putting things
where you want to, so you have to manage things when these things are
created and make sure they get put in the way you wanted them.

So, it's not really that there is something badly wrong with the
language or the compiler, it's that it's trying to do something that is
much more difficult than compiling instructions into machine code and
the technology isn't perfect.

> If you have a C program that produces compiler warnings,
> you don't put up with having to read through them every
> time and decide whether there are any real problems.
> Instead, you rewrite the code so that it compiles
> silently.

For small programs, certainly. For large projects that go through
iterations of design, this is problematic when there is a budget
involved. Our current project (custom image processing on a FPGA chip)
currently takes about 2 hours to build every time there is a change
made. As long as we know what the warnings are referring to, it is not
worthwhile to clean up every last one of them if the design functionally
works. No warnings is a "nice-to-have" but not a necessity.

Anyhow, this is straying a bit far afield so I'll hush up about hardware
coding now. Just was very interested in the analogs to the natural
language object/rule creation into z-machine objects.

greg

unread,
Jun 10, 2006, 6:21:12 AM6/10/06
to
Mark Norton wrote:
> The case statement will produce a multiplexer. The if/then
> structure might produce a priority encoder. In hardware, these are
> significantly different constructs.
>
> So, it's very important to make certain the synthesizer did what you
> wanted it to do.

My problem with that is if you know what you want,
why doesn't the language let you *say* what you want
in the first place? Instead of having to let it
guess, and then check whether it guessed right.

My impression of these hardware languages is that
they take constructs designed for conventional
programming (if/then/else, switch, etc.) and try
to apply them inappropriately to a completely
different problem.

[Suggestion for a new hardware language, in
a heroic but doomed attempt to bring this back
on topic:

Rule for deciding on the output of the adder
when the clock goes from low to high:
Input1 Input2 Output Carry
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1

:-) ]

--
Greg

Gene Wirchenko

unread,
Jun 10, 2006, 10:08:12 AM6/10/06
to
na...@natecull.org wrote:

[snip]

>For example: I find the Inform standard library assumption that 'you
>can only talk to something animate' to be mostly unhelpful for me,
>since I tend to like science fiction / fantasy universes in which there
>is no clear distinction between 'animate' and 'inanimate' objects or
>beings. Is HAL 9000 animate? Talkie Toaster? So the first thing I
>generally need to do when implementing ask/tell is to completely rip
>and replace the whole conversation grammar, because it starts from what
>is, for me, a flawed assumption right down at the token-parsing level.

"Listen, you idiot computer! I want the player to be able to
talk to inanimate objects like idiot computers!"
"I'm sorry. I can't do that, Dave."
<yank><yank> [crude attitude adjustment]
The computer says nothing in return.

[snip]

Sincerely,

Gene Wirchenko

Andrew Plotkin

unread,
Jun 10, 2006, 10:53:28 AM6/10/06
to
Here, greg <gr...@cosc.canterbury.ac.nz> wrote:
> Mark Norton wrote:
> > The case statement will produce a multiplexer. The if/then
> > structure might produce a priority encoder. In hardware, these are
> > significantly different constructs.
> >
> > So, it's very important to make certain the synthesizer did what you
> > wanted it to do.
>
> My problem with that is if you know what you want,
> why doesn't the language let you *say* what you want
> in the first place? Instead of having to let it
> guess, and then check whether it guessed right.

Because we're talking (in both I7 and hardware-design languages) about
very high-level languages, where the author's description uses a very
different model from the final product.

It's easy to be spoiled (or "ruined") by languages like C or Basic (or
most of Inform 6), where the language is a thin veneer over the final
operation. You can map C statements to machine-language operations in
a direct and mechanical. The compiler is doing very simplistic work;
perhaps work with a lot of detail, like remembering lots of symbols or
keeping track of heirarchies of statements, but essentially dumb
algorithms.

This model is great if you are willing to think like a CPU. But it
starts to break down even in not-very-high-level languages like C++.
Consider the rules for dispatching methods in a multiple-inheritance
class tree, or automatic type conversion. The language spec has long
and complicated rules for how this stuff works -- precisely because
the author is specifying a high-level description which has no simple
mapping to machine language. You have to either (A) memorize a lot of
fiddly rules, or (B) write some code and see if it compiles to the
behavior you want.

(The same is true of I6's action dispatching system, although that's
complex runtime behavior rather than compile-time. The rules for
orders/before/after/etc are very fiddly. Why? Because they're trying
to provide a high-level model for specifying how world customizations
interact. I7 has a different model, which is better. I think even
better models exist -- but they will be better because they're more
flexible and easier to manipulate, *not* because they're simplistic
and mechanical.)

You gave a joking example of a "NL" hardware description language, but
it is in fact the answer to your question. Why doesn't the hardware
language let you specify every output bit for the various inputs?
Because that would be horribly tedious, and you'd never finish
designing a four-function calculator, much less a Z-machine. You
need the "inappropriate" high-level descriptions as basic working
tools.

--Z

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

It used to be that "conservatives" were in favor of smaller government,
fiscal responsibility, and tighter constraints on the Man's ability to
monitor you, arrest you, and control your life.

Mark Norton

unread,
Jun 10, 2006, 3:54:16 PM6/10/06
to
greg wrote:
> Mark Norton wrote:
>> The case statement will produce a multiplexer. The if/then
>> structure might produce a priority encoder. In hardware, these are
>> significantly different constructs.
>>
>> So, it's very important to make certain the synthesizer did what you
>> wanted it to do.
>
> My problem with that is if you know what you want,
> why doesn't the language let you *say* what you want
> in the first place? Instead of having to let it
> guess, and then check whether it guessed right.

Well you certainly CAN do this. There are schematic editors for
programmable logic, and you can plunk down blocks that you know EXACTLY
how it works.

The trouble (from personal experience) is that it doesn't scale.
Imagine being the next guy on a project after the first one got hit by a
bus. They hand you a set of schematics that runs upwards of *70* pages
(I am not making this up, this happened to me). The design had gotten
so big and so complex that the schematic version was a nightmare, where
a code version would have been probably 12-20 pages and probably commented.

The other thing to note in what you said was, "say what you want in the
first place". This is all well and good for individual flipflops, but
what about a multiplyer? That's a pretty complex construct. What I
want to say is "I want a 16 bit by 16 bit multiplyer with a 32 bit
output." (which you can do with the hardware design logic). What I do
*not* want to describe is the oodles of xor gates and all the carry
permutations. It's a nasty experience for me, and it's a nasty
experience for the next guy after I get hit by a bus.

> My impression of these hardware languages is that
> they take constructs designed for conventional
> programming (if/then/else, switch, etc.) and try
> to apply them inappropriately to a completely
> different problem.

Not completely different, but yes, it's not just machine code.

> [Suggestion for a new hardware language, in
> a heroic but doomed attempt to bring this back
> on topic:
>
> Rule for deciding on the output of the adder
> when the clock goes from low to high:
> Input1 Input2 Output Carry
> 0 0 0 0
> 0 1 1 0
> 1 0 1 0
> 1 1 0 1

Well, it comes back to what you want to say. I would argue you do NOT
want to say this. What you really WANT to say is:

c <= a + b

If you have to say it the other way, it's a tedious effort (albeit
potentially more accurate the first time around).

Fortunately the language synthesizers have gotten very good at figuring
out the hardware description languages and what should be created out of
various constructs. They are simply imperfect, so you have to keep an
eye on them.

In same way, Inform 7 is trying to achieve this for interactive fiction.

Hope this helps.

Best regards,
Mark Norton

greg

unread,
Jun 10, 2006, 9:23:45 PM6/10/06
to
Andrew Plotkin wrote:

> Because we're talking (in both I7 and hardware-design languages) about
> very high-level languages, where the author's description uses a very
> different model from the final product.

That makes no difference. If I'm using a high-level model,
I should be able to reason about the system in terms of
that model alone. If I have to think about what it
corresponds to at a lower level, I consider that a
*failure* of either the language or its implementation.

> This model is great if you are willing to think like a CPU. But it
> starts to break down even in not-very-high-level languages like C++.
> Consider the rules for dispatching methods in a multiple-inheritance
> class tree,

I tend to avoid using multiple inheritance in a way
that tangles up the method dispatching, precisely because
it makes it hard to reason about the behaviour. I would
actually prefer the language to have *simpler* rules
that made it impossible to get yourself into the trickier
situations.

> You have to either (A) memorize a lot of
> fiddly rules, or (B) write some code and see if it compiles to the
> behavior you want.

I don't believe that a high-level abstraction needs to
have complicated rules. If the rules are so complicated
that a human can't keep them in his head, then the
abstraction is of little use, IMO, regardless of how
high-level it is.

> Why doesn't the hardware
> language let you specify every output bit for the various inputs?

> Because that would be horribly tedious... You


> need the "inappropriate" high-level descriptions as basic working
> tools.

But I don't agree that "if-else" and "switch" are higher
level than "priority encoder" and "multiplexer" -- it
seems to me that they're actually *lower* level abstractions,
which the compiler his having to heuristically convert up
to a higher level, and then down again to gates.

In any case, they're not the abstractions that the hardware
designer really wants to think in. If he knows he wants
a multiplexer, then he's thinking in terms of multiplexers,
not switch statements. So why not let him write 'multiplexer'
instead of 'switch'?

--
Greg

greg

unread,
Jun 10, 2006, 9:31:27 PM6/10/06
to
Mark Norton wrote:

> Well you certainly CAN do this. There are schematic editors for
> programmable logic, and you can plunk down blocks that you know EXACTLY
> how it works.

> What I want to say is "I want a 16 bit by 16 bit multiplyer with a 32 bit
> output."

Seems to me you should be able to write more or
less exactly that in a textual language just as
well as in a graphical one.

--
Greg

Richard Bos

unread,
Jun 12, 2006, 6:19:48 PM6/12/06
to
"vaporware" <jmc...@gmail.com> wrote:

> Richard Bos wrote:
> > Possibly, but wouldn't that be horrendously expensive? Having a rule
> > checked every turn just for what is basically a react_after... ugh.
>
> No more expensive than writing a before, instead, or after rule, which
> are also checked every turn (!)... or the cascade of objectloops, class
> tests, and routine calls that happen when you write expressions like "a


> random unexplored toy which the player can touch". Inform 7's attitude
> seems to be "screw it, it's the year 2006 and we're all running on
> GHz-level processors anyway", and I can't entirely disagree.

I can. I still play IF on a hand-held, and on a pretty old Win98 box.

Richard

Richard Bos

unread,
Jun 12, 2006, 6:19:50 PM6/12/06
to
"Kevin Forchione" <ke...@lysseus.com> wrote:

> "Gene Wirchenko" <ge...@abhost.us> wrote in message
> news:vhp5821iefnr6qp2l...@4ax.com...


> > My system is a 400 MHz box. So I need to upgrade my hardware to
> > run a text game? That is something new.
>

> You're implying that text games are somehow less sophisticated than some
> other kind of game?

No, he's implying that textual sophistication should need less
processing power than graphical muscle-work. And he's not wrong.

Richard

Xub...@gmail.com

unread,
Jun 12, 2006, 7:57:43 PM6/12/06
to
I am less certain of that than you appear to be.
To me, at least, it is not immediately apparent that the processing
horsepower required to create a textual description of a fictional
setting, *must necessarily* be of a lesser magnitude than the
processing horsepower required to create, say, 3D animation in
realtime. If *all* you're doing is spitting out pre-recorded
descriptions in response to specific pre-defined character strings,
then sure, the text game needs virtually no clock cycles. BFD. The
thing is, what happens when you add in a world model, and a parser to
translate the player's input into instructions which affect that world
model, and an output module which generates a textual description of
the new state of the world model, and..?
Text games, just like any other kind of games, can suck up an
arbitrarily large amount of processing horsepower...

Andrew Plotkin

unread,
Jun 13, 2006, 11:18:10 PM6/13/06
to
Here, greg <gr...@cosc.canterbury.ac.nz> wrote:
> Andrew Plotkin wrote:
>
> > Because we're talking (in both I7 and hardware-design languages) about
> > very high-level languages, where the author's description uses a very
> > different model from the final product.
>
> That makes no difference. If I'm using a high-level model,
> I should be able to reason about the system in terms of
> that model alone. If I have to think about what it
> corresponds to at a lower level, I consider that a
> *failure* of either the language or its implementation.

I don't think I'm talking about a "lower level" in the sense you're
imagining. It's not a matter of looking at the assembly output of a C
compiler to check for errors. (Nor the I6 output of the I7 compiler.)

I'm talking about languages where the compiler is doing a lot of
reasoning about the author's specification. In other words, where it's
*a lot of work* to turn the high-level description into a final
product. If it were easy to do, that would be a low-level language by
definition.


> > This model is great if you are willing to think like a CPU. But it
> > starts to break down even in not-very-high-level languages like C++.
> > Consider the rules for dispatching methods in a multiple-inheritance
> > class tree,
>
> I tend to avoid using multiple inheritance in a way
> that tangles up the method dispatching, precisely because
> it makes it hard to reason about the behaviour.

It may be that you don't *want* to work in a rule-based or logical
language. I am only arguing that *I* want to. :)

Let me pull an arbitrary example out of my ear. (I will be using
I7-ish syntax here, for familiarity, but the deductions here are
beyond the (current) capabilities of I7.)

An animal is a kind of thing. An animal can be widespread or extinct.
A mammal is a kind of animal. A reptile is a kind of animal. A bird is
a kind of animal.

To zork when X is an animal: [do A]
To zork when X is a mammal: [do B]
To zork when X is a reptile or X is extinct: [do C]
To zork when X is a mammal and X is extinct: [do D]
To zork when X is a bird and X is widespread: [do E]
To zork when X is extinct: [do F]

This may look like an odd assortment of conditions, but stuff like
this does come up in IF[*]. They would probably have been written at
different times, in different parts of the code.

Now, you can sketch some Venn diagrams (in fact, I just did) and
decide that these statements form an unambiguous hierarchy of logical
narrowness. Rule A is the most general; B is a subcase of A (and is
therefore considered an exception to it); D is a subcase of B, and
also of F; etc.

But I don't actually *want* to sketch that diagram. I (notionally)
came up with each rule because it made sense in the context of some
part of the game. If they conflict, it's probably in some obscure
concatenation of circumstances which I didn't consider. And I want the
*compiler* to figure that crap out. Why should I do the work? I should
be able to throw my ideas into the compiler, and then look at the
structure of the result and decide if it's right.

In this case, there's no guessing to be done, so the compiler will not
surprise me. But it may earn its penny by pointing out that rule A can
never happen. Did I notice that? Maybe I did, and rule A is a no-op,
or a placeholder from earlier in development. Maybe I didn't, in which
case I may rethink the code that was in rule A. But it's not a matter
of a "compiler warning" which must be attended to; it's information
about the system which the compiler is presenting to me.

So then, a month later, I say to myself -- fish! I need fish in my
game![**] So I add:

A fish is a kind of animal.
To zork when X is a fish: [do G]

Now the situation is no longer unambiguous. If X is an extinct fish,
should zorking follow rule F or rule G? Neither is clearly an
exception to the other.

So, depending on the language model, the compiler will either query me
for a decision, or decide for me. (I7 decides based on which rule
appears first in the source.) Which it does is not important here. The
point is that I will be looking at the compiler's output information
to discover these things.

[* For example, the standard Inform model of darkness could be
expressed as: "When the room is dark and (the action is examining or
the action is looking): say 'It's too dark to see.' And so on.
Although I7 does not in fact implement darkness with simple rules --
it uses the I6 legacy implementation, which I think is a pity.]

[** Happens more often than you might think. Come to think of it, my
old fish-game idea might be really easy in I7...]

Don't confuse the analogy here. The significance of hardware-design
languages here is not whether they're textual or graphical. It's the
large amount of processing that goes on between the author's
specification and the final design.

--Z

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

If the Bush administration hasn't subjected you to searches without a
warrant, it's for one reason: they don't feel like it. Not because of
the Fourth Amendment.

greg

unread,
Jun 14, 2006, 6:45:06 AM6/14/06
to
Andrew Plotkin wrote:

> So, depending on the language model, the compiler will either query me
> for a decision, or decide for me.

I'd much rather have it stop and complain, so I can
revise the source to remove the ambiguity. Then I
never have to deal with that particular piece of
compiler output again.

> Don't confuse the analogy here. The significance of hardware-design
> languages here is not whether they're textual or graphical. It's the
> large amount of processing that goes on between the author's
> specification and the final design.

All I was saying is that if the designer is *thinking*
in terms of multiplexers, it would seem to make sense
to use a language in which multiplexers are an explicit
construct. That language could be either textual or
graphical.

But the whole hardware language discussion has just
been an off-topic side issue, really. I never meant
to draw any analogies between that and I7.

--
Greg

Andrew Plotkin

unread,
Jun 14, 2006, 10:02:32 AM6/14/06
to
Here, greg <gr...@cosc.canterbury.ac.nz> wrote:
> Andrew Plotkin wrote:
>
> > So, depending on the language model, the compiler will either query me
> > for a decision, or decide for me.
>
> I'd much rather have it stop and complain, so I can
> revise the source to remove the ambiguity. Then I
> never have to deal with that particular piece of
> compiler output again.

I agree, tentatively. But until I've worked with a full-scale IF
system built that way, I'm not going to say it's definitively better.
It's possible that "normal" IF coding (combined with a standard
library) would produce so many queries that it wouldn't be worth
using. If that's so, then you'd want to change to a model where the
system used a heuristic that was right most of the time.

Also, the "query" model trades off a piece of compiler output that you
never have to look at again, for a line of code that you *will* have
to keep looking at. It's not obvious which is the greater burden on
the author.

In any case, the distinction is -- as I noted -- tangential to my
point.

--Z

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

You don't become a tyranny by committing torture. If you plan for torture,
argue in favor of torture, set up legal justifications for torturing
someday, then the moral rot has *already* set in.

Kevin Forchione

unread,
Jun 14, 2006, 3:33:05 PM6/14/06
to
"Richard Bos" <ral...@xs4all.nl> wrote in message
news:448de148...@news.xs4all.nl...

Perhaps that's what he's implying. The statement is true. But it's also true
that if you're running the new versions of text based game systems you're
going to benefit from a faster machine.

--Kevin


Kevin Forchione

unread,
Jun 14, 2006, 3:41:41 PM6/14/06
to
<Xub...@gmail.com> wrote in message
news:1150156663....@h76g2000cwa.googlegroups.com...

Well, the real issue is that in a realtime game you have a much larger
compuational window that you do in a text based game cycle. If response time
were not an issue then the processing speed wouldn't matter, but you have a
window of some dozen milliseconds within which to perform all of the
processing that you state above. A graphics game, especially a realtime one,
is updating game state regardless of whether the player is inputing a
command. or not. Now if it were a "level playing field" you'd have to
estimate what kind of machine you'd need for graphics games if they did all
their computation within a few dozen milliseconds of the mouse-click.

--Kevin


Neil Cerutti

unread,
Jun 15, 2006, 9:45:36 AM6/15/06
to

Part of the problem is that there are fancy $300 boards and huge
libraries designed by geniuses to help authors pump out 3D
graphics. For processing a whole lot of English text, there's
no such support. We've got the few IF design system that are
available and current. If folks could purchase a MSI Zip board
for there computer, things might be different. ;)

--
Neil Cerutti
Remember in prayer the many who are sick of our church and
community. --Church Bulletin Blooper

Andrew Plotkin

unread,
Jun 15, 2006, 10:33:34 AM6/15/06
to
Here, Neil Cerutti <lead...@email.com> wrote:
> On 2006-06-14, Kevin Forchione <ke...@lysseus.com> wrote:
> > "Richard Bos" <ral...@xs4all.nl> wrote in message
> > news:448de148...@news.xs4all.nl...
> >> "Kevin Forchione" <ke...@lysseus.com> wrote:
> >>
> >>> "Gene Wirchenko" <ge...@abhost.us> wrote in message
> >>> news:vhp5821iefnr6qp2l...@4ax.com...
> >>> > My system is a 400 MHz box. So I need to upgrade my hardware to
> >>> > run a text game? That is something new.
> >>>
> >>> You're implying that text games are somehow less sophisticated than some
> >>> other kind of game?
> >>
> >> No, he's implying that textual sophistication should need less
> >> processing power than graphical muscle-work. And he's not wrong.
> >
> > Perhaps that's what he's implying. The statement is true. But
> > it's also true that if you're running the new versions of text
> > based game systems you're going to benefit from a faster
> > machine.
>
> Part of the problem is that there are fancy $300 boards and huge
> libraries designed by geniuses to help authors pump out 3D
> graphics. For processing a whole lot of English text, there's
> no such support. We've got the few IF design system that are
> available and current. If folks could purchase a MSI Zip board
> for there computer, things might be different. ;)

The increasing CPU cost (from Zil to I5 to I6 to I7) has almost
nothing to do with text processing. It's the increasing sophistication
of the world model and game logic: flexibility of scoping, flexibility
of actions, and now the rule model.

It's true that this stuff has no direct analog in current 3D games.
But I can imagine non-text-parser games that could make use of it.
Nethack, for example, has a vast and complicated library of magical
effects, which interact with each other and with the environment. I'd
think that rule-based programming would be ideal for that.

The same could go for graphical RPGs, for that matter. Nearly all
spells and superpowers in current MMORPGs are simple stat buffs and
effects; they combine linearly, if they combine at all. Imagine
designing such a game with complex spell interactions and side
effects.

--Z

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

If the Bush administration hasn't thrown you in military prison without trial,

it's for one reason: they don't feel like it. Not because you're patriotic.

Michael Martin

unread,
Jun 15, 2006, 7:21:08 PM6/15/06
to
Andrew Plotkin wrote:
> The same could go for graphical RPGs, for that matter. Nearly all
> spells and superpowers in current MMORPGs are simple stat buffs and
> effects; they combine linearly, if they combine at all. Imagine
> designing such a game with complex spell interactions and side
> effects.

I try, but I mostly imagine the outraged cries of
"zomgoverpowerednerfplz" from every corner of that genre's fandom.

I haven't played any of the graphical RPGs seriously intended to be
open-ended, such as Oblivion -- I suppose it might work better with
those.

--Michael

Gene Wirchenko

unread,
Jul 30, 2006, 5:37:01 PM7/30/06
to
"Kevin Forchione" <ke...@lysseus.com> wrote:

Let me make it more explicit then. If a 400 MHz box is not
sufficient to run a text game, I am highly suspicious that the game is
very inefficient.

0 new messages