In light of the new Z-machine 1.2 spec suggestion, here’s a rough outline of how Vorple would work with the proposed stream 5.
First, the story file would have to find out if it’s being run on a Vorple-enabled interpreter. At the start of the game it would send this to stream 5:
javascript:try {
return vorple.core.requireRelease( x );
} catch(e) {
return false;
}
where x is the Vorple library version compatible with this story file. If it returns false, the story file disables all Vorple features and won’t use stream 5 anymore. The above code would be valid even on hypothetical non-Vorple interpreters that support JavaScript evaluation from stream 5. I suggest using “javascript:” to signify JavaScript data, which would be in line with what browsers use (i.e. the code above is valid JavaScript even with the identifier).
If there must be an end-of-transmit signifier, I don’t know what it could be that would also be valid JavaScript (which I think it should be); perhaps a special comment like /* END */ or something like that.
For simplicity’s sake before evaluation the interpreter should wrap the code to a function and write the return value to the input array (this should be Vorple-specific though, not something that should be in the Z-machine spec). The return value should be either an integer, a string or a boolean value. (Not entirely sure how to deal with boolean values: perhaps write their string representation “true” or “false”?) If the return value is undefined (i.e. nothing is returned) the interpreter does nothing.
There are basically 3 general cases where the interpreter might want to pass data to the story file. The first is a synchronous response to JavaScript code passed through stream 5. This is relatively straightforward: The interpreter writes the response to the array and closes the stream, and the story file picks up the data from the array, as per the 1.2 spec proposal.
The second case is passing simple events from the interpreter or UI to the story file and the interpreter doesn’t expect to receive a direct answer (e.g. the player pushed a button in the UI); this is the simplest case and can be handled with hidden commands sent through the command line.
The third case is asynchronous responses (interpreter must wait for a response from a third-party service, for example) and other spontaneous data the interpreter wants to send (e.g. player submitting information through a form in the UI). In this case the interpreter must first tell the story file that it has information to pass. According to the 1.2 proposal, the input array is unavailable unless stream 5 is open. Therefore, AFAICT, the procedure would be this:
- The interpreter has data to pass. It stores the data temporarily into an object with a unique id as the key.
- The interpreter waits for the story to be idle (waiting for player input).
- The interpreter sends a hidden command through the command line that tells the story file to prepare for data transfer. The command includes the id of the data it wants to pass.
- The story file sends javascript:return vorple.parser.retrieveData(x) (where x is the id) through stream 5 and closes the stream.
- The interpreter evaluates the JavaScript code which returns the requested data. The data is then written to the input array.
- The story file reads the data from the input array.
Does this seem like a sensible approach? Also, for actually implementing this I would need the I6 code for reading the input array. I have practically no idea how arrays work in I6.