Game of Worlds technical postmortemy things



This is not a post-mortem in the strictest sense of the word, but I have had a few PM’s and emails asking ‘how did you do that?’ – in reference in particular to the fact the graphical elements are injected into the HTML framework from Inform, and the AI of the opponent.

GoW TOURNAMENT is just a card game I thought was fun, and I wanted people to play. It placed slightly higher in the comp than I thought it would – most reviews were entirely correct in their assessment of ‘this is quite fun, but I’m supposed to be judging IF here!’ and I expected and was entirely ok with that – I would have written the same thing.

The graphical elements use Furkle’s excellent little framework to inject elements from Inform into the framing Javascript. I’ve written a blog post about it:

It is not perfect, but it really is worth experimenting with if you get the chance. I don’t think I’ve even scratched the surface of potential here. In theory, you could use Inform as a meta-language to manage entirely the front-end – specifically as a kind of user-command led wrapper around a suite of Javascript functions.

Each card has a little meta-description in the code. For example:

Scion of Uther is a GameCard. The description of it is "Arcana: Mind[line break]Name : Scion of Uther[line break]Effect : Four turns[line break]Description: Halves progress of your opponent's Lifeform towards the next stage of Evolution.[paragraph break][italic type]He was the scion of an ancient noble family; she an orphan without money or friends_*|CFICODE: './interpreter/Assets/Scion_Uther.jpg', 'Scion of Uther'|*_.[roman type]". The target_type of it is opposition. The priority of Scion of Uther is 4. The printed name of Scion of Uther is "[set link 1302]Scion of Uther[end link]".

This has the effect of replacing the image and text in the sidebar every time the description of the card is printed out in the main parser screen.
It would be interesting to see some experimentation with this. Each output in Inform could theoretically, for example be redirected to a different part of the page. Hmmmm….

The other aspect of the game that was interesting to develop was the AI. It’s actually quite a complicated thing. It’s a four-pass AI:

[code]Each turn:

  1. Assign Strategy to myself from aggressive, passive, builder, defender from game’s current state and the cards in hand.
  2. Optimise Cards – A little non-linear optimization function that prioritises each card depending on the strategy and game’s current state
  3. Optimise Field – Assess impact of each card on field of play.
  4. ……rinse and repeat recursively until an optimal choice is reached according to a fairly arbitrary ceiling[/code]

With this, the opponent can quite easily play the absolute optimal card every time – that maximizes its winning chance based on the state of play. Interestingly, this made the game too hard. It wasn’t much fun. Even when the player fully understood every mechanic of the game, and played optimally, the average win-rate was 50%.

So I had to do a ‘de-optimize’ step 5. You’ll notice that the opponent quite often will play a foolish card. Basically, every now and again, the opponent will ignore its optimized card and choose a ‘non-optimal’ card from its hand. The frequency and chance of this decreases as you progress through the competition.

The rulebook is a Twine. It is called directly from the game into a modal window using the BROWSE action. If anyone is interested, here is the code:

[code]browsing is an action applying to one thing.
Understand “browse [something]” as browsing.

Does the player mean browsing the game of worlds rulebook: it is very likely.

Check browsing:
if the noun is not the Game of Worlds Rulebook:
say “That is not browsable.” instead.

Carry out browsing:
if the noun is the Game of Worlds Rulebook:
say “You _|INCOPEN: ‘./interpreter/Assets/Rulebook.html’|_open the rulebook.”;[/code]

And here is the little javascript function that sits inside Furkle’s framework:

