Our Motto

It is very easy to be blinded to the essential uselessness of [the products of the Sirius Cybernetics Corporation] by the sense of achievement you get from getting them to work at all.

In other words — and this is the rock solid principle on which the whole of the Corporation’s Galaxy-wide success is founded — their fundamental design flaws are completely hidden by their superficial design flaws.

— Douglas Adams: The Hitchhiker’s Guide to the Galaxy


Meanwhile, somewhere else…

… I’ve completed a similar project.

(No, I didn’t complete it. Software is never complete. But I brought it to a beta state.)


Slow Going

The problem right now is not so much to find the correct code, but to propel the story along.

While in the first “chapters” things automatically fell into place, it’s now a bit difficult to hit the right balance between storytelling and puzzles… hm.


Maybe not Quality, but a least Content

The game file now consists of 101.5 kB. (The “game file” being the actual game once it’s compiled for the Z-machine. In other words, these are the “raw” contents of text and logic, regardless of comments or spacer lines I may have introduced in the source. I’ve broken the magical barrier!)

Things are beginning to fall into place, and I think I have a fairly solid beginning and a bit of the parts for the middle play.

Of course, good ideas for the end game are still wanted… ;-)


1099 lines

Now if size was also a guarantee for quality… ;-)

(But seriously, I feel I’m making progress here!)


Inform 6: Attributes v/s Properties

Attributes and Properties are I6′ mechanisms for a game author to store and retrieve information about its objects. A number of attributes and properties is already predefined for new objects, and the author can add to them. The fundamental differences are:

  • Attributes are boolean variables, ie they can only be true or false. Properties are per default integer variables.
  • If a new attribute is defined, all game objects will possess this attribute (the attribute’s value true or false may of course change.) In contrast, properties are defined for a single object or a class by means of the with keyword, and only these objects or class instances have access to the property.
  • To test if the attribute uffda for object hoogla is set to true or false, use has hoogla uffda or hasnt hoogla uffda, resp. To set the attribute value (to true), use give hoogla uffda, to clear the attribute, use the slightly less intuitive give hoogla ~uffda.
    In contrast, property values are read and set like in conventional programming languages in their object code: self.uffda= 250 or if(self.uffda==250), resp.

Global variable can be defined with they keyword global.


Inform 6: Verb (or Action) Classes

Like many other things with I6, once you’ve got your head around it, the whole issue of verb classes isn’t as intimidating anymore.

In I6, there are exactly three verb classes:

  • Class 1 verbs are the one which aren’t evaluated as part of the game, but are about the game: Save, undo etc. are a part of that.
  • Class 2 verbs are actions which per default change the state of the game — for example, if you take an object, it will no longer be in its previous position, if you open a container, you can see what’s inside, if you eat something, it’s no longer there. (But see below!)
  • Class 3 verbs finally are those actions which per default leave the game state unchanged. This includes most of the life actions which are sent to animate NPCs. (In other words, even an animate object still needs to told to respond to life actions, if it’s not supposed to be completely inert.)

An interesting bit of trivia is that while eat is a class 2 action, drink is a class 3. I presume the idea is that even though you may drink from something, there is still an amount of it left afterwards.


How do Doors Work in Inform 6?

Central porch of Chartres cathedrale Chartre 041130 Melusin (GFDL)Since I was having a bit of trouble lately in making doors in Inform 6 work, I thought it might be a nice idea to write down my experiences for my own memory, and of course for the benefit of other I6 novices who could find some advice useful.

Doors are I6′ way of connecting rooms in any non-trivial way. As such, a bridge, a teleport system or such should be implemented as doors, too.

Since I’m writing such a sequence right now, let’s assume you are at an inn on the upstairs floor, which is aptly named inn_upstairs, and there is one other room to the east, namely chamber.
The trivial way would be to connect those simply with an exit from inn_upstairs:
e_to chamber
which gives you ready access from inn_upstairs to chamber — but this is of course not what we want.

