Requesting an opcode

Hello all (especially Zarf),
Reading through these forums, I’ve seen the suggestion to “request an opcode” or the like as solutions to trying to extend the functionality of an interpreter.

How do you request an opcode and, once you do, what do you do with the opcode from that point on?

I’ve sniffed around and I haven’t found the process laid out.

Thanks!

  1. Email Zarf and ask for a block of codes.
  2. Decide what you want to do.
  3. (Optional) Write a spec document for the new opcodes/functions. Example
  4. Add the new functions in your Glulx or Glk implementation.
  5. If you’re an author, use them in your storyfiles.
  6. Try to persuade other interpreter maintainers that your extensions are worth adding.
1 Like

Hi! Dannii is basically right, but I will add some context.

There’s actually several ways to extend the Glk/Glulx interpreter model.

  • Add Glulx opcodes (the VM)
  • Add Glk calls (the I/O layer)
  • Add Glk gestalt selectors (flags that indicate what Glk calls are available)
  • Add an I/O system to Glulx (this basically tells the VM where to send ordinary print statements, if not to Glk I/O)

Glk calls and Glk gestalt selectors typically go together. If you add a call (or a bunch of calls), you want to add a selector that indicates that they are available.

The fourth option, a new I/O system, would be if you want to replace the Glk layer entirely. This is a lot of work. (Mind you, the first three options aren’t necessarily easy.)

You should decide roughly what you want to do, at least enough to understand which option you’re going for. Then I assign a bunch (usually 256 of whichever it is). This is just to make sure that two people doing experiments don’t accidentally use the same values.

You can see notes on existing reserved ranges in the spec documents:

https://eblong.com/zarf/glulx/Glulx-Spec.html#opcodes_misc
https://eblong.com/zarf/glk/Glk-Spec-075.html#selectors

It is my duty to note that most of these experiments have not gotten much traction. The FyreVM folks (@vaporware, @DavidC) built a new interpreter and used it for a couple of commercial games, but these didn’t sell well and those tools been shelved (as far as I know).

(Does Vorple use a gestalt selector? I don’t think I have it noted anywhere.)

3 Likes

It did for the Z-Machine, but for Glulx I think it does all communication through external files.

There are Glulx gestalt selectors too. Pretty essential if someone was going to extend Glulx in a portable manner.

Right, thanks – that’s mentioned in the spec document, but I forgot to include it.

There is a C# version of FyreVM is open source at https://github.com/ChicagoDave/fyrevm-dotnet and a web version is at https://github.com/ChicagoDave/fyrevm-web. The output system completely replaces glk and uses a “channel” or key/value pair system. So the “score” comes back as “score”: 100 and “location” comes back as “location”: “The Living Room”. Your “client”, be it a windows app or a web app can then use that package of values to locate them in your user interface as you want.

There’s a working version of Cloak in Darkness of fyrevm-web at http://plover.net/~dave/cloakjs/. If you open up the console, you can see how the package is returned with the list of values. The custom Inform 7 library allows you to add new channels with a line of I7 syntax:

banner-channel is a channel with content name "bannerContent" and content type "text".

Channel types are typed so you can display them with formatting as necessary, or use them in logic.

Cloak is implemented using React + TypeScript with simple templates. This is the Status Line React component:

import React, { Component } from 'react';
import { Container, Grid, Header, Label } from 'semantic-ui-react'

export default class StatusLine extends Component {
    render() {
        return (
            <Container>
                <Header as='h1' textAlign='center'>{this.props.title}</Header>
                <Grid color='grey'>
                    <Grid.Column width={8}>
                        <Header>{this.props.location}</Header>
                    </Grid.Column>
                    <Grid.Column width={2}>
                        <Label>Score</Label><span>{this.props.score}</span>
                    </Grid.Column>
                    <Grid.Column width={2}>
                        <Label>Turn</Label><span>{this.props.turn}</span>
                    </Grid.Column>
                    <Grid.Column width={3}>
                        <Label>Time</Label><span>{this.props.time}</span>
                    </Grid.Column>
                </Grid>
            </Container>
        );
    }
}

I stopped working on it because it’s more or less complete as an alternative to glk Inform 7 development. I’d hoped to partner with someone on a more sophisticated React implementation, but no one has volunteered.