[code]var ROUTINES = {
‘INCOPEN’: doIncModal,
// Get the modal
var incmodal = document.getElementById(‘myIncModal’);

//To launch the Rulebook modal window
function doIncModal(source) {
var txtmod = document.getElementById(‘books’);
txtmod.src = source;
var modal = document.getElementById(‘myIncModal’); = “block”;
Finally, as a note to self - I’m adding a commandment to the canon of ‘thou should not’ for authors:

I lost count of the number of people who overlooked the Rulebook. This was my fault entirely.

Great competition. Great entries. Thanks to all who participated.


Documenting working cross-compiler of IF terps Android NDK

Seriously impressed by the technical achievement here. And the game was very fun and well balanced. One issue I did have is that once you have an advantage over the opponent, it’s very straightforward to use multiplier effects to widen that advantage, such that a lot of games were a bit of a steamroll.


Thank you, and,yeah, agreed. that’s some of what I need to work on for a next release. in addition, some of the cards plus multiplier are overpowered. Desolation + a multiplier towards the end of the game is devastating for example.


This was a lot of fun to play. I did notice the disjointed nature of the AI, in the sense that usually it would play pretty optimally but occasionally would play something completely silly. AI is a hard problem, though, and I was really impressed at how well it did normally. It took me several matches before I got enough of a sense of the cards to make a decent strategy. I got really flattened the first few times. Eventually I found that some cards were almost never useful, though, like the ones that changed the resource levels of the planet. I only played those when I didn’t have anything else useful to play. I’m curious about how the AI decided whether to use a counter token or not. Sometimes it would counter me multiple times and sometimes it would let me counter things unopposed.

Does this mean that this piece is actually a combination of Inform 7 and Twine? That’s really unusual, but brilliant. I don’t understand the usage of the INCOPEN routine or why it’s in the middle of the say statement, but if it works, awesome. Thanks for sharing some of the technical details.


Oh god, they’re combining. Soon the circle will be complete, the distinction between parser and choice games will be moot, and we’ll enter a brave new world of interactive fiction.

Tongue out of cheek: If this is true, or even if it’s not, the technical impressiveness of what I’ve heard about this game makes me really want to try it.


Reiko, the basic concept is that there’s a small little Javascript module that watches every bit of text that gets appended to the document. If text is rendered to the document matching the pattern PATTERN (I think, it’s been a bit), this is understood as a command to be executed, and the related Javascript fires, and the text is deleted. This way, the writer has some degree of control over what Javascript executes when, and the player (ideally, as far as I’ve seen) never sees the command at all.

In case this doesn’t answer why it’s in the say statement, the Inform virtual machine is very complicated, and requires some degree of collaboration and understanding to hook into, so instead of listening to or modifying the parser runtime, patterns intended to be understood as calling are only “heard” if they’re a part of text outputted by the Inform engine.

(matt w) #7

I enjoyed this and was very technically impressed, and the code sounds very awesome and useful!

How plausible do you reckon it would be to tinker with this sort of framework if you basically don’t know any Javascript? Do you see it as something that someone could plausibly use as an alternative to Flexible Windows?


For browser delivery of the game, yes. Furkle’s framework is a deceptively simple thing. In theory, all text could be parsed through the framework, calling simple Javascript functions to stream the output / manage several HTML elements. In my other game that uses this, Worldsmith, I’m using it to manage at least 6 elements in the page.

I’m going to experiment a little. I think it would be interesting to see how you could use this to stream some of the output into separate little ‘windows’, and manage more atomically the user UI,.


matt, please feel free to drop by the euphoria channel or message me on twitter (@furkle_) if you want to talk about integrating web stuff into parser. i can’t make any huge promises, and it certainly won’t work as well as if zarf wrote a glulx opcode for you, but i’m sure we can figure something out.

(matt w) #10

Thanks furkle! I am pretty much infinitely far away from having anything that I might want to put in this framework but if I get something I might want to mock up I’ll get in touch! Bookmarking this thread for future reference.

(Aside, having looking at your twitter TL I’m literally laughing out loud at this.)


Hi, I’m the player who sent you a mail about ‘negative kills’ bug.

I found the game interesting but I didn’t get farther than winning one match, I would have liked the base mechanics such as invading, expanding, evolving…to be less oscure.

Any chance you could explain some of that?
Or are these rules in the ingame manual already but somehow I managed to miss them?


@Matt that was cat’s (catacalypto on the forums) idea! it’s worked out quite well, and every other day or so it spits out something horrifying and delightful.


heh. based on the interest in the UI, I made a thing. I’ve done a blog post about it. I’ll do a longer post in the Add-ons board in a short while: … rser-games


Are there any other stories people can point me to that use the furkle framework with inline _*CFICODE ? I"m trying to see if I can adapt some of the basics like image loading and web page launch into Thunderword on Android. Probably the big thing I see is the container, as we are gong outside blorb files for images and such and I’m seeing more and more “.zip” file are being used to bundle assets outside the direct Glk pathways. I am seeing the need to consider a new kind of file system extension, like .ifzip that can be identified as an IF zip file - and some basic manifest or standard structure.