C code 'glkhtml' to work like 'GlkTerm' (curses) in HTML/CSS

Having spent a lot of time on Glk libraries, including the SDL1.2 nanoglk library, it finally occurred to me that really what I might be looking for is a C code library that takes Glk conventions and outputs modern simple HTML with CSS tags.

Open Invitation

I invite anyone to create such a library. An experienced C programmer could do this in one day! I’m a poor C programmer and intermediate HTML developer. I do know enough when to apply CSS tags to structure a flexible output, etc.

Why?

Both of the Android interpreters and the popular iPhone interpreters rely on C git/frotz/glulxe interpreters and add a Glk library. On the Android Linux side, we just don’t have a strong Glk library. Son of Hunky Punk and Twisty have no release that can run Glulx stories.

HTML also eliminates a lot of the tricky problems: font support is extremely strong, Unicode is solved and understood (Gargoyle Gtk on Ubuntu 16.10 can not render mixed-Unicode like Inform 7 IDE can on Ubuntu 16.10, nor can SDL 1.2 nanoglk deal with mixed Unicode), mouse and touch screen support is the home field advantage of HTML browsers and WebView objects, etc. In some ways, HTML has long ago solved the Glk problems like ‘frames’ to do Glk Window objects.

The general design is to keep the entire ‘engine’ of the game in C code on Android. So that Ubuntu and Android could equally run the game and it’s just a matter of piping the C code HTML output to a layer that knows how to best present it.

If there was such a C code project, ‘glkhtml5’, I am thinking about how Android Java would interface to the C code. The simplicity becomes very obvious. You could make a variation of this C library that maintains a concept of the HTML page/frames entirely on the C side of code and allow for a very simple API between C and outside presentation layers (Java). Minimalist to run Adventure:

  1. C code holds a Unicode String (jstring, UTF-8) that is the entire screen output (infinite size screen, with windows emptied on Glk ‘clear’). "
    Player Jimbo Jones is here
    Score: 17/99
    You are on a twisty road and find a fork() to change from East to West
    "
  2. C code API function to insert into the engine a single keystroke from the HTML browser to the C code Glk side. Such as ‘press any key to continue’ prompts or Glk menu systems you find in stories that respond to cursor up/down.
  3. C code API function to insert an entire input line. This is a basic Glk concept too. Where the whole line is edited before being sent to the Z or Glulx VM.
  4. NewContent notification. When a C code has new output or timer event it tickles the HTML side. But really Adventure (Colossal Cave) doesn’t need this, so we are beyond minimal implementation.

Of course, the devil is in the details, but this seems simple enough. I mentioned GlkTerm in the subject because it’s really not that far off. What happens with GlkTerm has a terminal window resize, etc?

P.S. In the ‘old days’ of 2014, HTML5 on Android was often a tacky shortcut to presenting output in a native fashion. But Google has changed their stance and since the release of Android 5.0 and Material Design they encourage HTML presentation layers as ‘native apps’. One key design change of Android 5.0 and newer is that the internal WebView is a downloadable and updated component of Android. So it isn’t stuck on phones as outdated with security problems.

This is what RemGlk is for, it produces and receives JSON which can be sent anywhere. Normally it gets sent to GlkOte, but it would be very possible to make an alternative implementation.

How feature-complete is it? Does it deal with hyperlinks, images, complex Glulx windows, sound, etc? Does it have a ToDo type list of what is completed and what is not? Does it have a list of games with known troubles (Counterfeit Monkey, etc.)?

Here’s the glk_gestalt implementation: github.com/erkyrath/remglk/blob … rggestal.c

From the looks of that a lot isn’t implemented, but I suspect that’s because the file hasn’t been updated since 2012, when GlkOte couldn’t support very much. It does now, so it probably wouldn’t take too much to add support in RemGlk for those things. The one thing GlkOte doesn’t support yet is sound.

Same problem with nanoglk and SDL1.2 that nobody has touched since it’s one and only release in February 2012. My main weak areas are C and GPU work, and that was driving me nuts. JSON and HTML is more the decoupled idea that a virtual machine (Z-machine / Glulx / TADS) inspires.

Open Invitation

Anyone and everyone: try out the established remglk and organize a list of every problem story game and missing feature you can find. It really helps to have a ToDo list for developers to know the state of a project.

Zarf does maintain RemGlk, but I would guess that he’s still thinking of it as an experiment more than something people want to use in production now. It certainly won’t hurt to raise an issue to ask for the rest of Glk to be supported!

