Z-machine/ VM design question

29 views
Skip to first unread message

Nathan Jerpe

unread,
Oct 12, 2005, 2:31:15 PM10/12/05
to
Just started to do some tinkering....

I guess the first question is the devil's advocate's one...why use a virtual
machine in the first place? If you want portability, can't you just write
yourself an OS abstraction layer? What exactly is the VM buying you that
justifies this complexity?

Secondly, why is the Z-machine designed (and I can only assume, the Glulx
model as well) to keep the stack outside of main memory and the global
variables inside of main memory? What is so different about a virtual
machine that would encourage it to exhibit the opposite structure of a real
one (Z-80, etc)?

Just trying to understand things a little better,
Nathan


Andrew Plotkin

unread,
Oct 12, 2005, 3:35:19 PM10/12/05
to
Here, Nathan Jerpe <nathanunde...@msn.com> wrote:
>
> I guess the first question is the devil's advocate's one...why use a virtual
> machine in the first place? If you want portability, can't you just write
> yourself an OS abstraction layer? What exactly is the VM buying you that
> justifies this complexity?

Working, stable interpreters on many platforms.

If your solution involves you (the game author) compiling and
distributing a game binary for every platform, then you have taken on
a problem that the rest of us don't even notice.

I *have* an OS abstraction layer, but I don't claim it's a complete IF
platform. It's one component of one.



> Secondly, why is the Z-machine designed (and I can only assume, the Glulx
> model as well) to keep the stack outside of main memory and the global
> variables inside of main memory? What is so different about a virtual
> machine that would encourage it to exhibit the opposite structure of a real
> one (Z-80, etc)?

Having the stack accessible is only useful if you're going to write in
a low-level language. (Or, to be more crude, only if you've got a
jones for C-style pointers.) Modern IF languages tend to be
high-level, whether they're designed for a VM or not. And modern VMs
(Java, Python, etc) *also* have the stack outside of main memory.

The Z-machine is not *well*-designed for high-level languages -- it
was 1980, after all. Having a flat memory map, including global
variables, is a small part of that.

(Glulx is designed to be similar to the Z-machine, because I wanted to
rewrite only half the Inform compiler, not all of it.)

The T3 VM is a more modern collection-of-object-references model; that
may suit your needs better. Depending on what your needs are.

--Z

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

Nathan Jerpe

unread,
Oct 12, 2005, 5:22:06 PM10/12/05
to
"Andrew Plotkin" <erky...@eblong.com> wrote in message
news:dijohn$8b4$1...@reader1.panix.com...

> Here, Nathan Jerpe <nathanunde...@msn.com> wrote:
>>
>> I guess the first question is the devil's advocate's one...why use a
>> virtual
>> machine in the first place? If you want portability, can't you just write
>> yourself an OS abstraction layer? What exactly is the VM buying you that
>> justifies this complexity?
>
> Working, stable interpreters on many platforms.
>
> If your solution involves you (the game author) compiling and
> distributing a game binary for every platform, then you have taken on
> a problem that the rest of us don't even notice.

I don't propose any new solutions. I'm just trying to comprehend the
rationale behind the original approach, before there were numerous
interpreters.


.
>
> I *have* an OS abstraction layer, but I don't claim it's a complete IF
> platform. It's one component of one.
>

Agreed. But when I think of an OS abstraction layer, I think of a library,
not a VM. It is conceivable that your IF platform could consist of a
collection of such libraries, of which the "OS library" would be only one.

>
>> Secondly, why is the Z-machine designed (and I can only assume, the Glulx
>> model as well) to keep the stack outside of main memory and the global
>> variables inside of main memory? What is so different about a virtual
>> machine that would encourage it to exhibit the opposite structure of a
>> real
>> one (Z-80, etc)?
>
> Having the stack accessible is only useful if you're going to write in
> a low-level language. (Or, to be more crude, only if you've got a
> jones for C-style pointers.) Modern IF languages tend to be
> high-level, whether they're designed for a VM or not. And modern VMs
> (Java, Python, etc) *also* have the stack outside of main memory.

Okay...that makes sense to me, I think. I suppose the advantage of
abstracting the stack away from main memory is one of security? Or maybe
just the abstraction itself? It seems if the stack is distinct from main
memory, then it could be represented via an entirely different data
structure than main memory, and nobody would notice.

