Select Mode

State in Grue

In the previous post in this series, I talked about the memory map of the Z-Machine. Here, I will get into a related topic involving the state of the Z-Machine. This will be a relatively short post to clarify what “state” means in this context.

In that previous post, I mentioned the notion of the “interpreter’s private memory.” That came from the Z-Machine specification and the relevant part was:

Note that the routine call state, the stack and the PC must be stored outside the Z-machine memory map, in the interpreter’s private memory.

I had Grue load up the “Z-machine memory map” in the previous post. Here’s the crucial point for this post: when Grue executes the Z-Machine program that it loads, it will use the “interpreter’s private memory” to keep track of the state of the program. Here, the “interpreter’s private memory” refers to Grue itself!

With the code I wrote in the last post, I got a bytes object that represents the memory map of the Z-Machine program. That memory map is used to look up instructions and data and to update the state of the program as that program executes.

So is it fair to say that the zcode memory map contains the “story state” or “game state”? Is it equally fair to say that the private memory contains the “interpreter state”? Arguably, that is a good way to think about it, and it certainly helped me as I conceptualized things. So, let me break this down.

  • The Z-Machine memory map, which is represented by the bytes object that I obtain by reading a zcode program file, contains the story state or game state. This includes the program’s instructions, data, and global variables.
  • The interpreter’s private memory, on the other hand, contains the interpreter state. This includes the stack, the routine call state, the program counter, and other data structures that are used by the interpreter to execute the Z-Machine program.

As Grue executes the Z-Machine program, it will use, or rather be the interpreter’s private memory, which will be used to keep track of the program’s state. This state includes the values of the program’s variables, the contents of the stack, and the current position in the program’s execution. The Z-Machine memory map is used to look up instructions and data and to update the program’s state as it executes.

State of Play

Consistent with my conceptualization above, consider this next bit from the Z-Machine specification:

The ‘state of play’ is defined as the following: the contents of dynamic memory; the contents of the stack; the value of the program counter (PC), and the ‘routine call state’ (that is, the chain of routines which have called each other in sequence, and the values of their local variables).

This tells me that the “state of play” in the Z-Machine combines the story state and the interpreter state. It includes the contents of dynamic memory, which is part of the story state, as well as the contents of the stack and the routine call state, which are part of the interpreter state. The Z-Machine specification also says:

The entire state of play must be stored when the game is saved.

That’s an interesting and crucial point! Let’s talk about why.

Saving and Restoring

In the Z-Machine, it’s possible to save and restore the state of play, which includes the contents of dynamic memory, the contents of the stack, the value of the program counter, and the routine call state. This state can be saved to a file and then later restored to continue the program’s execution from where it left off. When you save the state of play, you create an image of the program’s current state. So, for example, in a game, if the player moves around, picks up items, solves puzzles, and so on, all of that is stored in the “state of play.”

Restarting

Beyond saving and restoring the state of play in the Z-Machine, there’s also a “restart” operation. This resets the story state to its initial state, as it was when the program was first loaded into memory. This means that any changes to the story state made during the program’s execution are discarded, and the program starts again from the beginning.

Undoing

It’s also worth noting that in the Z-Machine, there’s the idea of an “undo” operation. This operation allows for reverting the current state of play to a previous state. This means that the program’s execution is rewound to an earlier point in time, and its state is restored to what it was at that point. Not all Z-Machine programs will necessarily support this operation, and even if they do, the number of undo “steps” available can be limited.

State is Serialized Memory

All of this is important to understand the notion of state and how that ties into memory. The state of the zcode program at any given time is a serialization of its memory. The Z-Machine specification says this:

Z-machine programs are stored on disc, or archived on the Internet, in what are called story files. (Since they were introduced to hold interactive stories.) A story file consists of a snapshot of main memory only.

Thus, an interpreter implementation like Grue takes a file as input, which is just a straight-up serialization of the story state. That’s what my code in the previous post effectively did. What’s becoming clear is that as I move forward with Grue, I will spend a lot of time figuring out how to decode that state.

Decoding that state means working with actual zcode files. As I go forward, and if you’re following along, you’ll see that I use some of those oracles I mentioned in the context post as a guide for determining what is and is not correct behavior in the context reading the memory and determining the state.

Specifically, I will use an actual Zork 1 zcode program. Loading up that program is getting the memory map or initial state of play. Executing the instructions in that program will allow the program to be “played” and thus allow for state changes. In the next post, I’ll dig into that program a bit and see what I can read from the binary data.

Share

This article was written by Jeff Nyman

Anything I put here is an approximation of the truth. You're getting a particular view of myself ... and it's the view I'm choosing to present to you. If you've never met me before in person, please realize I'm not the same in person as I am in writing. That's because I can only put part of myself down into words. If you have met me before in person then I'd ask you to consider that the view you've formed that way and the view you come to by reading what I say here may, in fact, both be true. I'd advise that you not automatically discard either viewpoint when they conflict or accept either as truth when they agree.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.