Thank you for the information and perspective. I’ll start compiling and working with RemGlk.

P.S. This could lead to a new browser solution for running Interactive Fiction inside a browser. Most of the Z/Glulx VM to Glk is just basic string manipulation and generating JSON or HTML5 is really just more string generation / data reworking from Glk API calls. This is very simple in technological terms. This points to using asm.js to run the C code inside a web browser: softwareengineering.stackexchang … ing-asm-js – conclusion: encouraging a lot of effort to making the C code of ‘glkhtml’ produce good output that could solve many runtime problems! With really excellent CSS structure, audio/video/animation could be done flexible outside the C engine.

It’s used “in production”, in the sense that FloydBot relies on it and is used regularly. However, my work on IF tools has mostly been need-driven, and the Floyd setup doesn’t have a use for sound and graphics.

Having pushed the Rem/Ote model forward for a few years now, what I’ve learned is: you can’t put all the logic in the “Rem” side. The display layer (GlkOte currently) has to track a fair amount of information about input state and current window contents. (The latter isn’t absolutely necessary, but the UI is generally going to be smoother if you update it incrementally than if you try to re-render the entire page.)

The display layer also has to keep track of timer events. The back-and-forth call model of RemGlk just doesn’t account for RemGlk triggering its own timer events.

All of this would be true of an HTMLGlk library as well. (It would need Javascript-or-something code to track timer events and input state, and it would be better off doing incremental updates of the display.) (Although you could use a React-style library to take care of the incrementalism.)

All of which is just to say, I agree with Dannii that this is most easily done as a transformation on RemGlk JSON output.

What would it take to add sound/graphics/timer features to RemGlk? Some work. Not too much. There are, as you say, details to work out – I have a documented JSON format for graphics commands, but none for sound commands. There should also be a way for the display layer to clue RemGlk in about whether sound/graphics will be displayed or dropped on the floor. (Because of the Floyd case.)

I like to line up an IF coding project for the winter holiday. I’m willing to schedule this (RemGlk sound/graphics/timer work) if people think it will be immediately useful.

I’m willing to schedule this (RemGlk sound/graphics/timer work) if people think it will be immediately useful.

Sure, please do. I appreciate your encouragement overall!

To me the same fundamental issues exist for JSON: triggering loading of sound/graphics/timer and making sure the C code hands off UTF-8 that a modern JSON/HTML5 environment (Chrome/Firefox) can understand. For example, on Gargoyle, my experience is that Ubuntu 16.04/16.10 can not do Unicode UTF-8 properly. I can literally copy/paste it from Gargoyle into my Chromium web browser and it shows up fine! It’s this kind of issue that the C code currently is not dealing with very well. Although I point out that Inform 7 on Ubuntu itself doesn’t have this problem and is ‘ahead’ of Gargoyle when running Git and Glulxe interpreters. I’ve been unsuccessful in finding out the key difference of why Gargoyle-git vs. Inform7-git has this Unicode problem on Ubuntu. I noticed right away that the February 2012 library nanoglk (SDL1.2) had the exact same Unicode output issues as Gargoyle.

All this makes sense to me given that C is notoriously bad (historically) with strings! And it is this frustration that has me realizing that a HTML layer makes sense. That’s what Glk is all about.

(It would need Javascript-or-something code to track timer events and input state, and it would be better off doing incremental updates of the display.)

I’m being serious here on design: But why? Does GlkTerm need Javascript to do timers? Or does it not have timers? rs232 serial remote terminals over tty isn’t a new idea. I think the C code should be as self-contained as possible as the presentation layer should have to poll or get an event (not Glk event, but OS event) notification. For example - on a mobile phone - a user could be given the option that switching apps to their e-mail could suspend the game (RemGlk an Internet disconnect?) or allow background timers to execute (like not answering a telephone call, with in-game consequences).

EDIT: My quick test of Glkterm is that it supports Memory Streams that Son of Hunkypunk does not. I also just tested Glkterm with Frotz and freefall (Tetris) and it works; also with zracer.z5 - both uses timers. I can’t understand why this can’t be done purely on the C code side…

No, no. The “pure C” solutions (including GlkTerm) don’t have this problem. That’s because they use a core event loop which has a concept of timeouts. GlkTerm can call the curses getch() function with a timeout; that blocks and waits for input, but aborts at the appropriate clock time.