>
> The T3 VM is a more modern collection-of-object-references model; that
> may suit your needs better. Depending on what your needs are.
>

No needs yet...just learning. But it is interesting to consider the notion
of a game world for which the IF-driven portion of it is only *a part*. The
most obvious example of this might be the implementation of, say, a
command-line interface for your ship's computer, in the context of a larger
action game or RPG that needn't know much about IF. Said computer might be
implemented internally as an IF-interpreter, but with, perhaps, an
additional layer added to integrate the interpreter with this world.

I don't know if this approach is worth pursuing with today's IF components
or not.

Cheers,
Nathan


Peter Mattsson

unread,
Oct 12, 2005, 7:13:28 PM10/12/05
to
Nathan Jerpe wrote:
> "Andrew Plotkin" <erky...@eblong.com> wrote in message
> news:dijohn$8b4$1...@reader1.panix.com...
>>I *have* an OS abstraction layer, but I don't claim it's a complete IF
>>platform. It's one component of one.
>>
>
>
> Agreed. But when I think of an OS abstraction layer, I think of a library,
> not a VM. It is conceivable that your IF platform could consist of a
> collection of such libraries, of which the "OS library" would be only one.

I think you're talking at cross purposes here. What Zarf's almost
certainly referring to is Glk (http://eblong.com/zarf/glk). According to
the spec:

"Glk is an attempt to define a portable API (programming interface) for
applications with text UIs (user interfaces.)"

This, I'm guessing, is exactly the sort of "OS library" that you're
thinking of. However, at present, it's generally used to build portable
interpreters, not the games themselves. (As Zarf says, for pure IF the
"compile once, run anywhere" ability of a VM-based system is a winner.
Infocom were the first to use one, for exactly this reason: it made it
easier to support the wide variety of different systems available at the
time.)

As for your idea of embedding an IF component in an RPG, say, I'd guess
your best solution would depend on how heavily integrated that component
would need to be with the rest of the game. The z-machine, having been
designed for an earlier era, is small and light by today's standards, so
(not being much of a programmer) I'd guess that embedding an interpreter
for one in your game would be easy enough. If you took one off the
shelf, you'd need to hack in connections to the rest of the game, so the
effectiveness of this approach would largely depend on what connections
were required.

The other question is how complicated your IF portion would be. For
example, simulating a basic ship's computer is probably a rather simpler
task than full-blown IF; handling an advanced one that with AI and the
ability to handle english sentences rather than straightforward commands
would be rather harder. The first task might lend itself to a homebrew
parser, while for the second it might be easier to leverage the work
that's already gone into the parsers of, say, Inform or TADS. As always,
it's likely to be a case of "horses for courses".

Regards,

Peter

drus...@wotmania.com

unread,
Oct 13, 2005, 7:56:43 AM10/13/05
to

Nathan Jerpe wrote:
> Just started to do some tinkering....
>
> I guess the first question is the devil's advocate's one...why use a virtual
> machine in the first place? If you want portability, can't you just write
> yourself an OS abstraction layer? What exactly is the VM buying you that
> justifies this complexity?
>
There is an article called "How to Fit a Large Program Into a Small
Machine" that I think answers this question. You have to remember the
limitations of home computers, as compared to mainframes, of that era.
http://www.csd.uwo.ca/Infocom/Articles/small.html

> Secondly, why is the Z-machine designed (and I can only assume, the Glulx
> model as well) to keep the stack outside of main memory and the global
> variables inside of main memory? What is so different about a virtual
> machine that would encourage it to exhibit the opposite structure of a real
> one (Z-80, etc)?
>

I once wrote a simple virtual machine, and I did it this way as well. I
can't remember why, but the thing works ;-)

-Donnie

Ben Rudiak-Gould

unread,
Oct 13, 2005, 12:41:15 PM10/13/05
to
Nathan Jerpe wrote:
> why use a virtual
> machine in the first place? If you want portability, can't you just write
> yourself an OS abstraction layer? What exactly is the VM buying you that
> justifies this complexity?

A virtual machine is an OS+CPU abstraction layer. Most of the complexity is
in the OS abstraction part (and the libraries). So why not abstract the CPU
also? It makes developers' lives much easier. The only reason software
engineers don't *always* abstract the CPU is that it tends to carry a
significant speed penalty compared to other forms of abstraction. But most
interactive fiction is not very demanding of CPU.

> Secondly, why is the Z-machine designed (and I can only assume, the Glulx
> model as well) to keep the stack outside of main memory and the global
> variables inside of main memory? What is so different about a virtual
> machine that would encourage it to exhibit the opposite structure of a real
> one (Z-80, etc)?

The Z-machine only has 64K of addressable memory, and the stack would have
cut into that significantly. In the case of Glulx, I think it was a poor
design decision (in a generally well-designed machine), though Zarf
obviously disagrees.

As for the globals, I suppose they decided that the extra flexibility or
simplicity outweighed the memory cost. The Z-machine globals are a lot like
the 6502's zero page.

-- Ben

Timothy Partridge

unread,
Oct 13, 2005, 6:19:32 PM10/13/05
to
In article <434d5676$0$49018$1472...@news.sunsite.dk>,

nathanunde...@msn.com ("Nathan Jerpe") wrote:

> Secondly, why is the Z-machine designed (and I can only assume, the Glulx
> model as well) to keep the stack outside of main memory and the global
> variables inside of main memory? What is so different about a virtual
> machine that would encourage it to exhibit the opposite structure of a real
> one (Z-80, etc)?

Apart from reasons others have given, the following spring to mind.

A stack can make it easier to compile expressions. You don't have to worry
about keeping track of temporary variables / registers in your compiler.
(Your company has to write the compiler as well.)

Keeping overall code size small was important - the games had to fit onto
tapes / floppy. Alternative models of providing operators which use an
accumulator and an address make the VM more complex and each operator has to
have code to interpret the address. This might make things slower or bigger.
(RISC style processors with a large number of identical registers weren't in
use for home computers back then.)

Processors have ideosyncratic methods of addressing memory - a stack can be
put somewhere fast to access. Doing arbitrary access to memory locations for
many operations might slow things down greatly.

I don't think security of protection against a deliberately rogue program
was a concern back then. The writers were only using a VM for their own
games.

I recall there being a Pascal compiler which generated pcode which was a
virtual machine, but it's too long ago (early eighties) for me to remember
if it was stack based or not. Forth is a stack based language which is also
known for being implementable on microprocessors. I'm not sure off hand
where it fits in time wise.

Tim

--
Tim Partridge. Any opinions expressed are mine only and not those of my employer

Matthew Russotto

unread,
Oct 13, 2005, 9:05:46 PM10/13/05
to
In article <434d5676$0$49018$1472...@news.sunsite.dk>,

Nathan Jerpe <nathanunde...@msn.com> wrote:
>Just started to do some tinkering....
>
>I guess the first question is the devil's advocate's one...why use a virtual
>machine in the first place? If you want portability, can't you just write
>yourself an OS abstraction layer? What exactly is the VM buying you that
>justifies this complexity?

Among other things, object-code compatibility.

>Secondly, why is the Z-machine designed (and I can only assume, the Glulx
>model as well) to keep the stack outside of main memory and the global
>variables inside of main memory? What is so different about a virtual
>machine that would encourage it to exhibit the opposite structure of a real
>one (Z-80, etc)?

The main reason a real machine keeps the stack in main memory is
that's all it has. A virtual machine doesn't have that constraint.

Michael Martin

unread,
Oct 14, 2005, 1:50:11 AM10/14/05
to
>I don't propose any new solutions. I'm just trying to comprehend the
>rationale behind the original approach, before there were numerous
>interpreters.

For the specific case of the Z-Machine, there never was such a time;
the Z-Machine was designed so that the same gamecode ran on a Commodore
64, an Apple II, a PC, etc., etc., etc., and so they could sell to a
much broader market than their competitors.

Nathan Jerpe

unread,
Oct 14, 2005, 9:13:24 AM10/14/05
to

"Timothy Partridge" <tim...@perdix.demon.co.uk> wrote in message
news:20051013....@perdix.demon.co.uk...

Hi Tim! Thanks to you (and others) for their thoughtful responses.

> A stack can make it easier to compile expressions. You don't have to worry
> about keeping track of temporary variables / registers in your compiler.
> (Your company has to write the compiler as well.)

Not sure if I follow you here. Do you mean the compiler uses the very same
stack at compile-time that the interpreter uses at runtime? If so, this is
an interesting idea, but I don't understand how it could be useful. Sure,
using a stack to compile expressions seems natural enough, but why should
this affect the runtime model?Maybe I'm missing something.

>
> Keeping overall code size small was important - the games had to fit onto
> tapes / floppy. Alternative models of providing operators which use an
> accumulator and an address make the VM more complex and each operator has
> to
> have code to interpret the address. This might make things slower or
> bigger.
> (RISC style processors with a large number of identical registers weren't
> in
> use for home computers back then.)
>

I recall reading that stack-based machines often resulted in more compact
code. I guess the more frequently you can *imply* a location in your code
(which a stack seems quite amenable towards) rather than expressing it
explicitly, the better.

>
> I don't think security of protection against a deliberately rogue program
> was a concern back then. The writers were only using a VM for their own
> games.
>

Well, if they were as good at generating bugs as I am, they probably had
graver concerns about their own interpreters trashing memory and so forth.
Cordon off the stack into its own, less directly accessible world, and you
mitigate these problems.

Cheers,
Nathan


Nathan

unread,
Oct 14, 2005, 10:50:58 AM10/14/05
to
Nathan Jerpe wrote:
> "Timothy Partridge" <tim...@perdix.demon.co.uk> wrote in message
> news:20051013....@perdix.demon.co.uk...
> >
> > I don't think security of protection against a deliberately rogue program
> > was a concern back then. The writers were only using a VM for their own
> > games.
>
> Well, if they were as good at generating bugs as I am, they probably had
> graver concerns about their own interpreters trashing memory and so forth.
> Cordon off the stack into its own, less directly accessible world, and you
> mitigate these problems.

Interestingly, the most common fatal error message I get from a bug in
an Infocom game is "stack overflow". I haven't really traced the root
causes but I suspect many of these bugs can result in some sort of
infinite recursion. For example, this happens in Bureaucracy if you
try something like MAIL ME LETTER. From studying the TXD output it
looks to me like the routine handling the "MAIL obj obj" action is
supposed to be calling the ordinary "MAIL obj TO obj" routine, but
erroneously calls itself. Keeping the stack separate certainly doesn't
protect you from this kind of error.

Andrew Plotkin

unread,
Oct 14, 2005, 11:24:31 AM10/14/05
to
Here, Nathan Jerpe <nathanunde...@msn.com> wrote:
>
> "Timothy Partridge" <tim...@perdix.demon.co.uk> wrote in message
> news:20051013....@perdix.demon.co.uk...
>
> > A stack can make it easier to compile expressions. You don't have to worry
> > about keeping track of temporary variables / registers in your compiler.
> > (Your company has to write the compiler as well.)
>
> Not sure if I follow you here. Do you mean the compiler uses the very same
> stack at compile-time that the interpreter uses at runtime? If so, this is
> an interesting idea, but I don't understand how it could be useful. Sure,
> using a stack to compile expressions seems natural enough, but why should
> this affect the runtime model?Maybe I'm missing something.

I think this has diverged from the original question. Having a
stack-oriented instruction set does simplify both the compiler and the
compiled code. However, this issue is separate from whether the stack
is in main memory or not. You could do it either way.

There is one small dependence between the issues: if the stack is in
accessible memory, you have to specify the byte-ordering of the stack.
This slows down all stack access. If you're using a stack-oriented
instruction set, you're doing lots of stack access. The speed hit was
a bigger issue in 1980 than it is today, of course.

(Or else you could say that the stack is in native byte ordering,
whereas the rest of memory is in portable byte ordering. But then,
any time the game accesses the stack segment of memory, your nice
portable VM model turns into a pit of buggy hell. So you might as well
have made the stack inaccessible in the first place.)

Ben Rudiak-Gould

unread,
Oct 17, 2005, 3:03:06 PM10/17/05
to
Andrew Plotkin wrote:
> Having the stack accessible is only useful if you're going to write in
> a low-level language. (Or, to be more crude, only if you've got a
> jones for C-style pointers.) Modern IF languages tend to be
> high-level, whether they're designed for a VM or not. And modern VMs
> (Java, Python, etc) *also* have the stack outside of main memory.

I think this is exactly backwards. The more high-level (i.e. divorced from
the machine) your language is, the more control you need over the stack. One
thing that struck me as I read through the Glulx spec is that it would be
difficult to compile a garbage-collected language to it, because the stack
isn't accessible to scan for and update root pointers. Unless I'm missing
something, you'd have to manage a software stack in RAM to hold your local
variables.

Another example: adding upward funargs to Inform would be next to impossible
(you'd need garbage collection) but lexically-scoped downward funargs are
doable, and quite useful: you can use them to implement the
generator/iterator pattern (like Python's yield), which could replace the
special-purpose objectloop command with something more general and
user-extensible. But this is made harder by the fact that there's no way to
access stack frames other than the current frame; the only solution I can
see is an ugly hack that involves temporarily moving local variables into
RAM around a function call.

Similarly, lexically scoped functions, a la Pascal, would be much easier to
compile to Glulx if the whole stack were addressable.

Then there's call/cc. SML/NJ supports call/cc without imposing any speed
penalty on code that doesn't use it, by means of clever stack manipulation.
To support call/cc in Glulx, it appears that you would have to bypass the
hardware stack completely, which would mean either compiling the entire
program into a single Glulx routine or compiling each basic block into a
different routine, since it's illegal to branch between routines except via
call instructions.

If Glulx was simply designed as a target for Inform 6, then I suppose that
none of these problems really matters. But the fact that you included a
tail-call instruction in the spec suggests to me that you were interested in
accommodating other kinds of languages. If so, it would have been better to
design the VM with enough flexibility that it didn't /need/ a built-in
instruction to support tail calls.

Also, Inform 6 is anything but a high-level language! It reminds me more of
Borland's old 8086 assembler, TASM, which had built-in support for
object-oriented programming:

http://cs-netlab-01.lynchburg.edu/courses/Assemb/OOPAssem.html

-- Ben

Ben Rudiak-Gould

unread,
Oct 17, 2005, 3:16:00 PM10/17/05
to
Matthew Russotto wrote:
> The main reason a real machine keeps the stack in main memory is
> that's all it has. A virtual machine doesn't have that constraint.

That's circular: a real machine has only one kind of memory if and only if
it was designed that way. There's no reason you couldn't design a hardware
architecture that stored the stack in a completely separate bank of RAM
chips. Since stack access patterns tend to be very different from heap
access patterns, you might even gain speed this way, by using special "HRAM"
and "STRAM" chips optimized for the respective access patterns. The
dual-ported VRAM found on higher-end video cards is an example of this kind
of design. The reason real hardware stacks tend to be stored in
general-purpose memory is that, on balance, it's a better design. There's no
fundamental reason it has to be done that way.

-- Ben

Sam Denton

unread,
Oct 17, 2005, 8:57:14 PM10/17/05
to
Ben Rudiak-Gould wrote:

> Andrew Plotkin wrote:
>
>> Having the stack accessible is only useful if you're going to write in
>> a low-level language. (Or, to be more crude, only if you've got a
>> jones for C-style pointers.) Modern IF languages tend to be
>> high-level, whether they're designed for a VM or not. And modern VMs
>> (Java, Python, etc) *also* have the stack outside of main memory.
>
>
>
> I think this is exactly backwards. The more high-level (i.e. divorced
> from the machine) your language is, the more control you need over the
> stack. One thing that struck me as I read through the Glulx spec is
> that it would be difficult to compile a garbage-collected language to
> it, because the stack isn't accessible to scan for and update root
> pointers. Unless I'm missing something, you'd have to manage a
> software stack in RAM to hold your local variables.


Or, the VM could include an @collect_garbage opcode that scans the stack
and memory. The opcode could either do all the work itself (at hardware
speeds) or it could have a call-back routine to allow better programmer
control.

> Another example: adding upward funargs to Inform would be next to
> impossible (you'd need garbage collection) but lexically-scoped
> downward funargs are doable, and quite useful: you can use them to
> implement the generator/iterator pattern (like Python's yield), which
> could replace the special-purpose objectloop command with something
> more general and user-extensible. But this is made harder by the fact
> that there's no way to access stack frames other than the current
> frame; the only solution I can see is an ugly hack that involves
> temporarily moving local variables into RAM around a function call.


Again, it's a VM, you could add opcodes to do all of this. In fact,
those opcodes could perform arbitrary manipulations of the stack; since
VM programs can't see the stack, they wouldn't have to worry about
entire stack frames being shifted around in memory. On the other hand,
the design of the Z-machine was fixed decades ago, and reflects best
practices of that era.

> If Glulx was simply designed as a target for Inform 6, then I suppose
> that none of these problems really matters. But the fact that you
> included a tail-call instruction in the spec suggests to me that you
> were interested in accommodating other kinds of languages. If so, it
> would have been better to design the VM with enough flexibility that
> it didn't /need/ a built-in instruction to support tail calls.


Zarf can correct me, but I presume that the tail-call was simply to
support the optimization of operations like "return func(a,b,c);" where
func may or may not be a recursive invocation.

> Also, Inform 6 is anything but a high-level language! It reminds me
> more of Borland's old 8086 assembler, TASM, which had built-in support
> for object-oriented programming:


Actually, Inform started out as a Z-code assembler, then grew into a
macro assembler, then turned into the language we know and love today.

> http://cs-netlab-01.lynchburg.edu/courses/Assemb/OOPAssem.html
>
> -- Ben

Kevin Forchione

unread,
Oct 18, 2005, 12:52:14 AM10/18/05
to
"Ben Rudiak-Gould" <br276d...@cam.ac.uk> wrote in message
news:dj0shb$sjq$1...@gemini.csx.cam.ac.uk...

> If Glulx was simply designed as a target for Inform 6, then I suppose that
> none of these problems really matters. But the fact that you included a
> tail-call instruction in the spec suggests to me that you were interested
> in accommodating other kinds of languages. If so, it would have been
> better to design the VM with enough flexibility that it didn't /need/ a
> built-in instruction to support tail calls.
>
> Also, Inform 6 is anything but a high-level language! It reminds me more
> of Borland's old 8086 assembler, TASM, which had built-in support for
> object-oriented programming:

Let's do hope this isn't merely practice for the thesis paper and is leading
up to a new VM for Interactive Fiction? Hmmmm?

--Kevin


Neil Cerutti

unread,
Oct 18, 2005, 8:34:14 AM10/18/05
to
On 2005-10-17, Ben Rudiak-Gould <br276d...@cam.ac.uk> wrote:
> Also, Inform 6 is anything but a high-level language! It
> reminds me more of Borland's old 8086 assembler, TASM, which
> had built-in support for object-oriented programming:
>
> http://cs-netlab-01.lynchburg.edu/courses/Assemb/OOPAssem.html

Inform's best qualities are its excellent notation for IF, and
its powerful, extensible IF-libary. A sensible way to judge it is
to answer the question: "Is Inform a good tool for writing IF?"

No IF-libary written in a high-level langauge has ever been
completed, i.e., had a real game written in it. Not even a port
of Collosal Cave. Paradoxically, general-purpose high-level
languages seem a burden to game implementors, since not even the
authors of such IF-libaries are able to use them to implement
real games.

Every successful IF development tool I can think of has had a
special purpose notation as its foundation. Most of these tools
have been lower level than Inform.

--
Neil Cerutti
_________________________________________
Usenet Zone Free Binaries Usenet Server
More than 140,000 groups
Unlimited download
http://www.usenetzone.com to open account

Kevin Forchione

unread,
Oct 18, 2005, 2:22:35 PM10/18/05
to
"Neil Cerutti" <lead...@email.com> wrote in message
news:slrndl9qb4.1...@FIAD06.norwich.edu...
<snip>

> No IF-libary written in a high-level langauge has ever been
> completed, i.e., had a real game written in it. Not even a port
> of Collosal Cave. Paradoxically, general-purpose high-level
> languages seem a burden to game implementors, since not even the
> authors of such IF-libaries are able to use them to implement
> real games.
>
> Every successful IF development tool I can think of has had a
> special purpose notation as its foundation. Most of these tools
> have been lower level than Inform.

Omg, how gauche! What's wrong with you people? That's like... like... doing
claymation with plasticine.

--Kevin


Gregory Weir

unread,
Oct 19, 2005, 2:02:52 PM10/19/05
to
Kevin Forchione wrote:
> "Neil Cerutti" <lead...@email.com> wrote in message
> news:slrndl9qb4.1...@FIAD06.norwich.edu...
<snip>
> > Every successful IF development tool I can think of has had a
> > special purpose notation as its foundation. Most of these tools
> > have been lower level than Inform.
>
> Omg, how gauche! What's wrong with you people? That's like... like... doing
> claymation with plasticine.

I know! Potter's clay is so much better... it can be used to make other
things, too!

Gregory

Reply all
Reply to author
Forward
0 new messages