IF Language Comparison

« Introduction

This is one of those works-in-progress. It isn't complete. It isn't thorough. It isn't finished. The word TODO is used frequently. And I'll probably try to port it to the ifwiki.

This is my attempt to compare, on a feature-by-feature basis, most of the main IF languages in use today: Alan 2 & 3, Inform 6 & 7, Hugo, and TADS 2 & 3. I am intrigued by the intellectual challenge. Each language uses different approaches to the many requirements of an IF work, and I want to know how are they different, and what stays the same.

Plus, I'm curious how I might compare them, how I might organize such a thing. What if a TADS operator's functionality is served by a function call in Hugo? Or if an object attribute in Inform corresponds to an object class in TADS? Sometimes, a low-level feature in language A has no direct comparison in language B because language B uses a completely different high-level approach; how to represent that?

There's also the practical usage of such a comparison when migrating from one language to another. I know how to readily create a reasonably nice program using Inform, but not in any of the other languages. Perhaps this comparison will help me or others learn a new language, or assist with the porting of existing IF programs. Anyone who is tempted to create RAIF-POOL (an unlikely program that can freely translate between the IF languages automatically) will need to go much further than this document proposes to go; that theoretical RAIF-POOL creator will not only have to resolve the conflicts between the languages, but also divine the intent of someone else's game code.

The reader will notice that I haven't included Adrift in this comparision. Although Adrift is a commonly-used IF development system, it isn't a language in the usual sense, and thus, it's not obvious to me how to represent its features here. I definitely do not want to insert screenshots. So, until I figure out how to get around that, I'm just going to skip Adrift for now. There's quite enough work to do with all the other languages as it is.


