[Z-machine] Stack depth?

How large should the stack be to handle pretty much any Inform 7 game?

Does anyone have any data points as to how much stack space some Inform 7 games use?


Hm. Good question. I probably did some tests back in the early days, but not recently.

I just tried a quick hack to count stack frames. This is the max depth of the call stack after testing some commands. I haven’t tried to count values pushed on the stack per frame.

Advent.ulx: 25 calls (after testing movement, GET ALL, and looking at the HELP menus)
Counterfeit Monkey: 63 calls (after the initial sequence getting into the Fair)
Hadean Lands: 84 calls (loading a saved game and then testing GO TO NAVE from the first room)

1 Like

…of course those are all Glulx games. Nevertheless, it gives you an idea how deep calls get in the generated I6 for a complex game.

I just had Primrose die on Ozmoo because the 1024-byte stack wasn’t enough. I increased the stack size to 4.5 KB ( the biggest I could easily make it) and then it worked. But this got me thinking - is there a rule of thumb as to how big a stack should usually be enough?

I have a dim recollection that, at the time of Inform 7’s first public release, we settled on a recommended minimum stack size of 4096. But I can’t find any remaining evidence of this.


I don’t think anyone has done a comprehensive analysis of zcode games to determine a minimum safe stack size. Even if someone did, there’s nothing to prevent a new game from taking even more tomorrow.

The latest interpreter library I’ve been building counts stack frames, locals and pushed stack values as well, but even then you only have a partial picture unless you can be certain you exercise all possible code paths.

Choosing a minimum for the standard would run up against the following problem: Any value you choose would likely be too small for some games, or too large for some platforms. There’s likely no perfect value.


Edit: Also, any limit would likely be meaningless to some implementations, such as one where pushed stack values don’t occupy the same area of memory as the call stack.

The Z-spec estimates are based on one such survey. But that was pre-I7.

I don’t remember. Let me see…

For the I7 public beta (2006), Graham wrote a release note that I kept a draft of:

We ask that interpreter-writers raise the stack size as far as sensibly possible. On genuinely small machines, this could be a waste of memory, but at any rate please ensure a stack of no lower than 16K in size, and if memory is not a concern then please allow 64K or more. Just in case.

I also have multiple email threads remarking that 1024 bytes (which was an early Frotz default) was definitely too small for I7 games.

1 Like

There’s also the following section of the standard which mentions 1024 as an absolute minimum and that some games need more. I remember reading somewhere of 32K not being enough for some particular game, but 60K or perhaps even 80K working. Unfortunately I don’t remember the game name, or where or when I read it. How terribly useful my memory is. :roll_eyes:

Edit: Maybe someone should write a really awesome game that nevertheless takes 128K of stack or more, to force the issue. :smiling_imp:


The absolute minimum standard for stack size is defined as:

let the ‘usage’ of a routine call be 4 plus the number of local variables it has. During a game the total of the usages for each routine in the recursive chain of routines being called, plus the game’s own stack usage, can be assumed to never reach 1024.

However, more recent games have required a much larger stack size than this allows for. It is advised that interpreters allow for these games by having a larger stack size if at all possible.

Two examples of modern interpreters with increased stack size are Windows Frotz , with 32768, and nfrotz with 61440.

Are you thinking of How much stack space does the Z-Machine need?

1 Like

That may have been it, with my memory filling in gaps incorrectly.

I plan to investigate the usage patterns of as many games as possible at some point, when I find the time.

The interpreter library I am working on can track all aspects of stack usage and it stores the call stack, the locals, and pushed stack values in separate locations with separate limits, so the information is of some practical value to me.