Rethinking GLK’s C API: A Message-Based Protocol for Better Capability Negotiation

Summary

I’ve been tracking DreamMaster’s efforts integrating GLK into ScummVM and noted Andrew Plotkin’s (Zarf’s) own remarks on GLK’s portability limits. Rather than continue squeezing every interpreter into GLK’s C API, I propose a lightweight, message-based protocol: engines emit JSON-style requests detailing content, styling, and input, and hosts reply with explicitly supported capabilities. This approach would let each platform—web, desktop, mobile—leverage its native strengths, avoid undefined behaviors (e.g., MCGA color mishaps in Zork Zero), and foster a community-driven spec maintained by implementers.

Background: GLK’s One-Size-Fits-All Shortcomings

DreamMaster’s recent ScummVM Glk integration highlighted persistent rendering issues—particularly with Z-code color in Zork Zero—which mirror the broader architectural limitations of GLK’s “maximally portable” C API (Wikipedia). Plotkin himself has since acknowledged that the universal interface model can lead to “impedance mismatches” when engines request features hosts simply can’t provide (Wikipedia).

In practice, implementers continuously patch around GLK’s lowest common denominator. DreamMaster reported ongoing struggles getting true VGA/MCGA colors and advanced text effects working in ScummVM’s Glk layer (The Interactive Fiction Community Forum). Likewise, Gargoyle, Spatterlight, and Lectrote developers have each built their own workarounds, combining GLK calls with platform-specific hacks (Wikipedia).

A Message-Based, Negotiable Protocol

Core Idea

  • Structured Requests: Engines send JSON messages like:
{
  "content": "red text",
  "styling": { "zcode_color": "red", "fallback": "emphasis" }
}

Hosts parse these, render true red if supported, or fall back to italics—no guessing, no crashes (Wikipedia).

  • Explicit Capabilities: On startup, hosts could advertise support:
{
  "capabilities": ["ansi_color", "true_type_fonts", "touch_input"]
}

Engines then tailor requests accordingly, avoiding “unknown attribute” errors (Wikipedia).

Platform-Specific Benefits

  • Web Clients: Map directly to CSS classes or canvas APIs—no GLK-to-DOM shim (Wikipedia).
  • Mobile Apps: Declare gestures and fonts; native frameworks handle UI widgets.
  • Desktop GUIs: Talk Qt, GTK, or Cocoa directly for rich typography and windowing.

By letting each front-end “negotiate” features at runtime, we embrace platform diversity instead of enforcing uniform behavior (Wikipedia).

Community-Driven Specification

Rather than Zarf alone defining GLK’s trajectory, a working group of implementers (DreamMaster, Spatterlight, Gargoyle, Lectrote, Parchment, ScummVM devs, etc) could:

  1. Draft a Core Spec for text, graphics, and input messages.
  2. Define Optional Modules (sound, animation, touch gestures).
  3. Iterate Openly on GitHub or a dedicated forum thread.
  4. Publish Versioned Releases with clear migration paths from GLK.

This collaborative model ensures real-world use cases drive the spec, not purely theoretical portability goals (Wikipedia).

Questions for IF Developers

  • DreamMaster: Would explicit capability negotiation have eased your color woes in Zork Zero? Were there deeper Z-machine attribute semantics issues that a JSON protocol couldn’t solve?
  • Spatterlight & Gargoyle Devs: Could you map your existing rendering layers to a message-based front end, and what stumbling blocks do you foresee?
  • Zarf (Andrew Plotkin): Given your reflections on GLK’s portability limits, would you back a successor spec built on capability negotiation over a static C API?

Your insights will shape whether we refine GLK or chart a new path that truly leverages each platform’s strengths and preserves our MCGA Infocom classics in all their intended glory (The Interactive Fiction Community Forum).


References

  1. DreamMaster’s announcement and discussion of ScummVM’s Glk integration and its limitations (The Interactive Fiction Community Forum)
  2. GLK API overview, portability goals, and Plotkin’s remarks on its limits (Wikipedia) (Wikipedia)
1 Like

