On Designing a WebCit

Citadel is a room-structured message system. The fundamental design goal is to provide a congenial forum conducive to interesting discussions. The software is intended to be as unobtrusive, unintrusive and unconstraining as possible. In software as elsewhere, good engineering is whatever gets the job done without calling attention to itself. -- Cynbe ru Taren, 1982

I gave up proprietary software almost entirely a few years ago. I had a miserable time with the Win32 port of Cit+, and my OS/2 box just didn't run any apps. I wiped my machines clean and installed Linux and BSD on them all.

I'd played with some web-based citadels before. Cit/UX has a web interface as well as a client/server setup and a telnettable option, and there was at the time a system known as WebCit that was written entirely from scratch in C. While I loved accessing the Cit/UX systems from the web, the interface wasn't citlike enough for me to do it with any regularity, and the "WebCit" was more like a glorified guestbook with no message threading and words like "room" and "hall" bandied about.

I was faced with a choice: I could run a classic telnettable cit, or I could write something on my own. I was leaning toward running Cit/UX, although it didn't support all of the nice user interface features that I had grown accustomed to in Citadel+. It was actively supported, and it had been reworked with all sorts of process threading and multi-user chat features.

But then I actually sat back and read the old aaBuyMe.doc file that Cynbe wrote nearly 20 years ago. I read his statements on user interface design and what constitutes good engineering. I read all the history about how he had been inspired by Xerox PARC's investigation into user interfaces. I thought for a moment about what I didn't like about the existing web-based citadels, and realized that my problems boiled down to two complaints:

  1. There are too many buttons to click.
  2. It takes too long to figure out which messages are new.

All web-based BBSs suffer from one of these two problems. Either you spend your whole life waiting for CGI scripts to load the new messages then old messages then new messages again as you try to find the context of a discussion, or you root around hopelessly trying to remember when you last logged in, and whether or not you already read the current discussion. Quite often, systems will even display all messages in reverse order, so that you can read the new ones first and then find context. I find all these things to be hideously confusing and irritating.

N, or Read New

The fundamental Goto, Read and Enter commands have been streamlined as much as possible. The message display format has a minimum of unnecessary noise: the topic is implicit in the message's location within a room, no explicit TO field is present, no message ID # is printed, no redundant "END OF MESSAGE" blurbs etc. The most common Goto, Read and Enter commands are all single-key. Citadel automatically skips rooms which have no new messages, and old messages in the current room. (Less concise commands are of course available to override this.) -- CrT (ibid)

So I tried to think what made Citadel's message-reading functions unique. I realized that the basic commands (forward, reverse, old, new, and combinations of these) used three basic message pointers:

Reading new messages (the n command) simply displays all messages from the last-read to the last. Reading forward goes from first to last. Reading old goes from the last-read to the first message, and so on.

Given that all web browsers have a scrolling facility of some sort, I decided to use the top and bottom of the page to represent the user's ability to find the first and last messages, respectively. I then used a simple anchor tag (<A NAME=NEW>, for those of you who know HTML) to represent the user's last-read pointer. Now the display allows the user to scroll down to read new, scroll up to read old, and scroll every which way to recreate any of the basic message reading actions.

G, or Goto

With the display of messages out of the way, I decided to set about designing the interface for moving around the thing. Although many people despise auto-next-hall, I feel it (or a floor-mode system) is the least confusing way to allow a user to view the whole system. I simply placed a big button marked "Go To" by the phonied-up room prompt, and allowed the use of that for the Goto command.

I thought long and hard about the use of .g to go to a specific room. I realized that I had to preserve the elegance of the single button, so I decided to create a control that defaults to the execution of the goto command. What I ended up doing is designing a dropdown box that lists the commands available, all phrased as part of a sentence beginning with the words "Go to...". The box lists things like "next room with new messages", "your preferences", "a map of the BBS" (our friendly k, or known rooms command!), and finally a list of individual rooms in the current hall that are available to the user. This way the user can just hit the "Go To" button, or he or she can select an action from the list before clicking the button.

E, or Enter

I had long been frustrated with systems where attempting to enter a message took the user to a new page. Part of the elegance of citadel is that the user can see his or her own message as part of the stream of messages even while entering it--only a single line or two makes it look any different. I decided to put the message entry box at the bottom of the page, after the controls for navigation. A Save Message button and an Abort Message button (the familiar "clear form" button) finished off the interface nicely.

The only problem with this is one that I plan to remedy shortly: the Go To and Save Message buttons are actually the same button. It should be trivial for me to fix the problem by checking some values in the primary control structure. I plan to do this as soon as I find time (I've been rather caught up with the Microsoft Windows Refund Day newsletter lately).

Dancing Baloney

many people have criticised me for using GremCit/Cit+ default colors for my output. This is easily changed. I had originally intended to just make the title, surname, and date bold while the username was underlined. An enterprising SysOp could make the necessary modifications in a few minutes.

The colors are garish, but they make it easy for the eye to distinguish header information from message text, and I often only read the magenta (username) and white (body text) when my eye scans down the page. The colors also help conjure up the feeling that the user is at the prompt of one of the old DOS citadels. I ended up eschewing the fixed-width courier font for a more legible sans-serif. This caused grumbles from the peanut gallery, initially, but all my users have grown to like it.

Little Pixies

Now, while I feel that I've done the best job of coming up with a web-based interface for a Citadel, the implementation is far from stellar. There is currently no telnettable interface for it, and the HTML is stored along with the messages in the room databases. The system uses a whole host of GDBM files, one per room (as opposed to the three primary databases used by most citadels). It can be rather sluggish when performing operations such as the display of the map. Still, ZorkCit does accept commands in CGI GET format, so the administrator can have links to rooms embedded in ordinary web pages.

Other problems with the system include a completely ad-hoc method for generating passwords and new accounts. In future, I hope to integrate these into the main program. As it stands, the new user must fill out a separate form (the ZorkCit welcome page is also a little confusing). In addition, ordinary HTML is allowed in the message entry, requiring both skill and conscience on the part of the users. Remote administration isn't exactly simple, and I spend most of my time manually peeking and poke-ing values into and out of the GDBM files (peek and poke are two scripts I wrote while trying to fix a room that had a nonprintable character in the name).

The one thing that I feel makes this system more Citlike than any other is the fact that it is released in source code form. ZorkCit is licensed under the GNU General Public License. This means that all those who wish to create derivative systems will always contribute the code back to the Citadel community. Almost all the Citadels recently in heavy use are descended from the source releases of Citadel 2.1, Cit86, and DragCit. I tend to think of these as the Unix 6th edition, 32/V, and BSD of the Citadel world. Citadel has always been rooted in the culture of open source software, and even Cynbe ru Taren is spending time writing pro-Linux rants!

Flame Wars, Topic Drift, and Citadel Suggestions

For an archive of the discussion on the development of ZorkCit, please see the WebCits.html file that is distributed with ZorkCit. It chronicles the arguments we had over the last year or so about how a proper citadel should be implemented. Feel free to join up with the discussion and share your thoughts in the WebCits room on the ZorkCit test system.

I'd like to thank Eve, Masquerade, Shazdeh, Iori Yagami, and Narcoleptic Dog for their feedback and contributions to the development of the system.