When the game reaches 256k of compiled code, then it will no longer fit
into an Advanced format game file. As a game gets longer, text takes up
an increasing portion of the Z-code. Here are some sample data points
(all compilations done with economy mode turned off):
Game Code Text Total text text (w/library)
----------------------------------------------------------------
Library only 31276 9604 40880 23.5 ----
Balances 40578 26030 66608 39.1 63.8
Magic Toyshop 43300 28316 71616 39.5 60.9
Adventure 47540 44040 91580 48.1 67.9
Christminster 87778 155246 243024 63.9 72.0
The value for `Text' is after the usual compression, but without any
abbreviations. The fifth column gives the percentage of text when the
contribution of the library is ignored; it is given by subtracting the
library code and text from the figures in the first two columns and then
dividing.
How many words will fit into a version 5 game? Assuming that the
percentage of compressed text in the Z-code (ignoring the library) tends
to 75, and that with a good choice of abbreviations, the Z-machine can
compress text down to about 600f its original length, then we have the
following results:
Story file Total Additional Number of words
bytes of text at 60ompression
-------------------------------------------------------
version 5 262144 165948 48100
version 8 524288 362556 105089
When your game gets longer than about 48,000 words, you'll need to
switch to version 8. Much longer than 100,000 words, and you'll need to
think about introducing another version of the Z-machine.
> Two: I've a character, a waiter, to be exact, who I want to be able to
> get an object for the player if the player types either 'waiter, get
> me a bagel' or 'ask waiter for coffee'. What action should I define
> to handle in the NPC's life()?
This is a tricky question. I'll give some simpler cases first.
If the player types `waiter, give me a bagel' and there is a bagel in
scope (perhaps it is sitting on the table in plain sight), then the
waiter's `life' routine is called with:
reason_code ##Order
action ##Give
noun bagel
second player
(some magic in the parser does the translation from the reversed form of
`give' into the usual form, so that `waiter, give the bagel to me' has
the same result). So you can handle this with:
Object waiter "waiter"
with ...,
life [;
...
Order:
if (action == ##Give && noun == bagel && second == player) {
move bagel to player;
"~Certainly, sir.~";
}
];
But if the bagel isn't in sight, then of course the parser will ignore
it, and simply fail to understand the input.
We can add some new lines of grammar that know about more objects that
just the objects in scope. For example:
[ PantryGiveSub; "You can't see any such thing."; ];
[ PantryGiveReversedSub; "You can't see any such thing."; ];
[ Pantry i;
objectloop(i in Pantry)
PlaceInScope(i);
];
Extend "give" last
* scope=Pantry "to" animate -> PantryGive
* animate scope=Pantry -> PantryGiveReversed;
So now if the bagel is in the pantry, then `waiter, give me the bagel'
will be understood just as in the case where the bagel was visible,
except that `action' will be `PantryGiveReversed'.
-- Gareth Rees