RemGlk is a different beast. It shouts data out through a pipe, and waits for more data to come in through a pipe. On the other side of the pipe is the display layer, doing the same thing. For the sake of sanity, they have a strict alternating you-me rule: one message out, one message in. There’s no provision for RemGlk to send a second message (“oops, timer fired, here’s more output”) out of turn. Nor do I think it’s worth complicating the protocol to add that.

Think of it this way: the Glk system really has two kinds of time-triggered events: timer events and sound-complete events. The display layer has to be responsible for the latter, because it’s running the audio I/O. So it’s cleaner, ultimately, for the display layer to handle timer events as well.

You and I are on the same page that sound and video gets far more complicated.

I’ve honestly not found that many actual games/stories that use timers. Tetris and ZRacer are the two I’ve found (neither use sound or bitmap graphics and are after the arcade timing behavior that can be done in a remote telnet or ssh terminal). I know some stories have timing built into their logic of ‘after 2 minutes if the person does not pick up the lantern, fail’.

Anyone want to chime in with ‘top 5 most popular stories’ that use timers? I’ve only tested about 100 zcode and glulx stories.

You get what I’m saying about some concept of timer that isn’t multimedia? But the keystroke related and story changing (“lamp runs out of fuel”) logic? Maybe we should ask the Glk standard to distinguish these because I find on testing the Java side (Son of Hunk Punk and Twisty) that they are clearly not equal to implement.

What I want to clarify is please don’t be discouraged by my thinking: I think a ‘glkhtml’ like RemGlk is a good idea and I’m right now looking at the RemGlk code. But I think ‘GlkTerm’ is a good reference point too of what more ‘fully fleshed out’ C simple API can do. This line of thinking may be faulty on my part, but I sense there is some lesson to learn here from the tty world. I can find no Android app that runs ZRacer, Tetris and does Unicode UTF-8 correctly - and here GlkTermW does all those correctly! tty rs232 terminals have always had some concept of ‘detatched’ on the millisecond level. Synchronous vs. async, etc.

Infocom’s Border Zone was the first one to use timers iirc. Kerkerkruip uses them in the display code.

progress: got RemGlk up and running and it passes the Unicode tests that nanoglk failed. The C to HTML passes the Unicode absent of munge.

If RemGlk is used locally then it doesn’t really matter where the timers are processed. If it is run remotely then this setup would add a lot of latency, and things like Kerkerkruip’s animations would run very slowly. But it should run perfectly fine in a mobile app.

Kerkerkruip-style timed animations (relying on very short timer intervals) are never going to look good across an internet connection. No matter which side the timers are run on. That’s just not a use case the API is aimed at. (Until some kind of animation support is added at the API level.)

I agree that it’ll be fine as an Android interpreter, though.

Very interesting.
I came to watch, as an glkhtml5 would be very interesting in Ubuntu Touch app development. I think that getting a system that rrnders to html could be very interesting as a long term solution. In the way Parchment, Quixe, Magnetic scriptand some other, work.

I agree. Right now I’m transforming the JSON output of RemGlk to HTML5 with good results… not using GlkOte at all. RemGlk has proven a useful base. I’ve been bogged down learning to compile and work with C code on Android for the past 10 days, but I’m mostly past that (Android’s Linux redirects stdin and stdout to /dev/null and it’s proven tricky to override that reliably on diverse set of phone and tablet hardware).

hacky learning going on, but I’m trying to tackle that RemGlk makes no effort to emit text color changes, user1 and use2 style. RemGlk source code file rgstyle.c.

So far, the basic solution seems to be to establish a multidimensional array:

// stylehint_NUMHINTS is typically equal to 10
// style_NUMSTYLES is typically equal to 11
glui32 stylehint_values[style_NUMSTYLES][stylehint_NUMHINTS];
int stylehint_is_set[style_NUMSTYLES];

Then, function glk_stylehint_set populates these:

    stylehint_values[styl][hint] = val;
    stylehint_is_set[styl] = TRUE;

Now, when to emit this in the JSON. You can go old-school outdated approach and emit them as JSON values right on the content lines. Or, a new more-modern approach would be to emit a new section of styles when Glk windows are emitted. C coders welcome to share code, etc!

I’m afraid I regard stylehints as a dead end and I don’t plan to support them in any new code. Stylehints aren’t powerful enough for authors, and they’re actively bad for users – not compatible with the color and font themes available in (e.g.) Lectrote.