Having just successfully built my own front-end to Quixe and run a .ulx and blorb through it, I can tell you that it’s very much possible. After being pointed in the right direction by Zarf, here’s what I figured out:
- Get rid of whichever version of the gltoke.js file is already in your project.
- Create your own GlkOte object or, as I did, add “GlkOte = YOUR_OBJECT;” to one of your .js files
- The object you replace GlkOte with must look like this as a baseline:
replacementForGlkOte = {
version: "2.2.5experimental",
game: null, // Added by me for calls in other functions
lastGenValue: 0, // Added by me for keeping i/o in sync as per https://eblong.com/zarf/glk/glkote/docs.html#input
init:
function (game) {
this.game = game;
if (this.game == null) {
if (typeof Game === 'undefined') console.log("Game undefined");
else this.game = Game;
}
this.game.io = this;
this.game.accept({
type: 'init',
gen: 0,
support: ['timer', 'graphics', 'hyperlinks'],
metrics: { left: 0, top: 0, width: 0, height: 0 }
});
},
update: function (obj) {
switch (obj.type) {
case "pass":
console.log("Pass, do nothing.");
break;
case "error":
console.log("Error: " + obj.message);
break;
case "retry":
console.log("Retry, still working, come back later.");
break;
case "update":
//console.log("Update:");
//console.log("\t\t" + JSON.stringify(obj, null, 2));
//console.log("\twindows: " + JSON.stringify(obj.windows, null, 2));
//console.log("\tContent " + JSON.stringify(obj.content[0], null, 2));
this.lastGenValue = obj.gen;
if (obj.content != null) {
let outputList = [];
obj.content.forEach((updateContent) => {
for (let i = 0; i < updateContent.text.length; i++) {
let updateText = updateContent.text[i];
let content = updateText.content;
if (content != null) {
let style = null;
let line = [];
let segment = { style: null, text: null };
content.forEach((lineSegment) => {
//console.log("Segment: " + lineSegment);
if (typeof (lineSegment) == "string") {
if (segment.style == null) segment.style = lineSegment;
else {
segment.text = lineSegment;
line.push(segment);
segment = { style: null, text: null };
}
} else {
// TODO: Implement object processing per https://eblong.com/zarf/glk/glkote/docs.html#linedata
console.log("Unknown " + typeof (lineSegment) + ": " + lineSegment);
}
});
outputList.push(line);
}
else {
outputList.push([]);
}
}
});
// Call your own function to actually use the outputList
// processOutput(outputList);
}
if (obj.input != null) {
obj.input.forEach((inputEntry) => {
//console.log("\tinput: " + JSON.stringify(inputEntry));
// Inform your input mechanism to start waiting for user input
//readyForInput(inputEntry.id, inputEntry.type, inputEntry.maxlen, inputEntry.initial);
});
}
//console.log("\ttimer: " + JSON.stringify(obj.timer, null, 2));
//console.log("\tdisable: " + JSON.stringify(obj.disable, null, 2));
//console.log("\tspecialinput: " + JSON.stringify(obj.specialinput, null, 2));
break;
}
},
extevent: function (val) {
//console.log("extevent: " + val);
},
getinterface: function () {
return this.game;
},
getdomcontext: function () {
//console.log("getdomcontext");
},
setdomcontext: function () {
//console.log("setdomcontext");
},
save_allstate: function () {
//console.log("save_allstate");
},
log: function (msg) {
//console.log("log: " + msg);
},
warning: function (msg) {
//console.log("warning: " + msg);
},
error: function (msg) {
//console.log("error: " + msg);
}
};