Let's Play: Dialog

Let’s Play: Dialog

The “let’s play” threads have been fun, and there has been some talk lately of Dialog as an IF language to try, and I’ve always thought it was a neat idea but though I’ve skimmed the manual and tinkered a little when it first came out, I’ve never given it a real try.

Of course this isn’t intended to be a comprehensive tutorial. A lot of the code in the Dialog category of the forum goes over my head at the moment. But I thought it’d be fun to try and walk through making a small game to give a taste of the language.

So.


Dialog is a Prolog-inspired language for creating (mostly) parser-based works of interactive fiction. Its author, Linus Åkkeson, is a retro-computing fan, so it’s also aimed at producing small code that runs on old machines.

And partly because of that, it’s not great at numbers: it currently only allows numbers from 0 to 16,383. Which gets you, say, 4-digit PINs and things. But no negative numbers out of the box, though someone has made a Signed Math Library over in the Dialog section. How often do you really use numbers much in IF anyway? But it’s a limitation you might want to know about.

It is also currently only for Windows and Linux. I suspect that it would be pretty easy to build it for Mac but that Linus doesn’t have the hardware to do it. I’m going to do this thread on Windows and assume that if you’re using Linux you know what you’re doing.

Edit: Thanks to all the people who pointed out that you can install it easily on Mac using Homebrew (see this thread), and Borogove lets you use Dialog online without any setup (you do have to go in the left sidebar and move the stdlib.dg to the bottom so it doesn’t override your game code). And for the adventurous, you can compile it from source on Mac: it’s not as hard as you think! :wink:

Installation

I’m using dialog_0m03_0_46.zip: Dialog used to get updates a lot but it seems to have stabilized and this has been the latest version for quite a while. So go grab the zip. There is a dialog_0m03_0_46 folder inside the zip, so if you just unzip it you’ll probably get two nested folders with the same name. For ease of use it might be nicer to open the zip and copy/paste the folder somewhere instead.

You’ll also need a text editor. If you don’t already have one you like, I suggest Notepad++ (no connection to the Windows Notepad): it’s a tiny download, it doesn’t have tons of incomprehensible extra buttons and panels so you can just open up and use it, and it works about as well as anything else.

And as with most parser IF, you’ll need an interpreter for the game files that you build. I’m going to assume that if you’re here, you have one of those, or can find one yourself.

Getting Started

OK, let’s create a source file, with Notepad++ or whatever you’re using. I’m going to call it game.dg. And I’m going to save it right inside the dialog_0m03_0_46 folder just to keep things simple.

Unlike a lot of other languages (especially Inform 7), Dialog pretty much just has one format for commands: you put the name of the command in parentheses (this is called the rule head), and then the body of the rule follows the parentheses. Rule names can have spaces in them, so for instance:

(story title) Curious Chicken and the Hydrangea of Doom
(story author) Josh Grams

I have no idea what sort of game might go with that title, but it’s the first thing that popped into my head, so sure, why not set up problems and hope future me can come up with a good solution?

If you’re making a game for publication, you probably also want to add a unique IFID. There’s an IFID generator on the main Dialog page if you scroll down past the long list of downloads. TADS has one as well.

(story ifid) 0FAA1D88-603D-4441-BACE-07938CB6E516

Then let’s add the minimal Dialog code to get a game running (the code above isn’t actually necessary):

