Dialog release announcements

Thanks for log! I look forward to using it once the brew recipe is updated and I can use it.

I will definitely be using (list objects $Rel $Obj) and (appearance $Obj).

I’m a little concerned about notice from appearance as it feels like I might mention an object explicitly, but if my room contains any items, those will then get noticed, overriding my mention.

1 Like

Dialog version 0i/02 (library 0.34) is a small bugfix release:

  • Library: Fixed a bug in how the visibility ceiling was computed. Thanks @hlship!

  • Debugger: Removed spurious extra “Query succeeded” after each interactive query. Thanks @hlship!

  • Debugger: Proper reporting of interactive queries to access predicates. Try e.g.: *($ is $ $)

  • Manual: Added missing multi-query asterisks to the fungibility examples. Thanks @Mikawa!


Another bugfix release: Dialog version 0i/03 (library 0.34).

  • Compiler: Fixed a bug where, under very specific circumstances, a register could get overwritten by an else-clause.

  • Å-backend: Fixed a bug where text containing non-ASCII characters would occasionally be converted to lowercase.

  • Debugger: Fixed a bug in how UTF-8 input is divided into words.

  • Manual: Added a clarification about the pristineness of nested objects, including the initial possessions of the player. Thanks @hlship!


Glad to see the change to the manual; just to be picky, there’s a problem below the new example:

All about appearances

You may have noticed a problem with the last example:

The wallet/receipt is now the “last example”, not the “bowl of gems”.

1 Like

Dialog version 0j/01 (library 0.35) is ready! Also make sure to get the companion release, Å-machine tools 0.4.1.


There is now a (span $) construct for applying style attributes to inline content, as a complement to (div $). The library provides style classes @bold and @italic by default, so you can do e.g.:

        (span @italic) { Lorem Ipsum } , he (span @bold) emphasized .

The old built-in predicates (bold), (italic), (reverse), (fixed pitch), (roman), and (unstyle) still work, but spans are preferable because they have full CSS support (when using the web interpreter) and provide a clean separation between content and presentation.

Better hyperlinks

The short form of (link) can now be followed by any kind of statement, not just a plain list of words. This makes it much easier to create clickable text on the fly:

(descr (fruit $Obj))
        You're really yearning to (link) { eat (the $Obj) }.

There’s also a new builtin, (clear links), that turns old hyperlinks into plain text. This is useful when the scope changes drastically, e.g. when moving to a different room.

Word manipulation

There are new builtins for splitting and joining words. This opens up all kinds of possibilities, like printing words backwards, counting the number of letters, or accepting transliterated input (such as “oe” for “ö”).

A new builtin, (unknown word $), checks if a word is listed in the game dictionary. This can be used to implement responses such as “You don’t need to use the word ‘borborygm’ in this story”. It is also required for the venerable “OOPS” command, which has now been added to the standard library.

Parentheses are now treated as individual words when parsing player input. The full set of such characters is: . , ; * ( ) "

From now on, such characters are also treated as separate words during (collect words) operations, even when they appear as part of larger words in the source code. This makes it a lot easier to work with object names like “purple envelope (open)”.