I have been using a JSON message based protocol called IFI (interactive fiction interface) between the “back-end” (IF engine) and the “front-end” (GUI) in the Strand IF system for some years now;

This is definitely a much more flexible solution than an API.

Some things to consider:

  1. The design must cover what and which features are the province of the GUI and which and what features are those of the game engine. For example, the game can give hints about fonts or styles but not actually demand them.

  2. The protocol design should be asynchronous.

  3. startup should be covered in depth. In IFI I have an initial exchange protocol whereby the game sends a bag of meta data to the UI and the UI sends a corresponding bag of meta to the engine. This happens before the game proper can start.

  4. in IFI, i have prohibited the back-end from requiring any OS specific API. For example, the back end cannot access the filesystem. This is done in the front-end (think about Web and Android here).

I could elaborate further if interested. Example web game using IFI.

Glk’s legacy is amazing, but what if this message-based protocol is the blueprint for its true successor? Imagine an ‘Xorg to Wayland’ kind of transition, but far smoother and better, fundamentally designed for developer ease without sacrificing excellence.

From an enthusiast’s view, the power of explicit capability negotiation and a decoupled, language-agnostic design feels immensely promising. Could this be the ultimate future-proof standard for Glk2.0, natively supporting an unparalleled range of systems—from ZX Spectrum and C64 up to the latest web platforms and consoles—making it universally portable and achieving a new level of excellence in every aspect?

This is a chance to shape the next chapter of interactive fiction infrastructure! Developers, users, anyone with valid points and good intentions—please share your insights. Let’s make this fundamental evolution a collective effort!

Do you think it would fit as a GLK successor able to fit into everything but better due to a different design? If yes, I would like to read about it :smiley:

You seem quite familiar with the Glk ecosystem already… but this already exists. It’s the GlkOte protocol.

But please understand that a protocol without an API is not easier to use. No, instead of one consistent way to generate protocol-compatible output you’d have a bunch of different incompatible unofficial APIs. Or every user of the protocol would need to manually produce its output.

The GlkOte protocol is, and should remain, an implementation detail. It doesn’t restrict what you could do in a Glk implementation (though real time effects are tricky), nor does it enable things that couldn’t be done without it. The Glk API on the other hand is both widely supported and extensible. There is lots more that could be added to the API, and it’s really only things that wholly depart from the Glk model (such as changing past output, or things which overlap multiple Glk windows) that would better suit a different system than Glk (though even they could be accomplished with a Vorple-style JS extension to Glk, it would just be limited to web interpreters.)

2 Likes

A couple of points I’d like to address;

Firstly, this (ie JSON messaging protocol) is not necessarily the way to go for messaging to scale from ZX Spectrum upwards. For retro dev, you’d probably be better with a tight pre-defined API.

Secondly, the idea of “explicit capability negotiation” is a bit vague here. When building IFI, i did not see any need for actual negotiation. Basically, the front-end UI makes its own decision on how to lay things out, and the game engine gives it suggestions or hints. So in that sense, there is no negotiation or fallback the game needs to consider. Instead it says what it would ideally want and the UI converts that as best it can.

Do you think it would fit as a GLK successor

Not really. There’s nothing actually wrong with GLK per se. My reasoning for making IFI was to accommodate all the things I needed not yet extended into GLK.

Afaik, the main point of GLK is being the I/O API for the Glulx virtual machine, and Glulx is the primary target of the Inform-7 compiler which a lot of games are using these days.

So I don’t see how GLK could really be anything else but a low-level and fairly fixed API, unless you are talking about extending the Glulx VM with a different way of doing I/O ?

I feel like I should stay out of this, since my bias is that Glk is fine the way it is. Mostly. Give or take a few feature ideas. :)

The GlkOte protocol is, and should remain, an implementation detail

I’d say it’s co-equal to the C API at this point.

It doesn’t restrict what you could do in a Glk implementation (though real time effects are tricky), nor does it enable things that couldn’t be done without it.

I agree with that though. Keeping them equivalent is now a design goal.

This reminds me that I should finish documenting the image scaling extension (Glk: Image scaling in buffer windows) and release it officially.

4 Likes