Thank you for the testing, QC.
Well, you don’t really need to emit JSON from the inform level, from a RemGlk perspective that would be “JSON within JSON”. They key technique is to do what I think around here is called “channel I/O” - which FyreVM extensions for Inform 7 do this. Essentially a zero-size Glk window (invisible) TextBuffer can be an output target to send either fixed or multiple commands. For example, “roomname=Tavern Bathroom” sent to command channel. The command channel concept is “cleaner” in terms of legacy fallback, as older interpreters should ignore the stream of data.
Alternately, develop some kind of tag system in the main window stream. Example tag system: _|ADDIMAGE: _|GRESET: - Worldsmith story does this, here are some details: Game of Worlds technical postmortemy things
As far as extensions for out-of-band, Vorple this year was enhanced to support two VM’s, both Z-Machine and Glulx, so it has a couple sets of extensions to reference. And I would look over FyreVM extensions.
Essentially we are talking “out of band I/O”, how to get Inform to send things outside the visible content. Technically this can be done with no extensions other than ones for creating a second window (multi-window Glk stories go back more than a decade, such as Jon Ingold’s Dead Cities). Vorple uses Glk files written to disk that it expects to be read, I would discourage this approach based on my experience working with it. Sending unicode text right to a hidden Glk TextBuffer window would accomplish the same thing and also can work remotely (the disk files that Vorple creates would only be on the server in a RemGlk situation, the client would have to download the files out of band or RemGlk software enhanced to send file data in the stream).
Worth nothing: Typically we are not talking massive amounts of data being exchanged. Mostly triggers, variables, etc. Mostly I think authors want to have predictable timing tied to the story narrative and information on what action or media they want (name of an asset such as a video file to play, etc). This is typically bypassing the legacy asset systems such as blorb files to work with a secondary asset system.