(current player #chicken)
(#chicken is #in #coop)
(room #coop)

Dialog uses hashtags as names for all objects. The manual describes Dialog’s objects as “thin” – they’re basically just names that you can attach behaviors to. And you use them for everything. We already have a person (#chicken), a room (#coop), and a relation (#in).

Note also that, as with Inform 7, command names can be words interspersed with their argument, as in ($ is $ $) which takes an object, a relation, and another object.


But let’s try building this. Save the source file.

Open up the dialog folder, click the File menu at the top left, and choose “Open Windows PowerShell”. If you’re on Windows 11 it might be “Windows Terminal” instead? I’m not sure. If you have trouble, maybe post a screenshot and we’ll figure out another way.

01-open-powershell

Now we want to run the dialog compiler. It’s in prebuilt\win32\dialogc.exe, but good command-lines will autocomplete if you press the Tab key, so you should be able to type p<Tab>w<Tab>di<Tab>. Then we need to tell it what type of output to build (we’ll use z8), give it our source file and the Dialog standard library (which is just another source file: you can open it up and read or even modify it if you want).

The full command we want is:

prebuilt\win32\dialogc.exe -t z8 game.dg stdlib.dg

When you use tab-complete you might get an extra .\ before all the filenames: .\game.dg, .\prebuilt\..., etc.). That’s fine, the . just means “the current folder”

So put in that command and press Enter. It should silently (and pretty much instantly) just give you another command prompt. But if you type dir<Enter> (or go back to your File Explorer window) you should see a game.z8 file.

If you open the z8 file, you should have a minimal game. There’s not much you can do here: look or x here or x me, and I think you can jump or sing? And quit, of course. But we compiled it, and it runs.


Let’s go back to the source file.

If you mention a hashtag at the start of a line by itself, it becomes the “current topic” and we can refer to it as *. I don’t know why it’s a piece of punctuation instead of the word “it”. You can use “it” in game. But whatever; you get used to it. No big deal.

So let’s give the room a description. Take out (room #coop) and do this instead:

#room
(room *)   %% We still have to say that it's a room.
(name *) Chicken coop
(look *) A boring chicken coop. Bet it's more interesting outside.

Let’s compile it again and see if that shows up. Another feature of good command lines is that they remember the previous things that you typed, so use the up arrow to find the dialogc command and press Enter to run it again. PowerShell usually remembers even after you close the window and restart it again.

In the dark
You are surrounded by darkness.

Hrm. Ah. Do you see what I did wrong? I called this room #room but we’re still putting the player in #coop. Which… interesting. I wonder if it doesn’t exist, or if rooms are created dark if they don’t exist? Well, either way, it’s an easy fix.

Chicken coop
A boring chicken coop. Bet it’s more interesting outside.

There we go.

Let’s also try adding an object.

#perch
(supporter *)   %% It's a supporter
(name *) perch
(descr *) A sturdy wooden bar. Good for sleeping on and not much else.

I don’t yet know why it’s (look) for rooms and (descr) for objects. You can look at both of them in-game. Maybe I’ll dig into the standard rules later and see if I can find out. Or maybe not.

Oh. Wait. I didn’t read carefully. It’s right here in the objects and state chapter:

The (descr $) predicate prints the external description of an object; what it looks like when viewed from the outside. Another predicate, (look $), prints the internal description of an object, i.e. what it looks like from the inside. This is used for room descriptions.

Cool. Let’s try this.

Hrm. Why can’t I examine it? Oh, right. We didn’t put it anywhere. Let’s put that right under #perch.

(* is #in #coop)

There we go. It doesn’t show up in the room description, though. Dialog’s objects are silent by default. We can say (appearance #perch) to give it its own paragraph after the room description. Or just mention it in the description ourselves.

Also:

> stand on perch
It’s not possible to get onto the perch

> put me on perch
It’s not possible to get onto the perch

Did I do it wrong? Or maybe you can put things on supporters but not get on them yourself? Let’s make another object to test.

#pebble
(* is #in #coop)
(name *) pebble
(descr *) A small pebble.

Do we have to do anything special to make it so we can pick it up? Hmmm…or do we have to do something to make it fixed in place? Maybe we can take the perch.

> x perch
A sturdy wooden bar. Good for sleeping on and not much else.

> x pebble
A small pebble.

> get pebble
You can’t take the pebble.

> take pebble
You can’t take the pebble.

> take perch
You can’t take the perch.

Nope. Hrm… the documentation doesn’t seem to say anything special is needed: it talks about taking in the section about disambiguation and adding synonyms for an object. But that might just be leaving out code that isn’t relevant to that particular discussion… Ah. Maybe it’s (item)? Let’s try that.

> take pebble
You take the pebble.

> put pebble on perch
You put the pebble on the perch.

Cool. So it’s chapter 3: Traits that talks about this: it has several diagrams. This one is “Traits that determine what actions may be carried out on an object.” (and incidentally, I wish more of these headings in the manual had names so I could link directly to them…

And it looks like (actor supporter $) is the predicate that allows the perch to support actors (us) as well as objects. Yup.

OK. I think that’s enough for a first post. Next time we’ll probably start getting into how rules in Dialog actually work, instead of just giving some trivial examples. This is both the powerful thing about logic programming languages, and the thing that can make them hard to read (I think): arguments to rules can be either inputs or outputs, and you have to tell from context because it’s not distinguished by the syntax.

game.dg (678 Bytes)

15 Likes

I’m running it on a mac (well, from the terminal) and don’t remember doing anything special.

1 Like

Excellent. But I’m assuming you had to build it from source? The distribution only seems to have binaries for windows and linux (32 and 64-bit). Unless someone else is hosting mac builds that I don’t know about (I didn’t look very hard, and “dialog” is difficult to search for). It’d be cool if someone had mac binaries that people could just download.

1 Like

I don’t think so. I don’t really know how to do that. I think I just unzipped the thing and ran it from the command line in the terminal. Mac users might want to look at this:
https://intfiction.org/t/installing-dialog-on-macos-using-homebrew/42305

Which I definitely used for updates.

EDIT: Oh and I do use VSCode for writing the programs but I’m pretty sure I started using a regular text editor like notepad.

1 Like

That wouldn’t work. You must have used the homebrew instructions.

1 Like

Oh yeah, I see now:

I should have written “for those of us” just to preserve my memory of the event. :wink:

(Thanks @zarf. :slightly_smiling_face:)

1 Like

For those who want an easy way to try Dialog, you can also use Borogove.app. (Although you have to reorder stdlib.dg to put it after the main story file for it to work properly.)


Simply mentioning an object will create it, so #coop does exist. But since you removed (room #coop), it becomes a regular object floating in the void, with the player inside. I guess it’s dark because the standard library’s rule for checking light doesn’t find a source of light (there’s nothing outside that can provide light since #coop has no parent).

Anyway, I guess it’s some kind of edge case that the standard library doesn’t check since it’s never supposed to happen.

5 Likes

Dialog is pretty easy to build on MacOS actually, if you have Xcode and Xcode command line tools from Apple on your machine. Open dialog’s Makefile and change CC = gcc to CC = cc and then run make to build dialogc and dgdebug. You can use the same procedure to build aamachine tools as well.

It will probably compile out-of-the-box with gcc, if you have that one installed alongside with glibc package.

1 Like

My MacBook Pro M1 has the Xcode command line tools installed. I was able to take the source as-is, run make and it compiled perfectly without any troubles. I didn’t have to change the Makefile at all.

1 Like

I guess XCode sets a symlink to cc from gcc. Since I have gcc also installed(without glibc) it won’t work on my MacBook without modifying the Makefile.

Thanks, all! Excellent. I have a couple busy days here but I might get back to this for a bit tonight…

Have you tried getting people to use the command-line and build things from source? It’s even harder than getting them to try parser IF! :wink: But it’s good to know that it’s not hard: the build process did look very straightforward.

Ah, that makes sense. Of course there’s no light in an empty object floating in the void.

I wanted to mention some mistakes I made as I went along, both maybe to help people debug (having an object name typo seems like an easy thing to do) and also to highlight “hey, we all make easy mistakes, even those of us who have been coding as a major hobby for going on thirty years in a couple dozen languages…”

3 Likes