Also, when these single-character words are printed back as values, whitespace is inhibited before . , ; ) and after (. Earlier, if you wanted a comma in the printed name of an object, you had to do something like this:

(name #snowman)
        the tall , tall snowman

but now the following works exactly the same:

(name #snowman)
        the tall, tall snowman

Development and debugging

It is now possible to declare interfaces, a simple form of machine-readable documentation that describes how a predicate is supposed to work. Such declarations have been added to the standard library.

The compiler is able to trace unbound values, and print warnings about potential interface violations. Thanks to the interface declarations, the compiler is better equipped to report problems at the file and line where they actually originate, and not just at the place where they might cause problems at runtime.

The compiler will now also warn about variable names that only appear once in a rule definition, as these tend to be typos. To get rid of such a warning, change the variable into a wildcard ($).


(append $A $B $AB) is now built into the language, rather than defined by the library, for performance reasons.

The Å-machine backend produces smaller and faster storyfiles thanks to several new Å-machine 0.4 features.


  • Library: Fixed a bug in how reachability is determined. Thanks @hlship!

  • Library: (understand $ as any object $ preferably $) didn’t take the specified policy into account; this is now fixed.

  • Manual: Moved the section about the pristineness of nested objects to the end of the Items chapter.



Dialog version 0j/02 (library 0.36) is a small bugfix upgrade:

  • Debugger: Removed stray warnings about singleton variables when merging changes to the running program.

  • Library: Visibility is now recomputed after updating the current room variable and moving any floating objects.

1 Like

Thanks for the quick turnaround; I can verify that in my project, the problems I saw previously are gone.


Here’s Dialog version 0j/03 (library 0.37)!

  • The new big thing is choice mode, i.e. integrated support for switching between parser-based and choice-based interaction. There’s a new section in the manual about it—with diagrams!—and another section describing how to use it for choice-based conversations with NPCs.

  • Two new hooks, (early on every tick) and (late on every tick), have been added. Thanks @hlship for suggesting these!

  • Miscellaneous bugfixes and improvements.


You are adding so many compelling features to the Dialog development system, it is becoming a strong option for parser based IF. I have two i6 games currently in development. I may begin writing one of them in parallel with Dialog.

Thank you,

1 Like

It is alsready a strong option, in my opinion, plus the big advantage of being actually developed, unlike TADS and Inform.


Agreed. I should have said, “Becoming a stronger option”. Dialog is brilliant.



I would like to have an option for aambundle which lets you only export the new story.js file from an .aastory file. I am using a customized web enviroment for my game and it’s tedious always have to export the whole directory structure. It would be more convenient to only exchange the story itself, especially when doing only minor enhancements.


Good idea! Noted.

1 Like

New in Dialog version 0j/04 (library 0.38):

  • Undo is now treated as an action, [undo], and reported via (narrate undoing). Requested by @hlship.

  • Fixed a bug that disallowed @-prefixed words in slash-expressions. Thanks @hlship!

  • When the player types an object name in response to a direct question (e.g. “To whom?”), this is no longer ambiguously understood as a request to perform the default action (e.g. examine).

  • Several improvements to the optimizer.


This is now possible in Å-machine version 0.4.4. Be aware that the web interpreter also expects to find the original .aastory file in the resources directory, with a mangled filename. This is the file that gets served when the player selects “Download story file” from the menu.

1 Like

Time for some changes! Get Dialog version 0k/01 (library 0.39) here.

Simplified grammar

Language change: Access predicates can now have multiple definitions, and pattern matching is applied to the parameters. Thus:

@(magic rule [$Head | $Tail])    (ordinary rule $Head) (magic rule $Tail)
@(magic rule $Other)             (ordinary rule $Other)

With the above access predicate definitions, the query (magic rule [hello little world]) would be transformed, at compile-time, into:

        (ordinary rule @hello)
        (ordinary rule @little)
        (ordinary rule @world)
        (ordinary rule [])

Such compile-time transformations are a sharp tool, to be used sparingly and with caution. But with this small language change, the library can now offer a simplified syntax for extending the parser grammar and adding new actions.

Previously, adding an action such as “TRANSMOGRIFY object WITH object” required a lot of boilerplate code:

(understand [transmogrify | $Words] as [transmogrify $Obj with $Tool])
        *(split $Words by [with] into $Left and $Right)
        *(understand $Left as non-all object $Obj)
        *(understand $Right as single object $Tool preferably held)

But now, all you need is:

(grammar [transmogrify [object] with [single held]] for [transmogrify $ with $])

In light of this new syntax, most of the Understanding player input chapter of the manual has been reworked, and should be much easier to follow now.

You can still define (understand $ as $) rules, for those odd situations where the new grammar-syntax is too simplistic. In fact, the parser still queries (understand $ as $) as before, but the library provides a new rule for this predicate, which looks into a grammar table constructed at compile-time from (grammar $ for $) definitions.

Not only is the new grammar syntax easier to read and work with, it also results in a more compact runtime representation, thus lowering the memory requirements of the parser and improving performance on 8-bit systems.

Accumulating sums

A new variant of the collect-into mechanism has been added to the language. This will exhaust every branch of the inner statement, look at the values taken on by a given expression, and add those values together.

You can use it e.g. to compute a score:

        (accumulate $Score)
                (puzzle a is solved) ($Score = 5)
                (puzzle b is solved) ($Score = 1)
                (puzzle c is solved) ($Score = 10)
        (into $Sum)
        You have a total score of $Sum.

Or merely count the branches:

        (accumulate 1)
                (puzzle a is solved)
                (puzzle b is solved)
                (puzzle c is solved)
        (into $Sum)
        You have solved $Sum puzzles.

You could also e.g. compute the total recursive weight of an object and its descendants. Assuming you’ve defined ($ has weight $) for all relevant objects:

        (accumulate $W)
                        ($Obj = #player)
                        *($Obj has ancestor #player)
                ($Obj has weight $W)
        (into $Sum)
        The total weight is $Sum.

Other language changes

  • Added builtin (fully bound $) to check if a value is bound and, in case of a list, contains only fully bound elements.

  • (split $ by $ into $ and $) now accepts a single keyword as its second parameter (or a list of keywords, as before).

  • Added special keypress words @\u, @\d, @\l, @\r, @\n, @\s, and @\b. Removed (word representing up $) and friends.

  • The character + may now be used in the source-code names of objects and local variables.

Other library changes

  • Relation objects (#on etc.) no longer have dictionary words. They appear directly inside action grammar rules instead, e.g. [put [held] on/onto [single]].

  • Added intermediate action [switch $] that delegates to [switch on $] or [switch off $].

  • Bugfix: Duplicates are now removed from the list of choices in choice-mode.

And finally, there are some bugfixes and improvements to the optimizing compiler.


Dialog version 0k/02 (library 0.39) fixes a bug, found by @Karona, that prevented per-object variables from being initialized to complex values.


This is odd. I tried instantiating the Choice Mode example, and when compiling for z8, I get this:

Warning: A query is made to '(program entry point)', but there is no matching rule definition.
Warning: No release number declared.

In addition, it produces a story file that, when run, gives me a blank screen. The same happens when trying to compile the Cloak of Darkness example. I haven’t tried any others yet.

Sounds odd indeed.

Is there something wrong with your library file? That’s where the default release number is declared, and a rule for (program entry point) is defined.

…oh dear. Yes, that was my bad. I’ve been on hiatus and when I went back to Dialog, I didn’t check the manual for the inclusion of the library, I just looked at the command line instructions (–?), so in my grogginess I entirely overlooked the need for the library file.