mire - a better Plan9 MUD client than bog


Bog was a good learning experience, but I wanted a client that I could actually use to play with.

The differences from bog:

  • no fs (good to learn with, but there's really no compelling reason for it)

  • simplified code

  • supports scripting via Scheme 9 from Empty Space or smazga's s9

  • (almost) works in plan9port


mire -w net!host[!port] [-r rcfile] [-f font]
    -w: the world that you want to connect to
    -r: your scheme rcfile containing aliases and stuff
    -f: alternate font file


Mire runs an "embedded" s9 interpeter to facilitate aliases and scripting. The scheme framework is loaded from /lib/mire.scm. It's in its infancy right now, so it's not super featureful, but it does support arbitrarily complex scheme procedures, so there's that.

See example.scm in the source tree for some lame demos.


The bang (!) indicates to mire that the following input line should be sent to the scriptengine, not to the MUD server. The following would invoke the 'k' alias with the 'monster' argument.

!k monster

Arguments are passed to aliases in the args variable as a list.

Utility Functions

Various built-in functions are provided to make scripting easier.

Currently, the following are available:

  • (echo STRING) this echoes the given string to the user, but does not send it to the server

  • (send STRING) this sends the given string to the server, and also echoes it to the user

  • (metered INT LIST) this sends each string in the list to the server after waiting for the given delay

  • (add-alias STRING PROC) add an alias to the script engine (see below)

  • (add-trigger STRING PROC) add a trigger to the script engine (see below)

Default Aliases

There are a few aliases included. In an attempt to avoid naming collisions, the built-in aliases are all prefixed with @. So, to call the mire alias, which is a simple ACK, you would send:


The following aliases are registered by default:

  • @mire simple ACK, mildly informative at startup

  • @aliases print the names of all known aliases (TODO: a description of some sort would be nice)

  • @triggers print the names of all known triggers

  • @reload load the passed rc file again. This makes rcfile development much easier (NOTE: it just loads, but doesn't clear. Aliases you delete from your rc file will not disappear until you restart the client)

  • @f1..@f12 by default, the function keys are bound to call their corresponding aliases, though it is up to the user to define those aliases

Adding Aliases

It's probably easiest to just show examples:

(add-alias "w" '(send "wave"))
(add-alias "k" '(send (format #f "kill ~A" (car args))))
(add-alias "login" '(metered 500 '("smazga" "mypassword" "" "1")))
(add-alias "@f1" '(send "quaff heal"))

By way of explanation, the login alias is tailored to my test mud, which is a default circlemud. The login procedure there is:

  1. enter username
  2. enter password
  3. press 'enter' to pass MOTD
  4. select '1' to enter the mud

Each string is entered after a 500 millisecond delay, to account for crappy connection and slow server. Probably unnecessary, but good for testing.

Adding Triggers

First, it's important to understand that, while mire/bog are slow already due to the cheesy drawing technique used, adding a bunch of triggers is going to transport you back to 1992 when you were mudding over a 9600 baud modem. If you want that kind of nostalgia, knock yourself out. Otherwise, be aware that every line of text received from the server is passed through the script engine and every known trigger has its regex compared against that line. So, many triggers means many comparisons.

Some day I may try to think of a better way, but since I'll probably be the only person to ever use this client, and I'm ok with it as-is, it'll probably never change.

The syntax is basically the same as (add-alias) with the difference that the first argument is a regex pattern, not just a name.

From example.scm:

(add-trigger "large fountain" '(echo "There is a fountain here."))

With a group match:

(add-trigger "Welcome \\([a-zA-Z]+\\)" '(echo (format #f "~A is here" (car args))))

bog - a Plan9 MUD client

Why? Because I wanted to:

  • create a client to play MUDs with
  • learn how to use libdraw
  • learn how to create a Plan9 file system
  • get more familiar with Plan9

What can it do?

Not much. It supports telnet-based MUD servers and provides some level of ANSI color support.

It will post a service (if you use the -s option) that can be used for scripting (example coming soon).

The future

  • add a man page
  • add a scripting example
  • code cleanup (it was a learn-as-you-go deal which leaves messy code behind)
  • possibly MXP support
  • scrollback

What was learned?

  • flushimage() is poorly documented
  • how to use channels
  • how to draw simple stuff with libdraw
  • how to create a simple mkfile
  • how to create a simple file server
  • #plan9 is a ghost town