Rather, we’d like to have a door. First of all, we need to create it — which is done by inserting an object with the attribute has door and placing it in the room which we want to leave through said door (we’ll call this the “source room”) — in our exmaple, the room to leave is inn_upstairs. Now we need to implement the actual door behaviour, which is a three-step process:

  1. Define the door as the exit of the source room in the direction of the adjoining room, which in our case lies to the east — hence:
    e_to the_door
    replaces the previous direct exit in its definition.
  2. Secondly, we need to declare to which room the door will lead, provided it’s open — ie, define the door with
    door_to chamber
  3. Finally, we must also state into which “direction” the door is leading, namely
    door_dir e_to

I’m still a bit puzzled as to the purpose of the third step. My guess is it has to do with the behaviour that once a door is open, you can walk through it like through a regular exit without re-opening it every time, ie the original’s room e_to is now replaced by the door_dir.

Your door needs to be given the attribute openable so that it can be opened and closed and will behave as expected. To determine its initial state, you can give it the attribute open. (Without that it will initially be considered closed.)

To spice things up a bit more, you can define the door lockable (and locked, at your whim). It can then be locked or unlocked with any object you may have defined elsewhere, by defining it as the key for the door: with_key room_key, for example.

The complete code for rooms, door and key looks like this: (Note that the key is defined elsewhere, but since really anything can be the key, there’s nothing special about it.)

!##########################################################################
object inn_upstairs "A tiny landing"
with initial "You climb up the narrow stairs -- hardly more than a
ladder -- to arrive on the landing.",

description "A tiny landing on the tavern's first floor. While the
stairs lead down to the hall of the inn, one door leads to a room
south of you.",

e_to the_door,
d_to inn,

has light;

!##########################################################################
object the_door "room door" inn_upstairs
with name "door",

description "A door to one of the guest's chambers.",
when_closed "Another locked door bars your way to a room east.",
when_open "An open door leads east to the chamber behind.",

after[;
unlock: give self open;
],
door_to chamber,
door_dir e_to,
with_key room_key,

has door lockable openable locked static;

!##########################################################################
object chamber "A chamber in the inn"
with initial "You enter the modest small room and wait for a second,
until your eyes are accommodated to the bit of light coming
through a little window.",

description "The room is obviously occupied by a female guest, but
the lady isn't present.",

w_to inn_upstairs,

has light;

The lines
after[;
unlock: give self open;
],
may require a bit of extra explanation:

Per default, locking/unlocking and closing/opening a door (or any container, for that matter) are two seperate actions. With the after rule the opening follows the unlocking automatically, to make it easier and quicker on the player, and since it can be assumed that if the player unlocks the door, he’ll also want to open it (in this scenario).

Note that trivial exits and doors have one thing in common: Per default, they’re one-way in I6, which means that a door which connects room A to B does not automatically also give access from room B to A. Rather, you must implement a second door back from B to A (and ideally one which shares its locked/open state with the first door…). (In my example I went the easy way and simply gave the chamber visited through the door a “regular” exit back to inn_upstairs. In the current scenario, it makes little sense for the player to for example lock himself in the chamber.) I presume the one-way feature was designed with “unusual” doors like trap-doors in mind. You can also find libraries for I6 out there which help in implementing two-way doors.


850 lines: Hard fight, but I won

Most of tonights wrestling with Inform concerned doors, but I finally have finished the first correct implementation.

To Inform, there’s a big difference between unlocking and opening a door…


740 lines

The girls do my (or the player’s… ;-)) bidding, and I think they do so with a bit of charm.

The nun and the blind beggar have also been put into action.

It’s fun learning your way around Inform 6, and slowly, but surely getting the hang of it — I even “refactored” (ie, rewrote) a few old lines of code because I’ve learnt since how to better achieve what I want.


600 lines

I was a little distracted over the last few days.

But now, the Doge and Guido, the guard, have been written for the better part.

Today I need to make the girls by the fountain do what I want.