[TODO: Explain ground rules; that I'm using standard libraries wherever possible, that sort of thing.]

[TODO: Talk a bit about Alan 2 and Alan 3]

[TODO: Talk a bit about Hugo]

[TODO: Talk a bit about Inform 6]

[TODO: Talk a bit about Inform 7]

[TODO: Talk a bit about TADS 2]

[TODO: Talk a bit about TADS 3]


[TODO: Explain my own syntax]

token?     token is optional; may occur 0 or 1 times.

token+     token is required, and may occur several times.

token*     token is optional, yet may occur several times.

NL     literal newline.

« Notation

« Overview

« Hello, World! (sample)

 Hugo 

routine main
{
  print "Hello world"
  pause
  quit
}

Inform 6

[ Main; print "Hello world^"; ];

Inform 7

"Hello World" by John Smith

Hello World is a room.

TADS 3

#include "tads.h"
main(args)
{
  "Hello from TADS 3!!!\b";
}

Alan 2 TADS 2

TODO

« Game template

Alan 2

[OPTIONS option+]? unit+ start

 Hugo  Inform 6 TADS 2 TADS 3

TODO

« Pre-processing

« Comments

Alan 2

-- This is a comment in Alan.

-- There is no multi-line comment form in Alan.

 Hugo 

! This is a single-line comment in Hugo.

!\
  And this is a multi-line comment
  Which goes across more than one line.
\!

Inform 6

! This is a comment in Inform 6.

! There is no multi-line comment form in Inform 6.

Inform 7

[ This is a comment in Inform 7. ]

[ And this is a multi-line comment
  Which goes across more than one line. ]

[* This type of comment turns into a footnote. ]

TADS 2 TADS 3

// This is a single-line comment in TADS.

/*
  And this is a multi-line comment
  Which goes across more than one line.
*/

« Line breaks & line conjoins

Alan 2 Inform 6 TADS 2 TADS 3

Non-applicable issue for most languages. Alan statements end in periods; Inform and TADS statements end in semi-colons. How you format your code is up to you.

 Hugo 

Hugo statements have no terminator character; the end of the line marks the end of a statement.

Use \ at the end of a line to split a statement onto two or more lines; the backslash is optional in long string constants broken over multiple lines.

Use : to put two or more statements onto the same line.

« Include statements

Alan 2

$INCLUDE 'filename'

Inform 6

Include "filename";

Include ">shortname";

Use #Include (with the #) if using the directive inside a routine.

 Hugo  TADS 2 TADS 3

TODO

« Conditionals

Inform 6

[Ifdef name; | Ifndef name; | Iftrue condition; | Iffalse condition;] NL stmts NL [Ifnot; NL stmts NL]? Endif;
Default name value;
Stub name number;

Alan 2  Hugo  TADS 2 TADS 3

TODO

« Pragmas

Alan 2

Closest equivalent is the optional Options Section at the beginning of an Alan source file. The Options Section begins with the word OPTIONS followed by one or more option statements:

Note that an interpreter may override the Width and Length options, and that debugging may be enabled instead by a compiler option.

Inform 6

Replace SomeRoutine;
System_file;
Message [error | fatalerror | warning]? "message";
Release number;
Serial "dddddd";

 Hugo  TADS 2 TADS 3

TODO

« Macros

TODO

« Literals/Constants

« Binary Constants

Alan 2

n/s. Use 1 and 0.

 Hugo  Inform 6

true and false (which are equal to 1 and 0, respectively)

TADS 2 TADS 3

true and nil

« Character Constants

Alan 2 TADS 2 TADS 3

In Alan and TADS, there is no distinct Character datatype. Just use one-character string constants; eg:  "x" in Alan, or 'x' in TADS.

 Hugo  Inform 6

eg:  'x'

In Inform, be careful not to confuse character constants with dictionary words.

« Dictionary Words

Alan 2

n/a. Use normal and quoted variables in NAME phrases. Also, see the SYNTAX construct.

 Hugo 

eg:  "x" "joe's" "silver" "keys"

Always in doublequotes. Doesn't use Inform's //p, etc.

Inform 6

eg:  'x//' 'joe^s' 'silver' 'keys//p'
or "x" "joe^s" "silver" "keys//p"

The single-quoted syntax is the preferred form. Use ^ for an apostrophe, eg: 'joe^s'. Append // for a single-character dictionary word, eg: 'c//'. Append //p for a word that is always plural, eg: 'keys//p'. Nine character resolution; note that digits and typewriter symbols count as two characters, and accented characters even more.

TADS 2 TADS 3

n/a. Use string constants, eg:  'x' 'joe\'s' 'silver' 'keys'.

« Integers

 ALL   Alan 2  Hugo 

All languages understand simple decimal notation, eg:  4205

For Alan and Hugo, this is the only integer notation format.

Inform 6

hex example:  $3f08 (begins with $)

binary example:  $$1000111010110 (begins with $$)

TADS 2 TADS 3

hex example:  0x3f08 (begins with 0x)

octal example:  035 (begins with 0)

« Integer Range

 Hugo  Inform 6 Inform 7

−32768 to 32767

TADS 2 TADS 3

−2147483648 to 2147483647 (signed 32-bit integer)

Alan 2

TODO

« Real Numbers / Floating Point

Alan 2  Hugo  Inform 6 Inform 7 TADS 2

n/s. Most IF languages don't provide any native support for real numbers or floating point arithmetic. It's almost never necessary.

TADS 3

Supported via the BigNumber class, able to represent values from 10−32,767 to 1032,767. (See t3_doc\t3bignum.htm)

« Strings

« String Constants

Alan 2  Hugo  Inform 6 Inform 7

"This is a string constant."

TADS 2 TADS 3

'This is a string constant.'

Note that a doublequoted string in TADS is not a string constant; it is a directive to print the string.

« Character Codes in Strings

Alan 2

Use "" for a doublequote, eg: "Bob says, ""Hi!"""

Use $n for a newline.

Use $z for a literal dollar-sign. (Actually, put any character after the $, as long as that combo doesn't mean anything to Alan.)

 Hugo 

Use \" for a doublequote, eg: "Bob says, \"Hi!\""

Use \n for a newline; use \\ for a literal backslash.

Accents, eg:  \`a = à; \'e = é; \^o = ô; \:u = ü; \,c = ç; \~n = ñ.

Also:  \< = «; \> = »; \! = ¡; \? = ¿; \ae = æ; \AE = Æ; \c = ¢; \L = £; \Y = ¥; \- = — (em-dash).

And, \#xxx = any ASCII character where xxx is its 3-digit number.

Inform 6

Use ~ for a doublequote, eg: "Bob says, ~Hi!~"

Use ^ for a newline, eg: "Line one^Line two"

Accents, eg:  @`a = à; @'e = é; @^o = ô; @:u = ü; @,c = ç; @~n = ñ; @oa = å; @\o = ø.

Also:  @<< = «; @>> = »; @!! = ¡; @?? = ¿; @ae = æ; @AE = Æ; @oe = œ; @OE = Œ; @ss = ß; @LL = £; @th = þ; @Th = Þ; @et = ð; @Et = Ð.

And, @@num for other characters, where num is the ZSCII value, eg: @@92 = \; @@64 = @; @@94 = ^; @@126 = ~.

Plus, @{hhhh} is a Unicode character, where hhhh is its hex value. Unfortunately, few interpretors (if any) support Unicode.

TADS 2

Use \" for a doublequote; \' for apostrophe.

Use \n for a newline; use \\ for a literal backslash.

Use \< for < (to disambig. vs. <<).

Use \- followed by any two bytes to pass those bytes literally (eg: for multi-byte characters like Japanese).

if using HTML-TADS:

Use &amp; for &; &lt; for <; &gt; for >.

Use named entities like &eacute; and &pound; to get special characters like é and £.

TADS 3

Similar to TADS 2, except that it's always in HTML mode, so entity codes like &amp; for '&', etc. is now required. Also, \- is no longer used; instead use Unicode characters, eg: \uABCD, where ABCD is the hexadecimal code value.

« Controls Embedded in Strings

Alan 2

$p = New paragraph (one empty line)
$i = Indent on a new line.
$t = Insert a tabulation.
$$ = Do not insert a space.

 Hugo 

\_ = Forced space (overrides left-justification).
\B = Boldface on; \b = Boldface off.
\I = Italics on; \i = Italics off.
\U = Underlining on; \u = Underlining off.
\P = Proportional font on; \p = Proportional off.

Inform 6

\ = For "folding lines" (no longer needed).

TADS 2

\b = Insert a blank line.
\t = Insert a tab.
\space = Literal space; overrides default spacing.
\^ = Capitalize next letter; \v = lowercase next letter.
\( = Highlighting on; \) = Highlighting off.
\H+ = HTML-TADS on; \H- = HTML-TADS off.
(if using HTML-TADS:)
Several HTML tags, like <b>, <i> and <font> are supported, plus a few tags unique to HTML-TADS, eg: <sound>.

TADS 3

TODO

« Variables Embedded in Strings

Alan 2

$l = name of current Location
$v = verb that player used (first word)
$a = The name of the actor that is executing
$o = The current object (first parameter)
$n = The parameter with number n, where n is a digit.

 Hugo 

n/a.

Inform 6

@00 to @31 = String constants set via Inform's string statement.

TADS 2

<<expr>> = Evaluate the expression. It must evaluate to a number or a string (single or doublequoted). This feature only in doublequoted strings, and may not be nested.

TADS 3

<<expr>> evaluates expr just like in TADS 2, still only useable in doublequoted strings.

{the dobj/he} is an example of the new substitution codes, useable in both single and doublequoted strings.

« Variables

« Identifiers, Case sensitive?

Alan 2

No: Normal identifiers are not case sensitive.
Yes: Quoted identifiers are case sensitive.

 Hugo  Inform 6

No. room101 is the same name as Room101.

TADS 2 TADS 3

Yes. showSum is distinct from showsum and ShowSum.

« Identifiers, Legal

Alan 2

Normal identifiers must not start with a digit. May contain letters, digits or underscores. Max length TBD.

There are also quoted identifiers, which must begin and end with single-quotes, and may contain any character (including spaces). Note that there are several restrictions on when and how to use quoted identifiers.

 Hugo  Inform 6

Identifiers must not start with a digit. May contain letters, digits or underscores. Can be up to 32 characters long.

TADS 2

Identifiers must start with a letter. May contain letters, digits, dollar signs, or underscores. Can be up to 39 characters long.

TADS 3

TODO. Can be up to 40 characters long.

« Datatypes

TODO

« Predefined Variables

TODO

« Reserved Words

TODO

« Expressions & Operators

« Arithmetic Operators

« pre- & post-increment • pre- & post-decrement

Alan 2

n/s. Use:  SET a TO a + 1.   •   SET a TO a - 1.

 Hugo  Inform 6 TADS 2 TADS 3

++a   and   a++   •   --a   and   a--

« unary negation

Alan 2

-a   (but only supported in certain contexts?)

 Hugo  Inform 6 TADS 2 TADS 3

-a

« multiplication • integer division • addition • subtraction

 ALL  

a * b   •   a / b   •   a + b   •   a - b

Inform 7

I7 understands both *, /, +, and -, and the following forms as well:

a multiplied by b   •   a divided by b   •   a plus b   •   a minus b

« remainder (aka modulus)

Alan 2

Use:  (a - ((a / b) * b))

 Hugo 

Use:  mod(a, b)

Inform 6 TADS 2 TADS 3

a % b

Inform 7

remainder after dividing a by b

« Array/List

« declaration of an array

Alan 2

n/a

 Hugo 

array arrayname [ size ] (elements 0 to size−1)
(to initialize:)
arrayname [ startindex ] = val [, val]*

Arrays may contain a mix of datatypes. Local arrays are illegal.

Inform 6

(property array:)
propertyname val+
(global array:)
Array arrayname --> size ; (empty array; 0 to size−1)
Array arrayname --> val val* ; (filled array)
Array arrayname --> "chars" ; (char array)
Array arrayname table size ; (empty wordarray; puts size in arrayname-->0; elements 1 to size.)
Array arrayname string "chars" ; (char bytearray; puts length of string in arrayname->0; elements 1 to length.)

Replace --> with -> to get a byte array. Wordarray elements may be integers, strings, chars, dictionary words, or object references. Bytearray elements may only be integers from 0 to 255, or chars.

Inform 7

Use tables as directed in chapter 14. Tables are declared in a single paragraph with no blank lines inbetween rows.
The first row must be the title line in one of three formats, eg:

Table code
Table of whatever

The second row must be the column header names separated by tabs.

The remaining rows are the table entries, columns separated by tabs.

All values in a column must have mutually compatible datatypes, eg: you can't have strings and numbers in the same column.

Rows are numbered from 1; columns are refered to by their names.

Table code - whatever

TADS 2

[ listitem* ]

Lists may be empty. Lists may contain a mix of subtypes. Listitems may be explicitly separately by commas. If the list is the value of a property, all listitems in the list must be constant values (eg: integers, single-quoted strings, constant lists); otherwise, a list may contain expressions.

TADS 3

[ ]   (for an empty list)

[ listitem [, listitem]* ]

Same as in TADS 2, except listitems must be separated with commas. If the list is the value of a property, all listitems in the list must still be constant values; however, the compiler will translate
theProp = [rand(3), foo.location]   into
theProp { return [rand(3), foo.location]; }

« element of an array

Alan 2

n/a

 Hugo 

array [ index ]     (first element is index 0)

Inform 6

wordarray --> index
bytearray -> index     (first element is index 0)

TADS 2 TADS 3

list [ index ]     (first element is index 1)

« property array

That is, how to refer to an array/list when it's the value of an object's property.

Alan 2

n/a

Inform 6

object .& arrayproperty

TADS 2 TADS 3

object . property

 Hugo 

TODO

« property array size

Alan 2

n/a

 Hugo 

array[] returns array's length.

Inform 6

object .# arrayproperty
(Note: Returns length of a bytearray, or 2×length of a wordarray.)

TADS 2

length(list)

TADS 3

list.length()

« list concatenation • list subtraction

Alan 2

Neither are applicable.

 Hugo 

TODO

Inform 6

Neither are supported.

TADS 2 TADS 3

a + b       a - b

where a must be a list; b must be either a list or a dataitem that can be in a list.

« Assignment

« set equal to

Alan 2

Use:  SET a TO b.

 Hugo  Inform 6 TADS 3

a = b

TADS 2

a := b     (default style)
a = b     (C mode style)

« op= (combination assignment ops)

Alan 2

Use:  SET a TO a op b.

 Hugo 

+= -= *= /= &= |=

Inform 6

Use:  a = a op b

TADS 2 TADS 3

+= -= *= /= %= &= |= ^= <<= >>=

« Bitwise

« bitwise AND • bitwise OR • bitwise NOT

Alan 2

Not supported.

 Hugo  Inform 6 TADS 2 TADS 3

a & b     a | b     ~a

« bitwise XOR

Alan 2

Not supported.

 Hugo  Inform 6

Use:  ((a | b) & ~(a & b))

TADS 2 TADS 3

a ^ b

« left shift • right shift

Alan 2  Hugo 

Not supported.

Inform 6

(ZCode left shift:)  @log_shift a b -> result

(ZCode right shift:)  @log_shift a -b -> result

TADS 2 TADS 3

a << b     a >> b

« Class/Object

« is instance of class

Alan 2

object ISA class

Note: ISA is only useable in Syntax constructs.

Inform 6

object ofclass class

TADS 2

Use:  isclass(object , class)

TADS 3

object.ofKind(class)

 Hugo 

TODO

I note that object.type returns the value of object's primary class, but that's not quite the same thing.

« defines property

Inform 6

object provides property

TADS 2

Use:  defined(object, &property)

Note that a property pointer is passed to defined().

TADS 3

Use:  object.propDefined(&property)

Alan 2  Hugo 

TODO

« property of

Alan 2

property OF object

Inform 6 TADS 2 TADS 3

object . property

 Hugo 

TODO

« "superclass"

That is, how do we call (or access) the superclass's property (or method) from within the current object's property (or method)?

 Hugo 

class .. property

Inform 6

class :: property

TADS 2

I'm confused on this still. I've been told that pass prop; is equivalent to return inherited(args); where args are the parameters passed to the current method.

It might also be valid to either use inherited.property or inherited class.property as appropriate.

TADS 3

TODO. TADS 3 doesn't use TADS 2's pass statement.

Alan 2

TODO

« has boolean attribute • hasn't boolean attribute

Alan 2

object IS attribute      object IS NOT attribute

 Hugo 

object is attribute      object is not attribute

Inform 6

object has attribute     object hasnt attribute

TADS 2 TADS 3

n/a. Use: object.property     !object.property

« is at/in • is not at/in

Alan 2

object IN obj2   •   object NOT IN obj2

object AT location   •   object NOT AT location

object HERE   •   object NOT HERE

object NEARBY   •   object NOT NEARBY

 Hugo 

object in obj2   •   object not in obj2

Inform 6

object in obj2   •   object notin obj2

TADS 2

Use:  object.location = obj2   •   object.location <> obj2

TADS 3

object.isIn(obj2)     indirect containment

object.isDirectlyIn(obj2)     direct containment

Although T3 still uses the location property, you are advised not to fiddle with it directly. See also in the Thing class: isNominallyIn(obj), isInFixedIn(loc), isHeldBy(actor), isOwnedBy(obj). (Negate with ! like any other T3 expression.)

« first child • last child

 Hugo 

child(parentObj) or eldest(parentObj)   •   youngest(parentObj)

Inform 6

child(parentObj)   •   n/s

Alan 2 TADS 2 TADS 3

TODO

« previous sibling • next sibling

 Hugo 

elder(childObj)   •   sibling(childObj) or younger(childObj)

Inform 6

n/s   •   sibling(childObj)

Alan 2 TADS 2 TADS 3

TODO

« child total

 Hugo  Inform 6

children(parentObj)

Alan 2 TADS 2 TADS 3

TODO

« parent

 Hugo  Inform 6

parent(childObj)

TADS 2

Use:  object.location

Alan 2 TADS 3

TODO

« Logical
  logical AND • logical OR • logical NOT

Alan 2

a AND b   •   a OR b   •   n/s.

For logical not, use NOT as a modifier of another operation. For example, instead of NOT(x = y), use x NOT = y. And instead of NOT(x IS male AND y AT House), use x IS NOT male OR y NOT AT House.

 Hugo 

a and b   •   a or b   •   not a

Inform 6

a && b   •   a || b   •   ~~a

TADS 2

a and b   •   a or b   •   not a

a && b   •   a || b   •   !a   (alternate syntaxes)

TADS 3

a && b   •   a || b   •   !a

« Relational

« equal to • not equal to

Alan 2

a = b   •   a <> b

 Hugo 

a = b   •   a ~= b

Inform 6

a == b   •   a ~= b

TADS 2

a = b   •   a <> b     (default style)

a == b   •   a != b     (C mode syntax)

TADS 3

a == b   •   a != b

« less than • less than or equal to • greater than or equal to • greater than

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

a < b   •   a <= b   •   a >= b   •   a > b

« between...and

Alan 2

x BETWEEN a AND b

Inform 6 TADS 3

Use:  a <= x && x <= b

TADS 2

Use:  a <= x and x <= b

 Hugo 

TODO

« Strings
  string concatenation

Inform 6

n/a

TADS 2 TADS 3

a + b   where a must be a string.

Alan 2  Hugo 

TODO

« Other Operations

« address of

Alan 2 Inform 6

n/a

 Hugo 

&function     &object.property

TADS 2

&function     &property

TADS 3

&property

« conditional

Alan 2

n/s. Use an IF statement.

Inform 6

n/s. Use an if statement.

TADS 2 TADS 3

a ? b : c

 Hugo 

TODO

« conjunction

Inform 6 TADS 2 TADS 3

a , b

Alan 2  Hugo 

TODO

« pointer dereference

Alan 2 Inform 6

n/a

TADS 2

(pointer)     eg:  obj.(propPtr)(actor);

 Hugo  TADS 3

TODO

« "or" extender

Alan 2

TODO

 Hugo 

a , b

eg:  if x = 2, 3, 5, 7, 11

Inform 6

a or b

eg:  if (player in Forest or House or Lake)

TADS 2

n/s. Write the condition in full.

TADS 3

(a , b)   in conjuntion with   is in or not in.

eg:  if (cheese is in (brie, cheddar, swiss))

« Functions

« Function Example

Inform 6

[ addlist arg1 arg2   sum count i;
  ...statements...
  return sum;
];

TADS 2

addlist: function(arg1, arg2)
{
  local sum, count, i;
  ...statements...
  return(sum);
}

TADS 3

function addlist(arg1, arg2)
{
  local sum, count, i;
  ...statements...
  return sum;
}

Alan 2  Hugo 

TODO

« Common Functions

TODO: array call capital dict hex number playback random readval recordoff recordon restart restore runevents save scriptoff scripton string system

« Statements

« stmt-block

Alan 2

stmt*

 Hugo 

{ stmt [NL stmt]* }

Inform 6 TADS 2 TADS 3

{ stmt+ }

« break-stmt

Alan 2

n/a.

 Hugo 

break

Inform 6 TADS 2

break ;

TADS 3

break label? ;

« call-stmt

 Hugo 

call var [( expr [, expr]* )]?

run object.property

Alan 2 Inform 6 TADS 2 TADS 3

TODO

« clear-screen-stmt

Alan 2

n/s. Print a string with 24 \n in it.

 Hugo 

cls

Inform 6

(Z-Code:)  @erase_window window

window should be 0 for lower window, 1 for upper, −1 for entire screen.

TADS 2

clearscreen();

TADS 3

clearScreen();     (see tadsio.h)

« continue-stmt

Alan 2

n/a.

Inform 6 TADS 2

continue ;

TADS 3

continue label? ;

 Hugo 

TODO

« do-stmt

Alan 2

n/a.

 Hugo 

do stmt NL while expr

Inform 6

do stmt until ( expr ) ;

TADS 2 TADS 3

do stmt while ( expr ) ;

« for-stmt

Alan 2

n/a.

Inform 6

for ( expr? : expr? : expr? ) stmt

Inform 7

repeat with var running from expr to expr begin; stmts; end repeat.

See 10.9,

 Hugo  TADS 2

for ( expr? ; expr? ; expr? ) stmt

TADS 3

for ( initlist ; expr? ; expr? ) stmt

where   initlist   →   init [, init]*

and   init   →   local? id = expr

« goto-stmt

Alan 2

n/a

 Hugo 

jump label

Inform 6

jump label ;

TADS 2 TADS 3

goto label ;

« if-stmt

Alan 2

IF expr THEN stmt* [ELSIF expr THEN stmt*]* [ELSE stmt*]? END IF.

 Hugo 

if expr NL stmt [NL elseif expr NL stmt]* [NL else stmt]?

Inform 6 TADS 2 TADS 3

if ( expr ) stmt [else stmt]?

Inform 7

if condition [then | ,] phrase [; otherwise phrase]

if condition begin; phrases; [otherwise; phrases;] end if

See 10.5, 10.7, 10.8. Note: else can be used instead of otherwise.

« input-stmt

 Hugo 

input
pause

TODO: explain what input and pause do.

TADS 3

Kwi tells me, "when using the standard library, you should call inputManager methods instead of inputLine() etc., to ensure that any pending output is displayed first." Which means that this section needs a TODO label stuck on it. :(

inputLine()   (read a line of text from the keyboard)

inputKey()   (read a single keystroke from the keyboard)

inputEvent(timeout?)   (read a single input event)

inputDialog(icon, prompt, buttons, defaultBtn, cancelBtn)   (display dialog)

inputFile(prompt, dialogType, fileType, flags)   (display a file selector dialog)

inputLineTimeout(timeout?)   (read a line from the keyboard with optional timeout)

inputLineCancel(reset)   (cancel an input line that was interrupted by timeout)

(all are intrinsic functions; see tadsio.h and t3tadsio.htm)

Alan 2 Inform 6 TADS 2

TODO

« label-stmt

Alan 2

n/a

 Hugo 

: label

Inform 6

. label ;

TADS 2

label : ;

TADS 3

TODO

« local-stmt

Alan 2

n/s. Declare "local variables" as other attributes in your Objects, Locations, and Actors.

Inform 6

n/a. A function's local variables are declared as part of the function's declaration frame.

 Hugo 

local var [, var]*

TADS 2 TADS 3

TODO

« move-object-stmt

Alan 2

To move an object (or the Hero) normally:
LOCATE object where_clause.
To remove an object from the game, create a Location that the Hero can't reach and Locate the object there (NOWHERE is part of std.i):
LOCATE object AT NOWHERE.
A where_clause is one of IN object, AT location, HERE, or NEARBY.

 Hugo 

move obj to loc

remove obj

Inform 6

move obj to loc ;

remove obj ;

TADS 2

obj.moveInto(loc)

TADS 3

obj.moveInto(loc)   (for normal movement)

obj.mainMoveInto(loc)   (for teleport-style moves)

Move things to nil to remove them from the game world.

(There is also obj.moveIntoForTravel(loc), but I haven't figured that one out yet.)

« object-loop-stmt

Alan 2

n/s. Depending on what you're trying to do, you may be able to use one of the aggregates COUNT, SUM OF property, or MAX OF property; eg: SET total_weight OF Hero TO 50 + SUM OF weight IN INVENTORY. Use LIST object. to list contents of a container. Use EMPTY object to obj2. to transfer objects.

 Hugo 

for var in object NL stmt

Inform 6

objectloop condition stmt

Inform 7

repeat with var running through expr begin; stmts; end repeat.

See 10.10.

TADS 2 TADS 3

TODO

« open-file-stmt

 Hugo 

readfile filename NL stmt

Opens a file for reading at the beginning of the block, and closes the file at the end.

Inform 6

(if ZCode, use one of:)
@input_stream n     0=keybd; 1=file
@output_stream n array?     ±1=screen; ±2=script file; ±3=array; ±4=cmnd file

Positive values open a stream; negative values, close. [see DM4 §42]

TADS 2

Use: fopen(filename, mode);

Alan 2 TADS 3

TODO

« play-sound-stmt (or music)

Alan 2

n/s

 Hugo 

music repeat? "file" , "song" [, vol]?
music 0
sound repeat? "file" , "sample" [, vol]?
sound 0

Inform 6

(if ZCode, z5 or z6 or z8:)

@sound_effect number effect? volrep? routine?     [see DM4 §42]

Also test if (($10-->0) & 128 ~= 0) then the player's interpreter can play sound.

TADS 2

(HTML-TADS:)  Use the <SOUND> tag:
"<sound src='resourcefile' layer=foreground|bgambient|ambient|background random=n repeat=n|loop sequence=replace|random|cycle interrupt cancel[=layer] alt='text' fadein=n fadeout=n>";

TADS 3

TODO

« print-stmt

 Hugo 

print print-arg [; print-arg]*

printchar var [, var]*

Alan 2 Inform 6 TADS 2 TADS 3

TODO

« print-image-stmt

Alan 2

n/s

 Hugo 

picture "resourcefile" , "picture"

picture "picturefile"

Inform 6 TADS 2 TADS 3

TODO

« print-newline-stmt

 Hugo 

print newline

Inform 6

new_line ;

TADS 2 TADS 3

"\n" ;

Alan 2

TODO

« quit-stmt

Alan 2

QUIT .

 Hugo 

quit

TADS 3

throw new QuittingException;

(TODO: for adv3 only? This needs more explanation.)

Inform 6 TADS 2

TODO

« return-stmt

Alan 2

n/a.

 Hugo 

return expr?

TADS 2 TADS 3

return expr? ;

Inform 6

TODO

« set-attribute-stmt • clear-attribute-stmt

Alan 2

MAKE item attribute .

MAKE item NOT attribute .

Inform 6

give object attribute ;

give object ~attribute ;

TADS 2 TADS 3

n/a. Use: object.property = true; (or nil)

 Hugo 

TODO

« set-colors-stmt

Alan 2

n/a.

 Hugo 

color foreground [, background [, input ]]

Inform 6

Z-Code:  @set_colour foreground background

TADS 2

HTML-TADS:  "<body bgcolor='background'><font color='foreground'>";

TADS 3

TODO

« set-cursor-position-stmt

Alan 2 TADS 2

n/s.

 Hugo 

locate ( row , column )

TADS 3

(TODO. TADS 3 has "TextGrid banners", I'm told.)

Inform 6

TODO

« switch-stmt

Alan 2

DEPENDING ON lexpr case-clause* default-clause? END DEPENDING.

where   case-clause   →   rexpr : stmt*

and   default-clause   →   ELSE : stmt*

 Hugo 

select expr case-clause* default-clause?

where   case-clause   →   NL case const [, const]* NL stmt

and   default-clause   →   NL case else NL stmt

Note: Avoid an expr with side-effects; it is executed for every case in the select.

Inform 6

switch ( expr ) { case-clause* default-clause? }

where   case-clause   →   case const [, const]* : stmt*

and   default-clause   →   default : stmt*

TADS 2 TADS 3

switch ( expr ) { case-clause* default-clause? }

where   case-clause   →   case const-expr : stmt*

and   default-clause   →   default : stmt*

« while-stmt

Alan 2

n/a.

 Hugo 

while expr NL stmt

Inform 6 TADS 2 TADS 3

while ( expr ) stmt

« Meta-Game

« Game ID

Game's Name

Game's Subtitle

Game's Date

Game's Version

Author Info

« Initialization

« Initial Location

Alan 2

This is the first line of the Start section, eg:
START AT Kitchen.

Inform 6

Set the value of location in the Initialise function, eg:
location = Bedroom;

TADS 2

The ID of the initial location must be startroom, eg:
TODO

 Hugo  TADS 3

TODO

« Intro Text (& Setup Code)

Alan 2

Put intro text in the Start section, after the "START AT" statement.

 Hugo 

TODO

Inform 6

Put intro text in the Initialise function.

TADS 2 TADS 3

TODO

« Language

« English and Non-English Support

Alan 2

Supports either English or Swedish games via the Language option. According to the Alan manual: "Other non-English languages may be supported in the future depending on demand."

 Hugo 

English only. Maybe. The Hugo manual doesn't seem to address this topic.

Inform 6

For a non-English Inform game, one must replace (at minimum) both the english.h and grammar.h files with language-specific versions. Versions of these files have been written in other languages, including French, German, Italian, and even Lojban. There exists a Spanish variant of Inform called InformATE. It helps if the target language is close to English in structure and alphabet. It would be very difficult to create Inform language files for Arabic or Japanese.

TADS 2

At minimum, a non-English TADS game would require one to replace/rewrite both the adv.t and std.t files. I'm not at all certain if that is sufficient or not. Still, TADS seems to be have the most potential for non-English language support: there was a Chinese game in TADS3 [**check this**], released in 2002.

TADS 3

TODO

« Verb Tense / Voice / Dialect

Alan 2  Hugo  Inform 6 TADS 2

All standard libraries of all four languages assume 2nd person and present tense. Changing the default voice and verb tense is a similar job to changing the language: editing/replacing the library files. It is simpler in one respect, in that you only need worry about output, not input.

TADS 3

2nd person and present tense are still the defaults.

To change Voice:  Actor.pcReferralPerson = FirstPerson (or ThirdPerson).

To change Tense:  TODO.

« Meta-Verbs

« ABOUT

(includes AUTHOR, CREDITS, INFO, INFORMATION, INSTRUCTIONS, LICENSE)

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« AMUSING

(includes ENDNOTES)

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« BRIEF/VERBOSE

(includes LONG, SHORT, SUPERBRIEF, TERSE)

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« FOOTNOTE

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« HINTS

(includes HELP, HINT, MENU, WALKTHROUGH, WALKTHRU)

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« NOTIFY

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« OOPS

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« QUIT

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« RESTART

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« RESTORE

(includes LOAD)

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« SAVE

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« SCORE

(includes FULL SCORE, FULLSCORE, STATUS)

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« TRANSCRIPT

(includes SCRIPT, UNSCRIPT)

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« UNDO

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« VERSION

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« Input

« Command Grammar Syntax (Verbs)

Inform 6

Verb meta? verbWord+ grammarLine+ ;

Extend only? verbWord [first | last | replace]? grammarLine+ ;

where

  verbWord  →  dictionaryWord

  grammarLine  →  * grammarToken* -> actionID reverse?

Predefined English Verb directives are in grammar.h.

TADS 3

VerbRule(VerbTag) grammarLine : VerbTagAction

  verbPhrase = 'verb/verbing (what)? prep* (what)?'

  propertyDefinition*

;

where

  grammarLine  →  ( grammarLine )  OR  grammarLine | grammarLine  OR  grammarToken*

Note that VerbRule is a macro defined in en_us.h, where VerbRule(tag) becomes grammar predicate(tag):; and grammar itself seems to be macro, whose definition eludes me. Predefined English VerbRules are in en_us.t.

Alan 2  Hugo  TADS 2

TODO

« Object Grammar Syntax (Nouns)

TADS 3

'adjective* noun[/noun]* [* pluralnoun+]?'

eg:  'painted framed picture/portrait*pictures portraits'

Note 1: Put brackets around a vocabword to mark it as a "weak" word.

Note 2: Use a hyphen character by itself to represent no noun.

Alan 2  Hugo  Inform 6 TADS 2

TODO

« Grammar Tokens

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« Parsing Variables

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« Synonyms

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« Verbs, Pre-defined

Inform 6

debugging metaverbs:  abstract, actions, changes, daemons, gonear, goto, messages, purloin, random, recording, replay, routines, scope, showobj, showverb, timers, trace, tree.

metaverbs:  brief, die, full, fullscore, long, normal, noscript, notify, nouns, objects, places, pronouns, q, quit, restart, restore, save, score, script, short, superbrief, transcript, unscript, verbose, verify, version.

game verbs:  adjust, answer, ask, attach, attack, awake, awaken, blow, bother, break, burn, buy, carry, check, chop, clean, clear, climb, close, consult, cover, crack, cross, curses, cut, d, damn, darn, describe, destroy, dig, discard, display, disrobe, dive, doff, don, down, drag, drat, drink, drop, dust, e, east, eat, embrace, empty, enter, exit, examine, fasten, feed, feel, fight, fill, fix, fondle, fuck, get, give, go, grope, hear, hit, hold, hop, hug, i, in, inside, insert, inv, inventory, jump, kill, kiss, l, leave, lie, light, listen, lock, look, move, murder, n, nap, ne, no, north, northeast, northwest, nw, offer, open, out, outside, pay, peel, pick, polish, pray, present, press, prune, pull, punch, purchase, push, put, q, quit, read, remove, rotate, rub, run, s, say, scale, screw, scrub, se, search, set, shed, shift, shine, shit, shout, show, shut, sing, sip, sit, skip, sleep, slice, smash, smell, sniff, sod, sorry, south, southeast, southwest, speak, squash, squeeze, stand, sw, swallow, sweep, switch, swim, swing, take, taste, tell, think, throw, thump, tie, torture, touch, transfer, turn, twist, u, uncover, undo, unlock, unscrew, unwrap, up, w, wait, walk, wake, watch, wave, wear, west, wipe, wreck, x, y, yes, z.

other verbs: again, amusing, g, o, oops.

TADS 3

debugging verbs: debug.

game verbs: a, about, activate, affirmative, aft, again, ask, attack, attach, back, blow, board, break, buckle, burn, bye, clean, climb, close, connect, consult, consume, credits, cut, d, deactivate, destroy, detach, dig, disconnect, disembark, drag, drink, drop, doff, don, douse, down, e, east, eat, enter, examine, exit, exits, extinguish, f, fasten, feel, find, flip, follow, footnote, footnotes, fore, foreward, full, fullscore, g, get, give, go, greet, good, good-bye, goodbye, hear, hi, hint, hints, hit, hello, holler, i, ignite, imbibe, in, inspect, inventory, jump, kick, kiss, kill, l, leave, lie, light, listen, lock, look, move, n, ne, negative, no, north, northeast, northwest, note, notify, nw, o, offer, oops, open, out, p, pause, pick, place, plug, port, pour, press, pull, punch, push, put, q, quaff, quit, read, record, remove, replay, restart, restore, return, rotate, rq, ruin, s, save, say, sb, score, scream, screw, script, se, search, set, shout, show, shut, sit, sleep, smell, sniff, south, southeast, southwest, stand, starboard, status, strike, sw, switch, t, take, talk, taste, tell, terse, throw, topics, toss, touch, turn, twist, type, u, undo, unbuckle, unfasten, unlock, unplug, unscrew, unscript, up, verbose, version, w, wait, walk, wear, west, wreck, x, yell, yes, z.

Alan 2  Hugo  TADS 2

TODO

« Output

« Alignment

Alan 2

Left justified only. Manual spacing won't work because Alan compresses multiple spaces before displaying text. But use $t in a string to print a tab.

 Hugo  Inform 6 TADS 2 TADS 3

TODO

« Box Quotes

Alan 2

n/s. Best you can do is put something like $n$t in front of each line of the quote.

Inform 6

box string+ ;

TADS 3

Use the <blockquote> and </blockquote> tags. May be abbreviated to <bq> and </bq>. Use <credit> and </credit> around the last line of the quote if it credits the quote's author.

 Hugo  TADS 2

TODO

« Characters, Non-ASCII

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« Colors

Alan 2

n/s. Can't specify colors.

Inform 6

TODO. Obviously the color capabilities of the Z-machine are much more limited than Glulx's.

 Hugo  TADS 2 TADS 3

TODO

« Fonts

Alan 2

n/s. Can't specify the text font within the program. If you want to use ASCII graphics, you'll have to ask the player to make sure his Alan interpreter is using a fixed-width font, and play the entire game that way.

 Hugo  Inform 6 TADS 2 TADS 3

TODO

« Graphics / Images

Alan 2

n/s. No graphics support as yet.

Inform 6
Z-Code: TODO (v6 only)
Glulx-Code:
glk_image_draw(window, image, val1, val2)
glk_image_draw_scaled(window, image, val1, val2, width, height)

 Hugo  Inform 6 TADS 2 TADS 3

TODO

« Panels

Alan 2

Fixed two-panel layout: main text panel and status bar panel at top. No control over status bar's contents. In the Options Section of your program, you may specify a Width of line to display, and a Length value representing how many lines to display before a <More> prompt, but an interpreter may ignore these options.

 Hugo  Inform 6 TADS 2 TADS 3

TODO

« Sound

Alan 2

n/s. No sound support as yet.

Inform 6
Z-Code: TODO (v6 only)
Glulx-Code:
glk_schannel_play(channel, sound)
glk_schannel_play_ext(channel, sound, repeats, notify)

 Hugo  TADS 2 TADS 3

TODO

« Text Styles (Bold and Italic)

Alan 2

n/s. Can't specify boldness or italics.

 Hugo 

\B = Boldface on; \b = Boldface off.

TADS 2 TADS 3

<b> = Boldface on; </b> = Boldface off; <i> = Italics on; </i> = Italics off.

Inform 6

TODO

« World Model

« Common Attributes and Properties

« Articles (a, an, the)

Inform 6

By default, Inform attempts to guess "a" or "an" for the indefinite article based on the item's short name's first character. Give the proper attribute to an item if no article is appropriate. Set the article property of an item to the appropiate string value to override the default indefinite article. Set the articles property of an item to a list of string values to explicitly declare all articles of an item (this last is meant for non-English games). Use the (The), (the), and (a) functions to print item's names with articles.

TADS 2

By default, the values of an item's adesc and thedesc properties are "a <<self.sdesc>>" and "the <<self.sdesc>>" respectively. Give these properties a new value to override their default values.

Alan 2  Hugo  TADS 3

TODO

« Description (Long)

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« Description (Short)

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« Floating items

Note: That is, objects found in multiple locations.

Alan 2

Locate your floating objects in pure containers, using the Container structure. Objects in pure containers are always where the Hero is. Create a matching storage object with the container property, and define a pair of rules to EMPTY the contents from pure container to storage container (and vice-versa) when appropriate. (See 6.10 of Alan manual.)

Inform 6

Define the object's found_in property as either a list of locations, or as a routine which returns true if the item should be found in location. Note that if a floating object is also given the absent attribute and the object removed, then the found_in property is ignored, and the object isn't anywhere.

TADS 2

Declare as of class floatingItem in addition to at least one other class. Only floatingItem objects may have a variable location property.

 Hugo  TADS 3

TODO

« Gender (male, female, neuter)

Alan 2

n/s. But it's simple to give Actors attributes like IS male or IS female.

 Hugo 

TODO

Inform 6

By default, animates are male, and all other objects are neuter.
Give the male, female, or neuter attribute to an object to indicate gender.

TADS 2

By default, all objects are neuter.
Set the isHim or isHer property of an object to true to indicate gender.

TADS 3

TODO

« Hidden / Concealed

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« Name

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« Plural

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« Transparency

Alan 2

n/s. Considering the need to empty out the contents of opaque containers to a storage container when the former is closed, transparent containers may be simpler. (Unless the transparent container can go in a closeable opaque one, in which case it becomes difficult again.)

 Hugo 

TODO

Inform 6

Give it the transparent attribute.

TADS 2

Declare it of class transparentItem. Or, if you just wish to "look through" it, declare it of class seethruItem and define its thrudesc method as appropriate.

TADS 3

Transparency in TADS 3 is modeled on the more general notion of sense-passing, in this case, with respect to the sense of sight. For the simple case where you want to make a container transparent, you probably want to set the container's material property to glass, e.g.: displayCase.material = glass. Glass is predefined as transparent to sight, but opaque to sound, smell, and touch. (Other predefined materials are adventium (which is the default and opaque to all senses), paper, fineMesh, and coarseMesh. See sense.t.)

« Things

« Clothing / Wearables

Alan 2

Declare a wearable object with the wearable attribute (see wear.i).
Locate it in the worn container to indicate that it's currently worn by the Hero (see invent.i).

Inform 6

Declare a wearable object with the clothing attribute.
Give the worn attribute to an object to indicate that it's currently worn by player. By default, worn affects only the player's clothing, not an NPC's.

TADS 2

Declare a wearable object as an instance of clothingItem class.
Set the item's isworn property to true to indicate that it's currently worn by its parent object.

TADS 3

Declare a wearable object as an instance of Wearable class (see objects.t).

Set the item's wornBy property to the object that's wearing it.

 Hugo 

TODO

« Containers

Inform 6

Give items the container attribute. If it is open, also give it the open attribute. If it's openable and closeable, also give it the openable attribute.

TADS 2

Declare items of class container or qcontainer. The latter is "quiet"; it doesn't list its contents in certain circumstances. Set its isopen property to true or nil as appropriate. If the container is also openable and closeable, also declare the container to be of class openable.

TADS 3

Declare with class BasicContainer, or Container, or one of Container's subclasses. Set its isOpen property to true or nil as appropriate. Use OpenableContainer for a container that is openable and closeable. Customize listing behaviour thru the properties isListed, isListedInContents, isListedInInventory, contentsListed, contentsListedSeparately, etc. (see Thing class).

Alan 2  Hugo 

TODO

« Creatures / Animates / NPCs

Alan 2

Declare creatures with the Actor construct.

Inform 6

Give creatures the animate attribute.

TADS 3

Declare creatures as instances of Actor, or one of its subclasses: UntakeableActor or Person.

 Hugo  TADS 2

TODO

« Doors

Alan 2

n/s. Section 6.4 of the Alan manual suggests defining two door objects, one for each side. Define the doors' VERB open clauses to open both sides simultaneously (MAKE side1 NOT closed. MAKE side2 NOTE closed.). Also, define the EXIT clauses in the rooms to CHECK side1 IS NOT closed.

Inform 6

Give a door object the door, static, and openable attributes, and if applicable, the open and lockable attributes. Set the appropriate exits in the rooms to point to the door itself, eg: n_to green_door. Set the door's door_to property to the destination room, and the door's door_dir property to the direction, eg: n_to. Optionally, define the door's when_open and when_closed properties.
Typically, an Inform door is also defined as a floating item; set its found_in property to a list of the two rooms that the door is found in. If you do this, remember to make the door's door_to and door_dir properties into routines to return the appropriate value based on self.location.

TADS 3

Most doors should be declared as instances of class Door. (Other possibilities include SecretDoor, HiddenDoor, and AutoClosingDoor.) For normal two-way doors, declare a pair of Door objects, one for each side of the door. One side will be the 'master'; set the other side's masterObject property to the first side. For one-way doors, you will need to set the destination property of the door. Since a Door is also a TravelConnector, you can easily associate a Door with its direction of travel by setting the appropriate direction property of the room with the door, e.g.: north = bedroomDoor

 Hugo  TADS 2

TODO

« Exits

Alan 2  Hugo  Inform 6 TADS 2 TADS 3

TODO

« Food / Edibles

Note: Food only, not drinks (see Liquids). By default, edible objects are removed from the game when eaten.

Alan 2

If using std.i, use IS edible.

 Hugo 

TODO

Inform 6

Give the edible attribute to a object that can be eaten. Nourishment is not modeled.

TADS 2

Declare an edible object as a member of fooditem class. Also, global.lastMealTime is decremented by the item's foodvalue property. By default, the foodvalue property is set to global.eatTime.

TADS 3

Declare an edible object as an instance of Food class. Nourishment is not modeled.

« Keys

Alan 2

n/s.

 Hugo 

TODO

Inform 6

n/s. To associate a key with the thing it unlocks, set the lockable object's with_key property to the key object.

TADS 2

Declare a key of class keyItem. To associate a key with the thing it unlocks, set the keyLockable item's myKey property to the key object.

TADS 3

Declare a key of class Key (extras.t). To associate a key with the thing it unlocks, set the LockableWithKey item's keyList property to a list of key objects, eg: frontDoor.keylist = [ brassKey, masterKey ]

« Light / Lit

Alan 2

n/s. Section 6.11 of the Alan manual suggests this approach. First, declare the default attributes for objects and locations as:

Object Attributes
   lightsource 0.
Location Attributes
   lit.

Set lightsource OF an object TO 5 (or some other non-zero value) when lit. Set dark rooms to IS NOT lit. Then, test for SUM OF lightsource HERE = 0 in your dark rooms and test for SUM OF lightsource HERE = 0 AND LOCATION IS NOT lit in your new Look verb definition. Also, you must use a container trick to swap out visible objects so they aren't described when you enter a dark room.

Inform 6

Give the light attribute to an object or room to indicate that it gives off light or is lit. By default, all objects and rooms are dark.

TADS 2

Declare light-emitting objects of class lightsource. Set its islit property to true or nil as appropriate. Declare lit locations of class room, and unlit locations of class darkroom. To give a darkroom light, set its lightsOn property to true; don't change its islit property, because it is a routine.

TADS 3

Light is a potentially complicated topic in TADS 3. Here's the basics:

 Hugo 

TODO

« Liquids / Powders

Alan 2

If using std.i, and the liquid is drinkable, use IS drinkable. No other support.

 Hugo 

TODO

Inform 6

n/s. The author in on his/her own in handling liquids' various properties, eg: availablity (eg: general water vs. carryable water), drinking, divisibility, evaporation, effects of emmersion/soaking, floating/density, mixing of liquids, portability (which containers may carry liquid), quantity, swimming.

TADS 2

TODO

TADS 3

TODO

« Locks

Alan 2

TODO

Inform 6

Give it the lockable attribute.

 Hugo 

TODO

TADS 2

Declare it of class lockable or keyedLockable, both of which are subclasses of openable.

TADS 3

Use the Lockable mix-in class for lockable objects. The predefined subclasses of Lockable are IndirectLockable, LockableContainer, LockableWithKey, and KeyedContainer.

« Objects

Alan 2

TODO

 Hugo 

TODO

Inform 6

TODO

TADS 2

TODO

TADS 3

TODO

« Parts / Sub-Objects

Alan 2

n/s. If the parent object isn't fixed in place, you'll probably have to use the container trick to keep sub-objects with their parent; see containers and floating objects.

 Hugo 

TODO

Inform 6

n/s. Use workarounds to put the part in scope:

TADS 2

TODO

TADS 3

Declare as an instance of the Component class.

« Protagonist / The PC

Alan 2

Use HERO, which is pre-defined. Its container property is INVENTORY. If you need to give new attributes to Hero, then explicitly declare Hero with the appropriate Actor construct.

 Hugo 

TODO

Inform 6

Use player (a global declared in parserm.h), which refers to the selfobj object (also declared in parserm.h).

TADS 2

Use Me, which is of class BasicMe.

TADS 3

There is no predefined PC object; you must create your own. Typically, one defines me as an instance of class Actor, and then within the mainCommon function, set gPlayerChar = me; so the game knows which object represents the player character.

« Rooms / Locations

Alan 2

Use the Location construct, eg:
LOCATION Kitchen
  DESCRIPTION "What a boring room. The exit is east."
  EXIT east TO Hallway.
END LOCATION Kitchen.

Inform 6

No default room class. A room is just another object. Objects that can be entered (eg: chairs, beds) are given the enterable attribute. Define its cant_go property to define a room's "you can't go that way" message.

TADS 2

The basic room class is room. Subclasses are darkroom for unlit rooms, and nestedroom for enterable objects within a room, which in turn has chairitem, beditem and vehicle subclasses. Define its noexit method to print a room's "you can't go that way" message (and which should also return nil).

TADS 3

Implemented via the Room class or any of its subclasses; eg: Darkroom, OutdoorRoom, FloorlessRoom. Use the mix-in class ShipboardRoom with another Room class for shipboard locations. Use BasicLocation or one of its many subclasses for any other location.

« Surfaces / Supporters

Alan 2

TODO

 Hugo 

TODO

Inform 6

Give it the supporter attribute. An object cannot be both a container and a supporter.

TADS 2

Declare it of class surface or qsurface. The latter is "quiet", and doesn't list its contents in certain circumstances. An object cannot be both a container and a surface.

TADS 3

Declare it of class Surface or one of its subclasses, such as Bed, Chair, or Platform. However, objects that are both a container and a surface ought to be declared of class ComplexContainer.

« Walls / Floor / Ceiling / Sky / Ground

Alan 2

n/s. See floating items for a way to handle them.

 Hugo 

TODO

Inform 6

By default, walls are bundled with the 8 compass directions; the floor is the same as "down", and the ceiling is the same as "up".

TADS 2

By default, locations don't have walls or ceiling, but do have a floor/ground item: theFloor, which is implemented as a beditem floatingItem.

TADS 3

Implemented via the RoomPart class or its subclasses Floor or DefaultWall. By default, a Room comes equipped with defaultFloor, defaultCeiling, defaultNorthWall, defaultSouthWall, defaultEastWall, and defaultWestWall; an OutdoorRoom has only defaultGround and defaultSky; and a FloorlessRoom has none.

Index


Index / davidwelbourn(a)hotmail*com / Last Updated: Oct 25, 2007.