I will add that a commercial IF company using Unity attempted to integrate the C# version, but for some reason they had serious performance problems with large story files. I don’t know what happened to that.

2 Likes

@Dannii Thank you for the answer.
@zarf Do options 2-4 allow for extending what an Inform 6 game can do within it’s code? For example, allowing an I6 story to trigger novel behaviour from the UI?

Yes, all of these extensions are accessible through Inform 6, though you may need to use some assembly code. Usually just a little, to set up the glk_ function like the others.

Well, I’ve already started replacing the I/O layer for my own needs but I think I want to pursue adding Glk calls and gestalt selectors. Is there a source text I can read about this?

Hard to say in general. Which interpreter or library are you modifying, or are you starting from scratch?

David C’s FyreVM is the only extension project I know of that goes with the entirely new IO system approach. I wouldn’t recommend it to be honest, Glk does a lot of stuff that you would have to consider replicating, and you also cut yourself off from the rest of the Inform Glk ecosystem. It can be done, but it’s a much bigger commitment than extending the Glk layer with a few custom functions leaving the rest intact.

If you explained what sort of extensions you want to make then we could give more concrete advice.

Yep, no problem. I may have miss-phrased, I’ve only replaced the GlkOte so I am still tapped into Glk.

I’m building off Quixe to make the game. Right now, the only extension I need to make is one to pass data between the Inform game layer and the javascript document. I don’t want to start going into Vorple because it’s a whole load of other things when what I’m trying to do is very basic.

I’ll likely add a few more extensions as development continues but I can’t be sure of what at this stage. That’s why I’m exploring making my own as, I feel, it’s likely that I will encounter the need at some point.

I’m a bit biased, but it does sound like Vorple would be a lot simpler both in terms of time and technical complexity. If you just include the basic extension it doesn’t do anything other than add the ability to pass data between the game and the browser, everything else is optional.

If you want to add the feature yourself the absolute easiest way is to use files: inside Inform write Javascript into a file and in the interpreter capture what’s being written and evaluate it. To pass data back to the game have the interpreter write it to another file and have the game read it from there. (These are “virtual” files in the interpreter, not actual files.)

Of course using opcodes is also possible, but unless you’re planning to make this system public for others to use it’s probably not worth it to go through the whole process of making it “official” at least not yet, especially if there won’t be a standalone Glulx file release to use in offline interpreters. Just pick any free block and add them to the custom interpreter you’re making.

2 Likes

Those are good suggestions, and I didn’t know I could include just one small portion of Vorple. Is there documentation about that?

As to the opcodes and other integration, I do plan to release the whole system I produce for use by others.

There isn’t much to document, really – basically the system is just an interpreter that can evaluate Javascript and a bunch of Inform extensions that do stuff by evaluating Javascript. If you don’t include an extension in the Inform project then it’s not included.

JS and HTML are easier than Glk.

I’m not looking for anything for fyrevm-web. It stands on its own. If someone wants to use it, good. If not, I did what I wanted to do. I had a different vision for Inform 7 IO and fyrevm (with @vaporware’s and thilo planz’s help) accomplishes that vision. The timing is off for me personally. I’m just less interested in coding these days and have other hobbies. I’d still like to finish some of my wips, but that may be awhile.

As for Glk, I’ve stated this before. That’s only part of my issue with the platform. The output is monolithic and deeply intertwined with Inform 6’s processing. If you want a suggested challenge for anything, pull out all of the bits of “print” statements in I6 and move them off to a separate library. All of them. Then add context to the output. That would really be something to see.

@DavidC If you’re willing, I’d like to have some off-forum back and forth on this. I favour Discord for this sort of thing (sarashinai#2896) but I’m open to other mediums. Let me know and I can provide you with other contact points.

Discord is perfect. Send me a server link.

I meant for things like external files, streams (including the memory streams that Inform uses internally), date/time, unicode. Glk provides a lot of functions that aren’t related to the user interface, and if you completely replace the IO system then there’s a lot of this stuff to either replicate or work around. I can’t remember what you did for FyreVM for the memory streams, because they’re pretty essential.

fyrevm has hooks to stream input and output from/to files or javascript. We didn’t leave that out.