The Purpose of the NPC
The NPC as Agent
NPC Movement, Action, and Reaction
Like my simulationism page, this page attempts to provide advice based on my own experiences, mentioning specific games wherever possible. It starts off with things that I consider easiest, and works up to the most obscure.
Other excellent places to look for NPC coding advice are Roger Firth's Inform NPC tutorial InfAct, the collection of Inform library contributions for NPCs, and Onyx Ring's tips for conversation implementation in Inform. For TADS, there's Michael J. Roberts' article about NPCs in T3 (some parts of which are theoretical and could be useful to anyone).
Also, if you're wondering: this page has changed considerably since its first introduction. I've expanded some sections to account for new games or material, and removed others because I came to the conclusion they were too esoteric or (in the case of the "Writing" section) deserved a fuller treatment than I could really offer here. Though I don't stand behind all its content at this point, I have kept an older version around for reference.
Before you code anything, you should figure out what kind of game you are writing, and what purpose you have for the NPCs who will appear in it. A game with a strong emphasis on puzzles, where NPCs are present only to provide another kind of challenge, will have a very different treatment from a linear, story-oriented game where NPC interaction is the chief purpose of the game. A mystery with a lot of knowledge puzzles will again have a different set of requirements from a romance, where emotional interaction is emphasized.
Even within a game, different NPCs can have different roles from a gameplay perspective. One of the best discussions of this problem I've seen is Jim Fisher's article on Ask/Tell theory: while it claims to be about a specific kind of conversation system, it addresses some important points about how NPCs can be used in any IF game. Do you want your player to talk extensively with NPCs and have a great deal of flexibility in the outcome? Or would you prefer to have control over how each conversation goes? Are the NPCs there mainly for local color, or do they provide vital exposition? Do they have to accomplish anything in the story?
The answers to these questions will affect the rest of your NPC design. In a game with a highly predetermined plot — that is, one in which you could sit down and write a list of all the scenes that must occur — a simulationist approach to NPC design would probably be the wrong approach. That is, you will probably have less use for variables to track emotion and behavior in general, and you will accomplish more of your effects by scripting them specifically. By contrast, in a game where the play is very broad, and the player can spend as much or little time with the NPCs as he would like, you may find yourself writing a fair amount of generic code to cover issues like NPC attitude, behavior, and goal-seeking.
One of the easiest ways to present a strong character is to prevent that character from ever showing his face in the work of fiction. This is not news even to static fiction authors: Captain Flint overshadows Treasure Island; the eponymous character in Du Maurier's Rebecca is chilling and memorable; the Odyssey begins with four books of people talking about Odysseus before the man himself is allowed to take the stage.
Because an NPC is perhaps the most difficult of all gobbets of code to make convincing, a bunch of stand-in objects pointing to that personality is often more successful. Gilles Duchesne's Nothing More, Nothing Less is pervaded by the character of an absent woman; everything that the PC looks at makes him think of something about her.
Memory. If the player character knows the NPC in question, she may remember events involving that NPC even when he's not present. Kathleen Fischer makes good use of this technique in The Cove, and somewhat in Redemption as well. It's a reasonable way of smuggling in background exposition and providing a context for the character whether or not he ever becomes available to interact with.
Evidence. In the absence of personal experience, there can be evidence of the NPC's presence — letters, photographs, personal possessions, and so on. Babel and Anchorhead both make good use of this sort of technique. The diary found crammed into a hidden place is a common trick, but it can still be effective if the diary contents are well-written and convey a strong sense of personality.
Overheard Conversation or Observed Action. The player is trapped. His character can't act. Inescapably, he is the mute eavesdropper on some scrap of conversation; or like the Jimmy Stewart character in "Rear Window," he observes something that he can't affect. It's often possible to contrive a plot reason to immobilize the player briefly and run a daemon for a few turns. The contrivance starts to show if you do this too much. Delusions, Varicella, and Spider and Web all make good use of the overheard conversation that the player is unable to change.
Back to Contents
Like any other object in the game, the NPC needs a physical description. The more important the NPC is — the larger a part of the game he or she is — the more detailed or layered it is probably worth making that description. Sometimes it's worth implementing for the NPC separately examinable clothing, props of various sorts, and even separate body parts (and not just for Adult IF pieces, either).
Of course, this approach can be carried to excess. The End Means Escape contains several characters implemented down the fingernails and bellybuttons, an effect that works in context but would probably be quite out of place in a less surreal game.
Back to Contents
An NPC who sits in a chair and does nothing is less convincingly alive than one who seems to be pursuing some sort of personal agenda.
Randomized Messages. Randomized messages, printed while the NPC is visible to the player, provide a minimum level of aliveness. Appending "Mrs. MacGillicuddy vacuums around the sofa." to the end of some other unrelated event is perhaps not the most striking innovation in characterization — but it does at least remind the player that the NPC is alive. For animal NPCs, a few random messages may be sufficient.
Interaction with Items in the Environment. A step up from this is to have the NPC actually moving or changing the states of objects in the room: dropping things, turning on lamps, picking up items you've left lying around. This is a bit more difficult to implement than the randomized messages, but it also gives the impression that the PC and the NPC are inhabiting and interacting with the same environment, rather than passing each other like a pair of ghosts. The thief in Zork is an early example of this kind of character.
Reaction to Player Actions. As you observe the NPC, so the NPC observes you. If the NPC reacts to the player's actions, it goes a long way to suggesting a separate, alert intelligence.
Adam Cadre's Textfire Golf carries this technique to perhaps its logical extreme: though you're not allowed to converse with the NPCs, they react in such a variety of ways to your behavior on the golf course that they seem interactive and well-characterized. Leon Lin's Kissing the Buddha's Feet is another, less exhaustive example of the same thing.
Moving Around the Map. An NPC who has something he or she wants to get done is likely to want to move around the environment a bit. The library module NPC_Engine does a wonderful job of handling options here: it allows you to move NPCs along random or predetermined paths, or to have them find their own ways. It also lets NPCs open and close doors, and allows you to design reactions for them if they get partway to their destination and find themselves blocked. And it handles verbs of following and asking one NPC where another one is. It's really quite a gem of simulationism, with the drawback only that it takes a certain amount of overhead and may run slowly if you're not careful. I've never used it in one of my released games, but this is only because I haven't had occasion to move NPCs around that way.
Even if you don't have recourse to such a sophisticated system, getting your NPCs from one place to another reminds the player that they are not glued into the environment in one place.
Pursuing Private Agendas. Periodically people on rec.arts.int-fiction discuss the problem of writing NPCs who would be able to do (perhaps somewhat simple) tasks in a semi-intelligent-seeming fashion. They might, for instance, look for lost keys by systematically searching all the appropriate areas of the room, opening closed containers, looking underneath large objects, and so on, until they found what they were looking for. The code to manage this would have to be flexible enough to account for any changes the player made to the environment, too: the NPC shouldn't keep looking for the keys if the player has put them in plain sight, for instance.
The problems here are actually fairly considerable, but there have been some innovations on the technical side that may make these goals possible. TADS 3 contains a system of actions and action validation that makes it possible for NPCs to interact with the environment in more or less the same terms that the player does. An object that is out of reach for the player could be made out of reach for the other actors as well. T3 is still coming to its maturity, but the sophistication of its world model makes possible some kinds of NPC programming that have never been seen before.
Also worthy of note is Nate Cull's Reactive Agent Planner libraries, which have been written to work with the standard Inform library, Platypus Inform, and TADS 2. These don't involve specific world modeling features. Instead, they allow the NPC to identify goals, form plans to achieve those goals, and modify the plans turn-by-turn to account for changes in the environment. The Reactive Agent Planner (or RAP) is fairly abstract and a bit difficult to understand at first, but once mastered can produce some fairly sophisticated and intriguing NPC behavior.
Back to Contents
Conversation is probably the most difficult thing to code for an NPC. There are several problems, but one of the most pressing is that we can't yet express conversation in interactive fiction the way we express it in real life. The most natural thing to do, from the player's point of view, would be to type exactly what he would like to say, using plain English (or plain Italian, or whatever) to convey both content and tone. The Ideal NPC would understand perfectly and would react to the player's attitude as well as the factual content of what was being said.
At the moment, however, this kind of parsing is beyond us. Moreover, while it might be an ideal solution from the player's perspective, it could only be a nightmare for the author. In other aspects of IF design, it's possible to limit the number of things a player could reasonably do: there are only so many verbs, and only a specific set of objects available, and the scope of action is fairly well understood. An NPC who understood all topics of conversation, and all kinds of tonality and mood, could never be exhaustively programmed; there would always be another quirk unaccounted for. And such a character would almost certainly exceed the boundaries of the intended plot, as well. It would be quite hard to write a story that had any sense of structure or continuity, if the intended plot could be set aside while the player taught the NPC the basic rules of cricket.
So instead of natural language processing, we have an assortment of variously successful systems to allow the player to communicate his conversation intentions to the parser.
Note that I discuss the usefulness of various systems in characterization, not the technical aspects of achieving these effects. For a good overview of this topic, at least in inform, see Roger Firth's tutorial InfAct. For another overview of this topic, with some different conclusions from my own, check out Michael J. Roberts' survey of conversation systems.
Yes/No Conversation. This is a one-trick pony: Andrew Plotkin did a brilliant job of handling it in Spider and Web, but it's not particularly suited to most games. Still, I include it here as an example of the most minimal possible form of conversation.
Talk To. When your player wants to communicate, he types >TALK TO JONES and the conversation takes place without further interference from him. The advantages are, first, that you can put realistic, situation-appropriate dialogue in the mouths of both PC and NPC, and that you don't have to worry about parsing anything funny at all, just about disabling (if they're implemented in the language of your choice) ASK and TELL. The disadvantage is that it leaves relatively little power in the hands of the player (whose only choice is whether to have the conversation or not to have it). TALK TO also locks the player into whatever characterization you have chosen for the PC. Stephen Granade's Common Ground exemplifies both the advantages and the drawbacks very well, I think. Ian Finley's Kaged, Kathleen Fischer's Masquerade, and assorted others have also made use of TALK TO.
This is an arena in which the writing skill of the author will make or break the game. If you are a skilled author capable of conveying a fair amount of character and emotion even in these set pieces (as Ian Finley, for instance, does, in my opinion), then you may be able to maintain a sense of immersion.
Menu Conversations. When your player wants to communicate, he types >TALK TO JONES and there appears on his screen a menu of three to six sentences he can say at the moment. Perhaps there is also an option to say nothing. Jones then replies, and the player may be given another menu, and so on, until the conversation ends. Photopia worked on a system like this, and some the existing libraries for handling menus in inform are at least partly derivative of the Photopia ones.
The advantage here is that again the author has control over the form of communication. You can hand the player a bunch of clever quips to say, which characterizes the player character as well as the NPC. (For player characterization that takes place to a large extent in the library menus and the PC's deployment of them, see Rameses, by Stephen Bond.)
The problem is that menu systems are fairly restrictive; sometimes the menu doesn't contain anything that the player wants to say, and there's no way to change what's on the menu, or even the illusory feeling of freedom that comes from typing >ASK JONES ABOUT THEOLOGY, even if no response has been implemented.
Another problem is what Duncan Stevens has referred to as the lawnmower effect. If you give me a series of menus, I don't have to do any work to get through the conversation, and I can methodically (using undo, for instance) go back and replay different variations, taking now the first and now the second path, until I am sure that I've seen the whole thing. The NPC is then finished, with no more thought on my part than I give to methodically mowing a lawn.
From my point of view, this lessens involvement. If you are writing a highly directed, railroad-esque game like Photopia or Rameses or Being Andrew Plotkin — preferably something so vividly written that the story or the humor of the narrative will make me want to move forward as rapidly as possible — then this may be right for you. If you're writing a game based on investigation, allowing the player to shape his own character, or leaving large stretches of the plot in the player's hands, then you may be better off with something more open-ended.
Ask/Tell. ASK/TELL is the standard built into Inform, and is the most common form of NPC interaction in the Infocom games and some other old-school works. It allows the player to ASK or TELL the NPC about any keyword he chooses, and get a response. The approach is obviously more flexible for the player than a menu conversation, and works better with knowledge-based puzzles where the player may be discovering and ASKing about new information as his understanding improves.
From the player's point of view, however, this can mean minimal characterization of the PC, and severe restrictions on what it's possible to express. Usually the game won't accept more than one or two words there, so >ASK JONES ABOUT THE TIME OF THE MURDER is likely to fail flamingly. The 2000 Comp game 1-2-3 tries to get around this, but it does so by prompting the player in an incredibly annoying fashion, and it is remarkably inflexible about WHICH long string of words it will accept.
Keyword-based 'natural language' input. Jon Ingold's game Insight allows the player to type complex natural questions such as BOB, WHO IS YOUR WIFE? or FRED, WHY ARE YOU ANGRY? Since I haven't seen the source code, I'm not sure exactly how this works, but I assume that it involves picking out the keywords (WIFE, ANGRY) and identifying a type of question (WHO, WHY, etc), and triangulating on an appropriate response from there. To take a relatively spoiler-free selection from early in the game:
>man, who are you?>mackenzie, what is your name?
"My name's Mackenzie. But I, er, guess you already knew that. What do you want to know? You know it all already, right? I've been working - living - in Olympia. I'm a genetic designer."
"You already know my name, of course you do," he replies.
>mackenzie, where is olympia?
"Nice enough place, I guess," he says. "We have a lot of problems with the windstorms because of the nearby mountains. I've been working on solutions for that, using plants."
>mackenzie, do you come from olympia?
-- Please be more specific about what you want to say.
>mackenzie, who else lives in olympia?
"I'm sorry," Mackenzie replies. "I didn't quite follow that."
When it worked, I found the effect pretty fascinating. Where the parser realizes it can't interpret, it can give a relatively satisfying excuse. It's the middle case that's the most disconcerting, where the game mostly understands but misses some critical nuance. The response for "where is Olympia?" doesn't sound exactly right; it seems to have caught the keyword "Olympia", but not to have interpreted "where?" properly. And the "Please be more specific" line isn't helpful at all, since the question struck me as fairly specific.
I don't mean to seem too critical, because this game is attempting something extremely difficult. The problem is that faking a natural language understanding always leaves some notable gaps. What can be forgiven in a chatterbot becomes a bit more serious in an IF game, where the success or failure of an interaction determines whether or not the player will be able to see the rest of the plot and finish the game in a satisfying way.
Meta-conversation Verbs. Adam Cadre's Varicella uses a form of modified ask/tell that allows for a little more player control of the PC's behavior. The ask/tell system works the same way as ever, but you are allowed to adopt one of three tones of voice: hostile, cordial, and servile. To take an example from the very beginning of the game:
You adopt a cordial manner.
>ask steward about nails
"How's the manicure proceeding?" you ask.
"Shouldn't be much longer, sir," the steward says.
The steward expertly attends to your fingernails with an emery board.>tone hostile
You adopt a hostile tone.
>ask steward about nails
"How much longer is this going to take, you mediocre manservant?" you bellow.
"Shouldn't be much longer, sir," the steward says.
The steward lightly blows on your fingertips.
You adopt a servile posture.
>ask steward about nails
You're scarcely about to address a common servant in an obsequious tone. For heaven's sake, where is your self-respect?
Reactions to this system have been mixed. I found it entertaining to go around seeing what interesting variations on the various statements I could get by changing my tone of voice, but I also frequently forgot to set the tone correctly and found myself acting inappropriately. And the more engrossed I was in the game, the more likely I was to forget about the tone system, which meant that I used it more as a toy than to get at the actually interesting variations that I understand are buried there as a result.
Another experiment along similar lines is Forever Always, which permits the player to use adverbs to control the tone of conversation. The player can, for instance, WHISPER HUSKILY, SHOUT ANGRILY, SPEAK POLITELY, etc. A menu of options appears, and its contents depend on what manner of speech you chose. This system, unlike the one in Varicella, lets the player see what he is going to say before he says it, so the effect of the different tones is a bit more obvious. The game is not flawless, but the problems in the later scenes seems to stem more from bugginess and lack of testing than from problems with the system as such, which is fairly interesting.
Both Varicella and the Forever Always have systems designed for a game where emotional states and relationships between characters are of primary interest; one's a palace intrigue, the other a romance-novel parody. The Forever Always system might not be at all successful for a game that centered on information gathering, since the player isn't allowed to specify keywords, and there's no potential for following up on, say, the clues of a mystery. On the other hand, I think it actually works better than the Varicella approach for the specific and limited purpose of doing character-emotion-based IF. (Since Varicella is partly about discovering information, the adverbs-only approach wouldn't have worked there.)
A word of caution, however. It's important, when expanding a conversation system to include new verbs, not to leave the player with an unmanageable number of options. In Varicella it was possible to keep track of the three tones of voice, but other suggestions I've heard (such as a >BE SYMPATHETIC command) or tried to implement myself (a system including COMFORT, INSULT, APOLOGIZE, FLIRT, SEDUCE, SMILE, LAUGH...) can lead to confusion: there's too much to write for the author, and the player doesn't have enough direction. It might be possible to write a good game with some subset of these options, but I haven't seen one so far. The author would have to exercise a fair amount of restraint in the design, I think.
Topic Words. Used in games such as J. D. Berry's SmoochieComp game Sparrow's Song and the older comp game She's Got a Thing for a Spring, this functions very much like ask/tell, except that the verbs themselves are omitted. The player simply types a word he wants to bring up and the conversation proceeds accordingly. This isn't so much, in my opinion, a new interface as it is a slight streamlining of an existing one — but it does excuse you from having to program separate reactions to ASK and TELL.
Modified Menu/Topic Hybrid. This system combines the freedom of ASK/TELL with a menu system. When you begin a conversation with someone, you see a menu of the possible things to say listed in the status line, and you may say one of them simply by typing the corresponding letter. If, however, you would like to change the subject, you may also type >TOPIC DIAMOND NECKLACE, and a new menu appears. For instance, >TOPIC JONES might bring up a menu
1. Have you seen Jones anywhere?
2. What does Jones do here?
3. How long has Jones been working for the company?
4. What is your opinion of Jones?
This gets rid of the lawnmower problem and forces the player to take some initiative in choosing how the conversation will go. It also means that you can allow the player to ask questions much more complex than are available in an ASK/TELL system, but without completely giving the game away by including questions like >ASK THE QUEEN WHETHER IT IS TRUE THAT SHE STOLE THE PRINCESS' DIAMONDS into a single main menu with >QUEEN, HELLO and >DO YOU KNOW WHERE I COULD GET MORE OF THIS SCRUMPTIOUS CAVIAR?
At a slightly more technical level, it also allows for single-exchange undos. In menu-driven conversations a common problem is that a whole conversation will elapse in a single 'turn'; if you don't like the way it went, you have to undo the whole thing and restart from the beginning. This is somewhat irritating.
One major drawback of this system is that it requires more writing to implement usefully than any other. Simple ASK/TELL usually means that the author has to write two responses for character for each major topic of conversation; if the plot is very complicated, or it's possible to get the NPC into more than one state of mind, then the author might have to write some variations on these responses, as well. With the menu system, in order to give the impression of a full implementation, the author winds up writing several questions and answers per topic per character. This can rapidly slide into the realm of the ridiculous.
Back to Contents
Beyond the task of coming up with a bunch of topics is the problem of making the resulting conversation plausible.
Flagging Used Topics. One of the least person-like habits of the typical IF NPC is that he always answers the same questions in the exact same words, regardless of how many times the player has asked. This issue need not come up in quite the same way in a menu-based conversation, since you could disable questions that have already been asked, whereas there's no good way to prevent the player from typing >ASK JONES ABOUT HAT ten times in a row.
At its most basic level, this is just about preventing the NPC from saying the same thing over and over and over again. Real people don't repeat the same words in the same language a hundred times in a row, and it detracts from the feeling of realism if your NPC does.
There have been various conversations on rec.arts.int-fiction about what sort of response is appropriate if the player tries to reask a question. Acceptable options, in my opinion, include: having the parser cut in and say, "You remember that Jones told you..."; having Jones tell you again but in a slightly modified form using some kind of randomization of text (so that over time you would get similar text over and over, but it wouldn't be identical each time); or describing the conversation without telling you the exact words ("Jones tells you again that...").
Managing Recaps. Another nice thing about having flagged which conversation topics have been used is that you can offer your players, if you wish, some kind of RECAP verb to remind them of what they've already discussed. In conversation-intense games this may be the only way to spare the player some tedious note-taking.
Making New Comments Available. In the natural course of a conversation, when one thing has been said, new comments become natural. If you're flagging which comments/topics have already been used, you may want to add new items to the menu when appropriate, or allow the player to >ASK ABOUT new things (or get new responses when asking about old things).
Contextually-based Reactions. In real life if you're talking to someone and that person starts to read a book, you may take a message from the fact. Likewise, there are spots in conversations where it may be more or less appropriate to react to the other person with advances (>KISS JONES) or violence (>KILL JONES WITH ROCK). If you have a system of conversation that tracks what the current topic of conversation is, and whether anything is actively going on, you can use it to tailor appropriate reactions for KISS, GIVE, SHOW, HIT, et al.
Somewhat more subtly, context in conversation can also be used to interpret the meaning of the player's keywords. For instance:
[The PC and Inspector Lynley have been discussing murder victims.]
>ask lynley about veronica
"Do you think it could possibly have been Veronica?" you suggest. "I overheard her arguing with the victim last night."
As opposed to:[The PC and Inspector Lynley have been chatting about their love lives.]
>ask lynley about veronica
"How well do you know Veronica?" you ask. "I'd like to ask her out, but I'm not sure whether things are really over between her and Marcus."
This kind of refinement is irrelevant, obviously, with a menu-based conversation, but for ASK/TELL it can lend a nice sense of depth. It takes some work, though, to make sure that really important questions never become entirely impossible to ask just because the conversation context is set wrong. If the player desperately wants to accuse Veronica of murder, he'll be frustrated if the game only permits questions about her love life.
Abstract Knowledge. One of the artificial abilities we might like to give our NPCs, aside from the ability to wander around a map intelligently and carry out complex goals, is the ability to understand what they are told: to keep track of what items of knowledge they have so far, use them to change their plans and goals, and even draw logical inferences from what they've learned.
Like the artificial intelligence involved in world manipulation, this is a theoretical problem that remains mostly unsolved, and that would probably only produce useful results in a fairly limited number of games. All the same, some libraries have been written to begin to deal with the problems involved. There are some libraries in the Onyx Ring collection, for instance, which are intended to let the NPCs learn new facts and communicate them back again.
Using abstract models of knowledge like this might produce greater flexibility, but it might create some large difficulties in terms of controlling gameplay and ensuring that the writing did not begin to seem too mechanical.
Back to Contents
The emotional state of the NPC is effectively another kind of context to what is going on. It's fairly easy to track emotions by giving each NPC a variable or series of variables which are affected by each conversational exchange (so that an insulting remark increments the Anger variable, for instance). It's more challenging to use the resulting variables to good effect.
Gesture. Emotional cues can be buried in a conversation through body language. An upset person may have a nervous tic; a lustful one may cast steaming glances in your direction.
The more important the character's mood is to the game outcome, the more you need to signal the changes and current state to the player. Modifying a character's description may be enough to let the player know what the current state is in some cases. In others — especially if the character's mood is changing frequently over the course of a deeply engaged conversation — you may need to make those changes more explicit. After all, if the player is talking to an NPC, you are probably safe in assuming (unless they're talking on the telephone, or in the dark) that they can see each other, and that dramatic changes in the character's attitude will be readily visible.
Altering Responses Based on Mood. Obviously an upset person will react to certain topics more vehemently than a calm one would. Inserting switches into the dialogue itself to test for variables is another fine way of handling this.
Back to Contents
Steering Topics. NPCs give the impression of being much more active and thoughtful if they show signs of having a private agenda of their own — which may include raising new conversational topics, deciding to cut a conversation short, and so on. There's a trade-off here again: the NPC who takes actions and doesn't wait for the player may seem more dynamic and alive than an NPC who sits around being questioned at the player's whim, interspersed with turns of the PC taking inventory, looking under sofa cushions, and unlocking safes. And if you have a specific set of information you need to convey to the player, sometimes it's useful to have an NPC who will just keep coming back to that topic until it's been adequately covered.
On the other hand, if the NPC is too active and too much in control, the player may feel that there's nothing left for him to do. He may be floundering for topics to discuss, trying to guess the noun, or otherwise having trouble with the interface, while the NPC blathers on and on. It can be fairly challenging to get this to come out right, so perhaps the best plan is to avoid too many long chains of conversation for the NPC; if the PC isn't saying anything, the NPC should perhaps stop eventually as well.
This is another area that hasn't been very extensively explored yet, so there aren't many good examples on which to draw. When trying any new direction in NPC development, I recommend playtesting the game a lot, perhaps starting in alpha stages. Don't set the system in concrete before you've gotten some kind of feedback on how well it works. It's easy to design something elaborate and completely unplayable.
Back to Contents
Back to Main Page
All text and images on these pages copyright Emily Short, 2001-3.
Contact me at firstname.lastname@example.org with any questions or comments.