\input texinfo   @c -*-texinfo-*-
@c
@c $Id: etalk.texinfo,v 1.10 1995/07/21 02:41:57 zappo Exp $
@c
@setfilename etalk.info
@settitle Emacs Talk

@ifinfo
@format
START-INFO-DIR-ENTRY
* Etalk: (etalk).       Emacs mode used to talk with other users.
END-INFO-DIR-ENTRY
@end format
@end ifinfo

@titlepage
@sp 10
@center @titlefont{Emacs Talk v0.10}
@vskip 0pt plus 1 fill
Copyright @copyright{} 1994, 1995 Free Software Foundation
@end titlepage

@node Top, , (dir),   (dir)

This file documents Emacs Talk v0.10B.  An emacs mode used to talk with
other users who are running emacs talk, or the either version of the BSD
vanilla talk program.

Copyright @copyright{} 1994, 1995 Free Software Foundation

@menu
* Introduction::
* Known Bugs::           Stuff I need to fix
* Wishes::               Stuff I'd like to have done
* Connecting::           Creating a connection to another user
* Talking::              How to edit, and manipulate talk buffers
* Advanced Features::    Special things you can to in etalk
* Tyrant Mode::          Game playing sub-system
* Log Buffer::           The etalk server command and log buffer
* Finger Mode::          Special mode for perusing finger lists
* Hooks and Variables::  Customization with available hooks
* Configuration Files::  Configure files to help etalk go faster.
* Programmer Goodies::   Routines other programmers may like to use.
* Index::
@end menu

@node Introduction, Known Bugs, ,Top
@chapter Introduction
@cindex Introduction
@cindex BSD talk
@cindex GNU talk
@cindex SunOS talk

Emacs talk is a program written in c and emacs-lisp which allows the
user to create talk connections to other users following the BSD talk
standard.  

The BSD talk standard allows a user program to send network messages
to a talk daemon on any supporting machine which can produce an
announcement message on their terminal.  Through the use of a talk
program on their machine, they are able to complete a network
connection.  This connection allows typed text to be displayed in a
window on their terminal, and for their typed text to be displayed on
your window as well.

Emacs Talk takes the standard talk protocol one step further, by
allowing connections to more than one individual to take place and be
displayed on one terminal.  From within emacs talk you are able to
manage connections to several people, all using different talk programs.
If these other users are also using etalk, you can then, in turn,
generate windows to all the people they, in turn are talking to.

Additionally, SunOS's older talk message format is also supported, and
with etalk one can connect between a Sun using this older daemon, and
any other machine with the newer protocol, but only if both sides use
etalk. (There is a program known as ytalk, which may work with etalk
over these barriers as well.)

Lastly, some extensions to the ntalk protocol have been added for use
with the GNU talk daemon, and support for them are in etalk.  These
extension include a "reply" feature, and the ability to redirect rings.

This manual starts by discussing the nuances of creating a connection to
another user with etalk, which is followed by a discussion on how to use
the various editing commands, the advanced features, and Tyrant mode, a
game playing feature.  The last two chapters discusses manipulation of
the etalk server executable through the log buffer, and
@code{finger-mode}, an extra mode which treats finger information the
way @code{dired} treats directory listings.
@refill

@node Known Bugs, Wishes, Introduction, Top
@chapter Known Bugs
@cindex bugs

@enumerate
@item 
OTALK version is actually a misnomer, since it is not compatible with
versions before BSD 4.2.  Instead, it represents the protocol used on
SunOS.
@item
The first keystroke in tyrant mode seems to go to the last buffer the
process was bound to.  This is a bug in emacs 19.23 and before.  It has
been fixed in future versions.  My suggestion is to hit @kbd{C-h} if you
use such a version as your first keystroke.  Things work ok after that.
@item
First keystroke AFTER a filter changes buffers/modes will go to the
previous buffer.  This seems similar but different to the previous bug
from emacs 19.23, but still occurs in emacs 19.27.  Other similar
instances are if auto-answer picks up creates a connection, and
entering/exiting tyrant mode.
@item
While byte compiling, the out of date variable
@code{unread-command-char} is used.  I assume that leaving this in will
preserve compatability to 18.  I don't know much about this aside from
that it works now.
@item
Hostname completion on systems with really huge lists used to get weird
sometimes.  In addition, when done in conjunction with a ~/.hosts.talk
file, duplicates appear.  Therefore /etc/hosts is no longer parsed. The
only files checked now are /etc/hosts.talk and ~/.hosts.talk
@item
The @code{word-thing} game will only work if the initiator has "spell"
installed on their system.  If anyone knows how to use ispell to do the
same thing, please let me know.  @code{word-thing-spell} is the function
to play with.
@item
When two etalk users are taking advantage of previous-line deletion,
occasionally the two talk buffers desynchronize.
@end enumerate

@node Wishes, Connecting, Known Bugs, Top
@chapter Wishes
@cindex wishes

Some things I'd like to have done:

@table @kbd
@item Interfaces
The etalk binary was meant to be a subprocess used for handling
connections to other machines via talk deamons, or any other method of
communication.  Someday I would like to have several interfaces to this
talk program.  A tty/termcap version, and an X version would be kool.  I
may just make new applications with the etalk code linked in.
@item OTALK
This talk program is designed for older talk protocols to be used.  It's
supposed to work with suns, but my access is limited.  Bug reports in
this area would be greatly appreciated.
@item GUILE
I'd like to some day integrate GUILE in.  I'm not sure EXACTLY what it
would be useful for, but with auto-answer abilities, it might prove a
nifty way to create an answering machine of sorts.
@item GAMES!
I'd love to have more games under emacs talk.  Some of the interfacing
has been simplified from the last version, making this much easier to
deal with.  There is a new section in this document on it.  In addition,
if you have an AI program you would like to share, please let me know
and chances are we can design an interface under tyrant-ai.
@item tyrant-mail?
The games and tyranting system could be modified to read mail messages,
and provide a convenient error-checking method for playing these games
a move at a time.  I do not know if the effort would be worth the
rewards.  If you have an opinion let me know.
@end table

@node Connecting, Talking ,Wishes , Top
@chapter Connecting
@cindex connecting

There are several methods for creating a connection to another user.
These methods should be used in conjunction with the restrictions to be
dealt with while connecting to the individual in question.

For those commands within emacs, a special minibuffer completion for
usernames is provided.

Only one connection of any type may be waiting for an answer at a time.

@menu
* etalk::               Generating a talk connection within emacs
* etalk-reply::         Starting etalk by "answering the phone"
* etalk-mail::          Using email as your talk service.
* etalk completion::    Using etalk minibuffer completion
* etalk-batch command:: A command line startup function.
* etalk ringer::        Having emacs automagically answer the phone.
@end menu

@node etalk, etalk-reply, Connecting, Connecting
@section @code{etalk}
@findex @code{etalk}
@cindex @code{etalk}

To create a standard connection through use of the BSD talk daemon, one
must simply type:

@example
M-x etalk RET
@end example

which will then prompt for who you want to connect to.  After typing in
a username of the form:

@example
user@@machine.name tty
or
machine.name!user tty
@end example

where the tty is optional, one must hit return and wait for the
connection to complete.  @xref{etalk completion}

While the connection is being created, a status is displayed in the
minibuffer each second, declaring how many rings have been sent, and how
long we have waited.  Once a connection has been completed, the result
is displayed in the minibuffer.

To cancel a call, one must simply use the hang up command to cancel the
connection.  @xref{Talking}

@node etalk-reply, etalk-mail, etalk,  Connecting
@section etalk-reply
@cindex etalk-reply
@findex etalk-reply

The use of @code{etalk-reply} can only be used if you have the GNU talk
daemon installed.  The REPLY command uses a protocol extension which
asks the local daemon who the last person who rang you was.

When this value is returned, emacs grabs the name, and asks if you wish
to talk to that individual.

To do this, simply wait for an announcement message, and say:

@example
M-x etalk-reply RET
@end example

When you are asked to connect to a specific individual, say @kbd{y}.

This convenience is supplied to make figuring out who just rang you
simpler.  Many times the name of the person gets erased when your editor
or whatnot is suspended and you loose the address.

@node etalk-mail, etalk completion, etalk-reply,  Connecting
@section etalk-mail
@cindex etalk-mail
@findex etalk-mail

The use of etalk-mail is out dated with the addition of support for both
the talk protocols NTALK and OTALK, and the inclusion of the GTALK
daemon with this distribution.  This method of connection overrides the
need for compatible talk daemons, or even the existence of one.

To use, one must simply say:

@example
M-x etalk-mail RET username@@machine.name tty01
@end example

Where the tty is technically irrelevant.  @xref{etalk completion} for
more details on using the prompt.
@refill

The user is then greeted with an emacs mail buffer which is mostly
filled out for you.  All that is required is to send it with
@kbd{C-cC-c}.  Additional comments, however, certainly don't hurt.

The user on the machine receiving this message will eventually notice
that it exists.  At this point there are two options.

If you receive a message from etalk, and you use rmail, vm, or other
emacs mail program, simply set the message buffer as your default and
type:

@example
M-x etalk-mail-reply RET
@end example

and your message will be parsed and a connection made directly from the
port number listed in the talk message.

Option two is to read the message, and find the port number from the
Etalk-Reply-To: field.  Then type:

@example
M-x etalk-mail-reply RET port RET
@end example
@findex etalk-mail-reply

where port is typed text from the mail message.

For people stuck with UUCP based mailers, this option will not work for
you when sending mail off site, no matter how hard you try.

@node etalk completion, etalk-batch command, etalk-mail, Connecting
@section etalk minibuffer completion
@cindex etalk completion

When being prompted for a username by etalk, several completion methods
are available.  First, the form of the internet address must be chosen,
which can be of the form:

@example
user@@machine.name tty
or
machine.name!user tty
@end example

For convenience, we will use the @@ form here.

Lets say we wish to connect to someone on a remote machine, but we are
unsure which user to connect to.  We simply start the address on the
command line like this:

@example
Talk to whom? @@c-!-
@end example

where -!- is the cursor, and hitting @kbd{SPC} starts short completion.
We are then rewarded with all machines which start with @samp{c}.  Once
this name is unique, the name will be completed, leaving us something
like this:

@example
Talk to whom? -!-@@choochoo.ultranet.com
@end example

Now, if we hit @kbd{SPC}, finger is run with the host name as the
parameter, the output is read in, and parsed, and available completions
are listed as combinations of username and tty.  Various message may
pass by as etalk attempts to get the information you need.  If we type
in a part of someone's username, we can complete that.

@example
Talk to whom? zappo@@choochoo.ultranet.com-!-
@end example

Now @kbd{SPC} will move the cursor one space preparing for the tty.
Completion here is the same as for the username, leaving us with
@samp{tty} at the end of the line.  When more than one tty is available,
and you are unsure which one to use, hitting @kbd{TAB} will look at each
of the available completions, and choose the individual with the least
amount of idle time.

@kbd{TAB} will complete as far as possible from any other point in this
example as well.

If we hit @kbd{SPC} or @kbd{TAB} now, we will be given a completion
message of @samp{[Matched: 240 minutes idle]}, indicating how long that
tty had been idle.
@refill

To accept this information, simply hit @kbd{RET}.  In this case, we will
get the question:

@example
zappo has been idle for 240 minutes.  Really call? (y/n)
@end example

A no response will return you to the username query.

Other available keystrokes are:

@table @kbd
@item M-TAB
Use finger on this individual and print all finger and process
information in a new buffer.
@item C-r
Rescan the selected host to get new users, or logout information.
Changes are summarized in the minibuffer.
@item C-h
Help buffer.
@end table

Managing lists of hosts for completion:
@vindex etalk-morehosts-file

Host names are read from the files @file{/etc/hosts.talk}
@file{~/.hosts.talk}.  When these files are too large, a query of

@example
@samp{Hosts file will take a long time to parse. Parse?} 
@end example

A no answer will result in no host completion unless a list of your own
hosts are available in @file{~/.hosts.talk}.  If this file is not
satisfactory, you may choose your own filename by filling in the
variable @code{etalk-morehosts-file}.  The format is the same as found
in @file{/etc/hosts}, which is the IP address followed by the name, and
the type of talk daemon just after it.
@refill

@node etalk-batch command, etalk ringer, etalk completion, Connecting
@subsection etalk-batch
@cindex etalk-batch
@findex etalk-batch

@code{etalk-batch} is a function which will allow a user to execute a
shell command and start emacs instantly into etalk mode.

To use this feature, simply create a shell alias with the value

@example
emacs -f etalk-batch
@end example

Binding this to some string, such as to @samp{etalk} will allow you to
say:

@example
etalk zappo@@choochoo.ultranet.com tty02
@end example

which will start an emacs up, and make it automatically connect.

Hopefully, someday this will also work with @samp{emacsclient} to allow
some really nifty and handy functionality, but I am unsure if that kind
of information processing is possible.

@node etalk ringer, ,etalk-batch command, Connecting
@chapter The etalk ringer
@cindex ringer file
@cindex auto answer

With the creation of the GNU talk daemon, and some of it's advanced
features, etalk is now able to automatically answer the phone.  This can
be done easilly through the menus, or with the command @kbd{M-x
etalk-ringer-on-command}, and turned off with @kbd{M-x
etalk-ringer-off-command}.  Never forget that the etalk process will be
started if it is not allready running.
@refill
@findex etalk-ringer-on-command
@findex etalk-ringer-off-command

When this feature is turned on AND your local host is running gtalkd,
then the next time someone attempts to use talk with you (reguardless of
the version of talk that individual is using) all talk requests will be
forwarded to your etalk session.  It is possible for the other person to
force the GNU talk daemon to write to your TTY instead of using the
ringer protocol by specifying a tty to write to.

When your ringer is on, the file @file{~/.ringer} is created with a
network pointer to etalk.  Etalk then recieves a network packet
specifying information about the talk request be asked for.  If you set
this feature, then start editing your next piece of free software you
plan on releasing, you could randomly be asked:
@example
You just got a call from %s; Answer?
@end example
to which you should reply @kbd{y} or @kbd{n} depending on if they like
to write free software as well.  Because the y/n query is conducted in a
true minibuffer, you may switch to another window with @kbd{C-x o} and
then switch to the buffer ``*ETALK LOG*'' to see the complete details of
the ringer packet which was sent to you before making the important
decision to answer the call.

If you do not wish to be asked this question, you may opt to have emacs
always answer the phone.  To do this, set the variable
@code{etalk-auto-answer} to @code{t} and this will happen.  Be warned
that it can be VERY disconcerting to have the file you were editing
being completely and randomly replaced by a talk buffer.
@vindex etalk-auto-answer

@node Talking, Advanced Features, Connecting, Top
@chapter Using talk mode
@cindex etalk-mode

Once a talk connection is completed, a wide selection of options becomes
available, the extent of which depends on if the remote user is also
using emacs talk or not.

The simplest act is simply to type.  Any typed character is sent
verbatum to the remote machine. Other editing commands are listed below:

@table @kbd
@item DEL
Delete one character backwards.
@item C-w
Delete one word backwards, and store text in kill ring.
@item C-u
Delete one line of text backwards, and store text in kill ring.
@item C-y
Yank text from kill-ring into the talk buffer.
@item C-x i
Load text from a file, and insert it into the talk buffer.
@item C-g
Sound the bell (both sides).
@item C-h
Help in minibuffer, or describe mode.
@end table

Note that @kbd{C-u} is delete-line backwards.  This is to provide
compatibility with other talk protocols which also act this way.
(Additionally, @kbd{M-DEL} doesn't really translate well to a 7 bit edit
character.)  If you preferred the older @kbd{C-k} binding, simply set
the variable @code{etalk-edit-characters-mine} to the string "^?^K^W"
instead.  The keybindings are magically keyed from this string so it
must be set BEFORE loading the etalk library.
@vindex etalk-edit-characters-mine

Other commands are used to manage the windows the talk buffers are in.
The buffers are labeled with the usernames of the individuals.  The
local talk buffer will have your full finger name in it.  Remote talk
buffers will contain their address in the form @samp{zappo@@choochoo}
with the option of their finger name following that, if they are using
emacs talk as well.

Commands to manage windows are as follows:
@table @kbd
@item C-r
Refresh the windows.  This gives each window the same number of lines
(or at least an approximation there of) with the local buffer on the
bottom of the screen.
@item C-c r
Refresh windows with one other buffer at the top.  This is useful when
referencing some other file while talking to another user.
@item C-c c-r
Refresh windows with the log buffer as the top buffer. @xref{Log Buffer}
This allows a view of what the server is doing while talking or waiting
for connections.
@item C-l
Refresh/clear screen.  This acts as @code{re-center} does, except all
text is scrolled above the top of the window, effectively clearing the
screen.  Handy if someone wanders in and you don't want them to see what
you typed.  It is similar to the VMS PHONE command, except the text
isn't completely erased.
@end table

Lastly, there is a keystroke to delete a connection, which is simply
@kbd{C-c C-c}.  This will send a hang up message to the server, and close
the connection to a user.

@cindex Multiple connections
In all cases, except when refreshing window geometry, the keystrokes
entered are connection specific.  When only one connection is open,
there is only one possibility.  Initiating multiple connections is
identical to initiating one connection.  The result is more windows
open to more people.  If more than one window is open, any command
entered in the local window affects all connections.  Thus text entered
is sent to all windows.  Even the hang up command will hang up on everyone
if entered in the local window.

To allow more selective communication, one must simply move the point
into one of the available remote windows to make editing commands affect
that individual only.  This holds true for all of the advanced features
as well.

@node  Advanced Features, Tyrant Mode, Talking, Top
@chapter Advanced Features
@cindex advance features

There are several features only available when two individuals are both
using emacs talk.  None require that there be only one connection from
each server, but it often does help ones sanity.

The features are varied, and listed in the following table:
@table @kbd
@item C-x I
Send a file to the remote emacs, and place in it's own buffer, and
display that at the top of their buffer list.
@item C-c m
Send a message to the remote which will appear in their minibuffer.
@item C-c h
Send a message string ``*HUG*'' into the remote minibuffer.
@item C-c o
Get a list of all users the remote is talking to who are also using emacs
talk.  When the list is returned, you are prompted for each individual
to create a connection to them.
@item C-c g
Query the remote and ask if they wish to play a tyrant mode game.
@xref{Tyrant Mode}
@end table

Each of these commands are connection specific.  @xref{Talking}

@node  Tyrant Mode, Log Buffer, Advanced Features, Top
@chapter Tyrant Mode
@cindex tyrant mode

Analogically, tyrant-mode is a minor-mode used for taking over innocent
major modes.  Tyrant mode will usually be seen under the controlled use
of emacs talk for the playing of games against other network bound
users.  It works by rebinding the keyboard, and referencing all
keystrokes to the game's local keymap.  Valid keystrokes are then sent
over the network, and simultaneously executed locally.  When keystrokes
are received from a network connection, the command that key is bound to
is then executed.  Thus, two independant emacses can play the same game
together.

To initiate a game, one must have an open connection to someone using
emacs talk.  Then the keystroke @kbd{C-c g} will prompt you for the game
you wish to play.

Once a game is selected, the remote is queried to play that game against
you.  If they choose yes, then that game is automatically started.

It also possible to start up a select few games to play against the
computer.  To do this, use the command @code{tyrant-play-computer} which
uses tyrant mode to play against some function written in lisp (which can
do whatever it wants to make decisions.)  Tyrant-ai has the same
controls as tyrant mode under etalk.

@menu
* Playing a Game::      General game features, and specific rules.
* Installing Games::    How to install and configure all the games.
* Writing Games::       How to write a game to use under tyrant mode.
@end menu

@node Playing a Game, Installing Games, Tyrant Mode, Tyrant Mode
@section Playing Tyrant mode games
@cindex tyrant-mode games

Once a game has been started, there are some standard commands
available, which are:

@table @kbd
@item C-c C-c or C-x k
Cancel this game.  Doing so asks both sides to hit return, which
restores the original talk windows.  The reason @kbd{C-x k} is also
listed is because killing the buffer would terminate the connection, not
cancel the game.
@item C-h
Tyranted game mode help.  This will offer some help for tyrant mode, or
the game in question.  @kbd{C-h} twice will do a @code{display-mode}.
@item C-c m
Send a message to the opponent in the minibuffer.  This allows some
communication during the game.
@end table

For the impatient, most games have the following key bindings for
consistency:

@table @kbd
@item f, C-f
Move forward (left)
@item b, C-b
Move backwards (right)
@item p, C-p
Move previous (up)
@item n, C-n
Move next (down)
@item SPC
Do something (grab, move, etc)
@end table

For these keys, when possible, the arrow keys (vt100 under 18, and all
emacs 19 terminals supported) will be mapped to the correct direction,
and converted into the sequence @kbd{C-f}, @kbd{C-b}, @kbd{C-p} or
@kbd{C-n} so the remote can interpolate it. @refill

Also, in many games, there is mouse support under emacs 19.  In general
a @code{click} event moves the mouse to the clicked on square, and does
the same thing @kbd{SPC} would.  @code{mouse-movement} and @code{drag}
events simply move the cursor about within the confines of the board.
@refill
The only caution is with mouse movement events.  When playing over the
network, you can seriously overload the net and the parsing ability of
the remote, and pull the two boards out of sync.  I strongly suggest you
drag slowly when using tyrant mode, or just skip it and only use 'clicks
to do what you want.

Because mouse commands are converted into tyrant control messages, mouse
commands will be allowed when the other user is not using an X display.

Lastly, when playing over the network, tyrant-mode will keep track of
the current turn, and your keystrokes will only be valid if it is
currently your turn.  You can tell when it is your turn because the
string ``T-Con'' appears in the list of minor modes, meaning the console
is in your terminal.

The etalk distribution comes with the following games, and it is very
easy to add or write new games.

@menu
* Talk Tac Toe::    Simplistic tic-tac-toe game
* Hangman::         Hangman!  Player one makes up a word, player2 guesses.
* Drop 4::          Drop pieces to get 4 in a row.
* 4 by 4::          A drop 4 derivative that is even more challenging.
* Word-Thing::      Make words from tiles, and place them on a board.
* Dots::            DOTS! Not just for paper anymore.
* Reversi::         An othello like game where you battle for stones.
* Chinese Checkers::That weird marble game.
* Order and Chaos:: A weird game of pure Offense/Defense for Order/Chaos
* Ataxx::           That funny blob game.
* Checkers::        Checkers.
* Gess::            Gess game (Go chESS) as seen in Scientific American.
* Trax::           That nifty tile game from New Zealand.
@end menu

@node Talk Tac Toe, Hangman, Playing a Game, Playing a Game
@subsection Playing talk-tac-toe
@cindex talk-tac-toe

@dfn{Talk-tac-toe} does not require the use of tyrant mode and can be run
without it.  It makes a buffer with a simple tic tac toe board in it.
To play, just hit a number and your move is recorded in the
appropriate square.  When it isn't your move, the tyrant will tell you
so. 

@node Hangman, Drop 4, Talk Tac Toe, Playing a Game
@subsection Playing hangman
@cindex Hangman

Hangman does require talk to be running.  It too is simple.  The
initiator is required to type in an initiation string.  This string has
to be < 30 characters, and all upper case letters and symbols are not
turned into @dfn{_} characters.

The initiator then watches, and can send messages @kbd{C-c m} while player
two hits letters until he gets the word, or runs out of body parts.

It's fun.  Trust me. :)

@node Drop 4, 4 by 4, Hangman, Playing a Game
@subsection drop 4
@cindex drop4

Drop 4 is a tic tac toe like game.  Your pieces start at the top of the
screen, and hitting SPC drops that piece.  The purpose is to get 4 in a
row.  The pieces are:

@example
Player 1  /##\   Player 2 /--\
          \##/            \__/
@end example

@noindent
Keys:

@table @kbd
@item 0-9
Select that numbered column.
@item f, C-f, . 
Move the piece to the left.
@item b, C-b, ,
Move the piece to the right. (note. @kbd{,} and @kbd{.} are
just under the @kbd{<} and @kbd{>} on most keyboards.)
@item RET, SPC
Drop piece.
@item q
quit.
@item mouse
Drags move the piece left and right.  A click drops.
@end table

This game is very addicting, so be careful.
@node 4 by 4, Word-Thing, Drop 4, Playing a Game
@subsection 4 by 4
@cindex 4 by 4

4 by 4 is a game of my own invention.  It can be played with, or without
tyrant mode running.

It is based on an 8x8 board, and the purpose is to get 4 pieces in a
row.  Like drop 4, pieces always start on one side of the board.
Unlike Drop 4, that side can be any of the 4 walls. (Thus, 4X4)

The player pieces are ``##'' for player 1, and ``::'' for player 2.

The movement keys are the typical emacs movement keys, @kbd{C-f},
@kbd{C-b}, @kbd{C-n}, @kbd{C-p} and their non-control versions @kbd{SPC}
will attempt to place a peice.  The strategies for playing are very
similar to that of drop 4, with the extra elements of the additional
building blocks.  Mouse drag actions will move the selected square, and
a click places a piece.

This game has similar addicting properties as Drop 4.

@node Word-Thing, Dots, 4 by 4, Playing a Game
@subsection Word-Thing
@cindex word-thing

Word-Thing works for both tyrant mode, and by itself.  The concept of
the game is the same as the popular Scrabble game except that many rules
are changed.

The idea is to take your tiles, (in the ``WORD-THING COMMAND'' window)
build a word, and move the outline of that word in the ``WORD-THING
BOARD'' window.  All key presses take place in the ``WORD-THING COMMAND''
window.

A typical hand may look like this:

@example
 +---+ . . . +---+ +---+ +---+ +---+ +---+ +---+ +---+
 |   | .   . |   | |   | |   | |eow| |   | |   | |   |
 | T | . R . | A | | I | | N | |   | | W | | M | | E |
 |   | .   . |   | |   | |   | |   | |   | |   | |   |
 +---+ . . . +---+ +---+ +---+ +---+ +---+ +---+ +---+
Word is now -> TAIN WME <-Score Them [9] You [0]
@end example

Where the tile surrounded by periods ( . . . ) is already on the board,
and the tile with @code{eow} in it marks the @dfn{end-of-word}.  The
score is then placed in the following line.  This hand will place the
word ``TRAIN'' on the board over a word that has an ``R'' in it.

When it isn't your turn, the letters in the tiles are replaced with the
@kbd{?} character, and the letters to your hand are placed where the
``word is now'' points to, so that you may contemplate possible moves.

The currently ``selected'' tile is the one with the cursor on it.
Tile movement is based on the selected tile.

The command keys are as follows.

@table @kbd
@item ,
Select tile to your left.
@item .
Select tile to your right.
@item <
Move selected tile to the left.
@item >
Move the selected tile to the right.
@end table

The choice of some of these keys are based on the configurations of PC
and DEC post VT420 keyboards which have the following keys next to each
other.

@example
+-----+ +-----+
|  <  | |  >  |
|     | |     |
|  ,  | |  .  |
+-----+ +-----+
@end example

Thus, moving a tile is simply a difference of holding down a shift key.

Other important keys are:

@table @kbd
@item C-f, f
Move word marker left on board.
@item C-b, b
Move word marker right.
@item C-n, n
Move word marker down.
@item C-p, p
Move word marker up.
@item t
Turn the word between horizontal and vertical.
@item RET
Place the word at this location.
@item g
Give up your turn if you have a REALLY bad hand.
@item G
Give up your turn, and get some new tiles if your hand is worse than that.
@end table

The following rules hold when playing this version of word-thing.
@enumerate
@item
There must be at least 1 three letter word in a placement.
@item
A word must either overlap the @kbd{*} piece, or another word.
@item
All new or changed words are scored together, including duplicated
letters only if the duplicated letter is one you place down.
@item
Valid words are those passed by the unix spell checker except for two
letter words which must be in an alist in the word-thing source.
@item
There are no bonus squares since they made the words unreadable on the
screen.
@end enumerate

This game will only work if the initiator has spell installed.

@node Dots, Reversi , Word-Thing, Playing a Game
@subsection Dots
@cindex dots

Dots is an old game.  The board is made of lots of dots (hence it's
name) and in emacs' case, plus signs.  A move is to place a line between
two points, either vertically or horizontally.  The goal is to capture a
box.  A box being when you make 4 lines around a center.  At this point,
you have captured a box.  The person with the most boxes is the winner.

The keys are the typical emacs movement keys [C-]f,b,n,p with optional
control being held down.  SPC will place a line.  Mouse actions will
select a line, and a click will put a line down.

When you capture a box, turns are not swapped, your name is placed in
the box, and you may move again.

@node Reversi, Chinese Checkers, Dots, Playing a Game
@subsection Reversi
@cindex Reversi

Reversi is like Othello. A legal move is one where the new piece and an
old piece surround the opponent linearly.  Upon placing a piece, all of
the opponents pieces between the new piece and all old pieces are
scarfed up.  To win, get as many pieces as you can.

Movement is done with the arrows, and SPC tries to place a piece.  Mouse
actions select, or place peices.

@subsection Toreversi
@cindex Toreversi

Toreversi is identical to Reversi with one rather evening exception.
There are no edges.  The board is folded into a torus, or donut shape,
so a move may capture stones over one edge, in any direction, onto the
other side of the board.  This causes many interesting occurances to the
novice, and removes the great importance placed on the edges of the
board.

Movement is identical to that of Reversi.

@node Chinese Checkers, Order and Chaos ,Reversi, Playing a Game
@subsection Chinese Checkers
@cindex Chinese Checkers

Chinese checkers is a game where both players move all their pieces to
opposite sides of the board.  In this ``O'' is player 1, and ``X'' is
player 2.  Movement can consist of one piece either moving to one
adjacent square, or to jump, one piece at a time, as many as they can.

Movement is done with ``Empire'' keys.  Mainly, a map where:
@table @kbd
@item y
Goes up and left.
@item u
Goes up and right.
@item g
Goes left.
@item j
Goes right.
@item b
Goes down and left.
@item n
Goes down and right.
@item SPC, h
Point.  Either grab or drop.
@end table

To make a move, put the cursor on a piece, and hit @kbd{SPC}.  This
marks it.  Then use movement keys to make it go.  Going to an adjacent
square unmarks and changes turns.  Jumping requires that you hit
@kbd{SPC} a second time to drop it.  Once jumping has commenced, moving
to an adjacent square at the end is illegal.

There is no mouse support yet.

@node Order and Chaos, Ataxx, Chinese Checkers, Playing a Game
@subsection Order and Chaos
@cindex Order and Chaos

Order and Chaos is a weird game someone asked me to write.  The rules
are that ORDER tries to get 5 in a row of either type (X or O pieces)
Chaos tries to prevent him from doing that.  Both players can place a
piece of any type on the board.

Movement is done with the standard emacs movement keys. An @kbd{x}
places and X piece, and an @kbd{o} places and O piece.

Mouse drags will move the selected square.  A click with mouse button 1
will place an X piece, and a click with button 2 will place an O piece.

@node Ataxx, Checkers, Order and Chaos, Playing a Game
@subsection Ataxx
@cindex Ataxx

Ataxx is a game where the winner is the person with the most pieces when
the board is full.  Play is done by moving the cursor, grabbing a
target.  Then move the cursor to a new location, and place it there.

A move to an adjacent piece will make a new piece in that location, and
take all of your opponents pieces neighboring it.

A move 2 away will jump that piece into that location, and grab all
of your opponents pieces adjacent to it.

Movement is done with the standard emacs movement keys.
SPC will grab a piece you own.
SPC will drop that piece after it has been grabbed.

Mouse drags will move the selected square, and a click will GRAB or DROP
a piece somewhere.

@node Checkers, Gess, Ataxx, Playing a Game
@subsection Checkers
@cindex checkers

The rules for checkers:
@enumerate
@item
A piece may move forward any one diagonal square.
@item
A piece may jump forward diagonally and capture over any opponent's piece.
@item
A piece reaching the far side of the board is kinged.
@item
A king may move forwards or backwards to an adjacent diagonal.
@item
A king may jump in any diagonal over an opponent and capture them.
@item
A king may jump over his own men without penalty.
@item
Several jumps are allowed.
@end enumerate

To play, use the arrow keys to select a piece.  Then use @kbd{SPC} to
mark.  Move the cursor to where you want to place the piece and hit
@kbd{SPC} a second time to go there.  To release a piece, and grab a
different piece if you haven't jumped anyone, place the cursor on the
grabbed piece and hit @kbd{SPC}.

Mouse drags move the selected square.  A click will GRAB or MOVE a
checker.

@node Gess, Trax, Checkers, Playing a Game
@subsection Gess, and Gess alternate footprint
@cindex Gess, Gess-alt

Gess is a game similar to chess, but played on a Go board.  For more
information check the Scientific American article on November 1994.
A "piece" is any group of up to 9 stones in a 3x3 block.  Movement is
based on the position of stones.  Pieces on the outer edge of the square
show how movement is allowed.  If the center is filled, then movement is
infinite in any direction.  When empty, movement is limited to up to 3
spaces in any given direction.  On an X display where faces are
available, the viable moves are highlighted for convenience.

The following examples Describe movement.
@example
...   This piece represents a "pawn".  It can move down 3 spaces.
...
.X.

.X.   This piece represents a "Rook".  It can move up, down, left,
XXX   and right as far as it wants.
.X.

X.X   This piece represents a "Bishop". It can move in any diagonal
.X.   as far as it wants.
X.X

XXX   This is your ring, or "King".  It can move in any direction,
X.X   but can only do so up to 3 dots away at a time.
XXX

XXX   This is a tee, or a mutant piece created by pushing the initial
.X.   rook up next to it's pawn.  It is my experience that this is
.X.   a handy configuration.

.XX   This is a mutant piece.  It can move up the 3 spaces up, diagonal
...   up-right, and down.
.X.
@end example

As with chess, you can "capture" the opponants stones.  When moving, you
may move up to your maximum distance which is usually stoped by a wall,
or someones pieces.  You may only overlap the opponant or yourself by 1
series of stones.  If you are moving as a rook, the most stones you may
take are 3.  If moving as a bishop, the most stones you can capture is
5.  You may also capture your own stones, but this is not very useful.

In Gess, you overlap when the "footprint" lands on any other stone.  In
normal Gess this footprint is the entire 3x3 block.  With the alternate
footprint rule, the footprint only consists of stones in the active
piece.

A piece becomes invalid in normal gess when an opponant's stone is
somewhere in your designated 3x3 block.  This is not true with the
alternate footprint version.

The goal is to break your opponants ring (King).  In the course of play,
it is possible to also make a new ring.  Emacs will keep track of your
original ring for speed, and when it is broken, it will look for new
rings to take it's place.

To play, use the arrow keys to move about.  Use @kbd{SPC} to select a 3x3
block.  If you are using X with faces available, the possible places to
move are highlighted.  Move the cursor to a new CENTER for your block.
Press @kbd{SPC} to move your piece.

With a mouse under X, click to select a 3x3 block to be your piece, and
click on a new valid spot to go there.

@node Trax, , Gess, Playing a Game
@subsection Trax
@cindex Trax

Trax is a tile based game, where there are basically 2 types of tiles.

The two tiles are a "Cross" and two "Curves".  When playing real trax,
the tiles have black and white player lines on them.  In emacs, they
look more like this:

@example
+..#..+       +..#..+
:  #  :       : #   :
-------  and  ##  /--
:  #  :       :  /  :
+..#..+       +..|..+
@end example

The goal is to create a "loop" of your color.  The other winning
strategy is to create a line that covers eight or more tiles from two
parallel edges.  The line must cover the maximum extent of the board,
not the eight tile minimum.

A sample game with a win loop in it may look like this:
@example
   1     2     3     4     5

A                         
           .     .     .  
                          
        +..|..+..#..+..#..+
B       :  |  : #   :   # :     
     .  ###|####  /---\  ##  .  
        :  |  :  /  :  \  :     
        +..|..+..|..+..|..+
C       :  /  :  |  :  \  :     
     .  --/  ####|####  \--  .  
        :   # :  |  : #   :     
        +..#..+..|..+..#..+
D       :   # :  |  : #   :     
     .  --\  ####|####  /--  .  
        :  \  :  |  :  /  :     
        +..|..+..|..+..|..+
                          
           .     .     .  
@end example

Here we see the "." tiles which are places where we can place tiles
legally, and there is the big loop of "###" marks.  This loop signifies
a win for player 2.

Player 1 is represented by the "---" lines, and player 2 is represented
by the "####" marks.

To play, use the normal movement keys to put the cursor on a space with
a "." in the center.  Next, press @kbd{SPC} to select a tile to put
there.  Only the center of the tile is drawn.  Continue to press
@kbd{SPC} until the piece you want is under the cursor, then hit
@kbd{RET} to drop it there and switch turns.  A move may place multiple
pieces on the board at once.  These other pieces are called "forced
moves" and are handled by emacs.  Forced moves are usually the winning
factor when playing trax.

There is no mouse support.

@node Installing Games, Writing Games, Playing a Game, Tyrant Mode
@section Installing games
@cindex installing games

If a new game is written, and you wish to install it, it can simply be
placed in the @file{games} directory wherever etalk is installed.  If
you do not have permission to this directory, you may create a
@file{games} directory wherever your local lisp library is, and place it
there.  The games list is built by searching @code{load-path} for all
lisp files in a @file{games} subdirectory.

Whoever you are talking to, however, must also have this game installed
to be able to play against them.

There are many configurable features to the games available.  The
variables you can set to modify behavior are:

@table @code
@item game-lib-use-colors
@vindex game-lib-use-colors
Default is set if you use emacs 19, and have a window system active.  If
you are on a monochrome monitor, you may wish to set this to nil.
@item game-lib-player1-face-color
@vindex game-lib-player1-face-color
Default "red".  This is the color used for player one pieces in all
games which use game-lib.
@item game-lib-player2-face-color
@vindex game-lib-player2-face-color
Default "yellow".  This is the color used for player two pieces in all
games which use game-lib.
@item game-lib-invert-foreground-color
@vindex game-lib-invert-foreground-color
Default "black".  For games which use inverse colors (to improve
visibility of small pieces), this is the foreground placed on top of the
backgrounds which are specified in @code{game-lib-player[1|2]-face-color}. 
@end table

@node Writing Games, ,Installing Games, Tyrant Mode
@chapter Writing Games
@cindex Writing Games

To write a game, there is a basic structure that must be adhered to.
This is, however, easy to do since much of it is handled by the
@file{game-lib.el} routines.

There are several features of tyrant-mode which you may wish to be
familiar with to improve the games you write as well.  As an example, we
will examine the first game I wrote, which is talk-tac-toe, and how it
is constructed, and uses the hooks and features of tyrant-mode with
game-lib.

All tyrant-mode style games can be written and tested without ever
entering etalk until the interaction with tyrant-mode is actually
tested.

@menu
* Initialization ::     How to initialize for using tyrant-mode
* Swapping Turns ::     How to swap turns
* Winning ::            How to declare a winner
* Mouse Control ::      How to use the mouse under tyrant-mode
* Secret Messages ::    Passing secret messages between etalk clients
* Gamelib functions ::  Listing of functions for game-lib and tyrant-mode
@end menu

@node Initialization, Swapping Turns, Writing Games, Writing Games
@section Initialization
@cindex Initializing Tyrant mode (code)

The first thing you must do is determine the name you wish to use.  The
file name, and the name of the entry point of your game-mode must be the
same, and *MUST NOT* end in -ai, or -lib.  (Such as game-lib.el) since
those file names are all filtered out of the games directories when the
list of games is generated.

Next, lets look at some sections from the main entry point of talk-tac-toe:

@example
(defvar ttt-map nil
  "Keymap used in talk-tac-toe.")
(if ttt-map
    ()
  (setq ttt-map (make-sparse-keymap))
  (define-key ttt-map "q" 'ttt-quit)
[ ... ]
  (game-lib-add-mouse-support ttt-map)
  )
@end example

Here we see the creation of the keymap.  The keymap should always be
sparse.  It may make playing singly unpleasant at times, but it will
improve the tyrant's control.

The last function call, @code{game-lib-add-mouse-support}, is a function
which takes the keymap of your choice, and adds mouse support to it.  It
handles problems when dealing with emacs18, and other unpleasantries.
@findex game-lib-add-mouse-support

@example
  (interactive)
  (let ((buff (get-buffer-create "TALK-TAC-TOE")))
    ;; bring buffer forwards
    (switch-to-buffer buff))
  (setq major-mode 'talk-tac-toe)
  (setq mode-name "T-T-T")
  (use-local-map ttt-map)
  ;; toast buffer contents
  (game-lib-clear-buffer)
  ;; insert board into buffer Note: spaces etc have been counted so
  ;; keeping this clean is importnat.
  (game-lib-insert-string 1 "-------------
| 1 | 2 | 3 |
-------------
| 4 | 5 | 6 |
-------------
| 7 | 8 | 9 |
-------------" nil)
@end example

Here we see two important things.
@enumerate
@item
Creation of a buffer, and selecting that buffer as current.  It must be
current when tyrant-mode checks to see what happened, and begins to take
over your game buffer.
@item
Clearing of the buffer with game-lib.  This clears out the buffer,
overlays, and some other nice things.
@item
@findex game-lib-insert-string
Creation of the game board with @code{game-lib-insert-string}.  This
function should be used when inserting strings if you plan on using any
overlays of any sort.  It also makes inserting/overwriting more
convenient, and safer since it takes many things into account.
@end enumerate

Next, some variables are created.

@example
  (make-local-variable 'tyrant-turn)
  (setq tyrant-turn 1)
  ;; tyrant mode mouse support
  (make-local-variable 'tyrant-mouse-function)
  (setq tyrant-mouse-function 'ttt-mouse-support)
  ;; tyrant mode help string
  (make-local-variable 'etalk-tyrant-brief-help)
  (setq etalk-tyrant-brief-help 
	"TalkTacToe: # to move, q to quit, C-c m to send message.")
  (make-local-variable 'etalk-tyrant-quit-string)
  (setq etalk-tyrant-quit-string "")
  ;; ok.. setup hooks dependent on whether you are player1 or player2
  (setq tyrant-player1-hook 
	'(lambda ()
	   (message "You are player 1")))
  (setq tyrant-player2-hook
	'(lambda ()
	   (setq etalk-tyrant-enabled-console nil)
	   (message "Your are player 2"))) ;player2 goes 2nd
)
@end example

Much of this is explained in the comments.  Briefly again, these
variables are mostly control features of tyrant mode.  They are:

@table @code
@item tyrant-turn
This important variable controls whose turn it is.  So long as you use
this, and it's value is always 1, or 2, game lib features discussed
below shall always work efficiently.
@item tyrant-mouse-function
This variable will hold a symbol to your function which can control how
the mouse is handled.  This function's parameters are described later.
@item etalk-tyrant-brief-help
This variable is simply a string printed when the user presses @kbd{C-h}
under tyrant-mode.
@item etalk-tyrant-quit-string
This variable can be either @code{fset} to a function which can generate
message saying who wins, or a generic string declaring the winner.  Here
we see that no extra text will be printed.  If a winner is declared
(see below) then this feature is not used.  If you can declare a winner
half way through the game, then @code{fset} this to a function which returns a
string saying who that player is.  (See DOTS, and REVERSI for examples)
@item tyrant-player1-hook, tyrant-player2-hook
These two hooks are your only entry way into knowing under tyrant-mode
which player you are running as.  Here we simply print out which player
we are running as.  Notice that we set the console to be disabled for
player two.  This is because it is not his turn.  This variable must be
set or both players can mess with the board at the same time.
@end table

@node Swapping Turns, Winning, Initialization, Writing Games
@section Swapping turns
@cindex  Swapping turns in tyrant-mode (code)

Exchanging turns under tyrant-mode is quite simple.  Here is an example
from talk-tac-toe:

@example
(defun ttt-swap-turns ()
  "Go to next person's turn."

  (game-lib-swap-turns "It is now %P's turn." "Player %d's turn"))
@end example

@findex game-lib-swap-turns
This should be all you need.  The function @code{game-lib-swap-turns}
takes two parameters.  The first is used when playing under tyrant-mode.
It should be a string parseable by @code{tyrant-format} @xref{Gamelib functions}

The second parameter will be given one number when formatted, and that
is the player who's turn it will be.

The net result of calling this function is the change the value of
@code{tyrant-turn} to be the next person's turn, and then the set the
tyrant-console to the appropriate player.

@node Winning, Mouse Control, Swapping Turns, Writing Games
@section Winning

To declare a winner, and subsequently exit the game buffer and return to
the talk buffers, the following example from talk-tac-toe is all you
need.

@example
    (if (setq didiwin (ttt-detect-win))
       (game-lib-win tyrant-turn "%P wins!" "Player %d wins!")
      (if (equal ttt-numb-moves 9)
	 (game-lib-win tyrant-turn "No moves left! Stalemate."
			  "No moves left! Stalemate.")))
@end example

@findex game-lib-win
Here we see a check to see who wins, and then a call to
@code{game-lib-win}.  Like @code{game-lib-swap-turns} it takes two
parameters for the string to print.  The first is how to say who wins
based on @code{tyrant-format}, and the second for when played alone.
The first parameter is the winner in question.  This value is used to
determine the name to print.  As you can see, it can also be used to
declare a stalemate.

Another way to determine a winner is by @code{fset}ing the variable
@code{etalk-tyrant-quit-string} to some function.  Doing this will let
you declare a winner in the middle of a game if someone gives up.

Here is an example from @code{word-thing} which can declare a winner
before all the tiles are used up.

@example
(defun word-thing-win-string ()
  "tyrant only function, generates a string declaring someone the winner"
  (save-excursion
    (set-buffer word-thing-command-name)
    (if (> word-thing-player-1-score word-thing-player-2-score)
	(tyrant-format "%n is the winner!")
      (tyrant-format "%N is the winner!"))))
@end example

Here, simply do whatever is necessary to return a string usable by
@code{tyrant-format} to say who won.  Notice that %n, and %N is
different.  @xref{Gamelib functions}

You may also kill the game at any time.  Here is an example of a
specific quit function from talk-tac-toe:

@example
(defun ttt-quit ()
  "Quit talk-tac-toe nicely"
  (interactive)
  (game-lib-quit t))
@end example

Here, @code{game-lib-quit} is called with "t".  The t is in the "kill"
field which simple tells game-lib to kill the talk buffer when it is
done with it, which minimized cleanup later on.

@node Mouse Control, Secret Messages, Winning, Writing Games
@section Mouse Control
@cindex tyrant mouse control

Using the mouse under tyrant-mode has been simplified through the use of
the key-binding @code{game-lib-add-mouse-support} @xref{Initialization}.

The function assigned to the variable @code{tyrant-mouse-function} can
be anything devised for use by your game program.  Once installed, this
feature is usable during solo play, and against an opponent in tyrant
mode.

Here is a sample from talk-tac-toe:

@example
(defun ttt-mouse-support (p e m)
  "Reads in a mouse event from the game-lib driver, and allows a
player to click on a square."

  ;; find which square we are closest to and go there
  (if (and (not (memq 'drag m)) (integerp p))
      (let ((first-line 0)
	    (line-width 14)
	    (block-width 3)
	    (block-height 1)
	    (block-vsep 1)			;vertical separator width
	    (block-hsep 1)			;horizontal sep width
	    x y xt yt
	    )
	(setq yt (/ (- p (* first-line line-width)) line-width))
	(setq xt (- (% p line-width) 1))
	(setq y (/ yt (+ block-height block-vsep)))
	(setq x (/ xt (+ block-width block-hsep)))

	(message "Clicked on %d %d" x y)
	
	(if (not (or (< (% xt (+ block-width block-hsep)) block-hsep)
		     (< (% yt (+ block-height block-vsep))
			block-vsep)))
	    (if (memq 'click m)
		(let ((last-input-char (+ (* y 3) x 1 ?0)))
		  (ttt-move)))))
    )
  )
@end example

The function takes 3 parameters, @code{p}, @code{e} and @code{m}.  The
variable @code{p} is the position character in the buffer where the
mouse was clicked.  (Same value as if (point) were called).  This can be
used to determine where the user clicked.  The variable @code{e}
contains the event as returned by the function @code{event-basic-type},
and the variable @code{m} contains the list returned by
@code{event-modifiers}.  These contents are converted to text and sent
over a talk session when in tyrant-mode.

in the above example, we see a simple bit of math to calculate what
virtual square we clicked in.  I've used this basic formula in almost
all of my games.  The 'click feature is used in my games to perform some
sort of 'selection', and drags will just position the cursor.

@node Secret Messages, Gamelib functions, Mouse Control, Writing Games
@section Secret Messages

In some situations, not all information is known.  Classic examples to
this are card games, and things like word-thing.  In these instances,
there must be ONLY ONE of the two etalk clients which keep track of
lists, hands, and information like that.

To handle this, you must set up a message handler, and declare player1
as the main bookkeeper.  Here is a sample from hangman:

@example
  (setq tyrant-player1-hook
	'(lambda ()
	   (while (> (length hangman-to-guess-string) 30)
	     (setq hangman-to-guess-string 
		   (read-string "Enter the word for remote to guess: "))
	     (message "Interpolating [%s]..." hangman-to-guess-string) )
	   (make-local-variable 'etalk-tyrant-brief-help)
	   (setq etalk-tyrant-brief-help
     "Hangman : C-c m to send a minibuffer message, otherwise just watch.")
	   (setq etalk-tyrant-enabled-console nil) ;player 1 don't
					;guess.
	   (hang-make-hangman-guess-string hangman-to-guess-string)
	   (goto-char 220)		;where the message should
					;start
	   (kill-line)
	   (let ((game-lib-replace nil))
	     (game-lib-insert-string (point)
				     (concat "    " hangman-guess-string)
				     nil))
	   (goto-char (point-max))
	   (insert "String to guess: " hangman-to-guess-string "\nGuessed chars: ")))

  (setq tyrant-player2-hook
	'(lambda ()
	   (setq etalk-tyrant-enabled-console nil)
	   (setq tyrant-call-interpreter 'hang-do-message)
	   (make-local-variable 'etalk-tyrant-brief-help)
	   (setq etalk-tyrant-brief-help
     "Hangman : Press any lower case letter to guess. C-c m to send message.")
	   ))
@end example

Here, under the player1 hook, the person who initiates get to choose the
word to guess under hangman.  The function
@code{hangman-make-hangman-guess-string} converts the typed string, and
sends the message to the other user.
@refill

Under the player2 hook, we see more stuff about messaging in the setting
of @code{tyrant-call-interpreter} to the function
@code{hang-do-message}.  
@refill
@findex tyrant-call-interpreter

Now, to actually send a string somewhere, simply use the function
@code{tyrant-send-message} which only takes one string.  That string is
then modified and sent over the the other etalk client.
@findex tyrant-send-message

The function assigned to @code{tyrant-call-interpreter} takes only one
parameter, and that is the string received from the remote.  What you do
with these strings is up to you.  In hangman, the string is the text
printed after the hangman diagram in which the text for the letters is
guessed.  In word thing, the letters in a given hand are simple sent
over as a string.  In the @file{card-lib.el} library, there is a cards
function designed to convert a stack of cards into a string, and parse
it back again.

@node Gamelib functions, ,Secret Messages ,Writing Games
@section Game library functions
@cindex game-lib
@cindex etalk-tyrant

The variables which allow you to control features of tyrant-mode are:

@table @code
@item etalk-tyrant-enabled-console
Default value: nil . Variable for minor-mode alist, defining when the
tyrant console is enabled.  This provides default value.
@item tyrant-player1-hook
Default value: nil. Hook used when starting up player 1's player space.
This should only be set by games who believe that they will be used
under tyrant mode.
@item tyrant-player2-hook
Default value: nil. Hook used when starting up player 2's player space.
This should only be set by games who believe that they will be used
under tyrant mode.
@item tyrant-mouse-function
Default value: nil. Function used to evaluate mouse actions locally in a
buffer.
@item tyrant-call-interpreter
Default value: nil. Function which can be set to evaluate message type 1
(game data).  Allows games to play as master/slave where initiator knows
some piece of global/random data like cards of word-thing pieces.
@item etalk-tyrant-enabled-console
Default value: nil. For games with TURNS, this flag is set by game to
control playing.  When this is NIL, key presses are not interpretted,
otherwise play can proceede as normal.
@item etalk-tyrant-brief-help
Default value: nil. C-h will print a tyrant help string unless this is
set in the game, then it prints a brief help message based on the game
rules.
@item etalk-tyrant-quit-string
Default value: nil. When a program is quit, and this has a value, then
print something like 'Eric wins!' before the hit return message.
@item tyrant-not-turn-message
Default value: nil. If set locally, the specified string is used instead
of 'it's not your turn' as per tyrant mode default.
@item tyrant-player-index
Default value: nil. Flag indicating who you are (player 1 means
initiator, player 2 means you agreed to a game request
@item tyrant-turn
Default value: nil. Contains local version of who's turn it is during a
tyrant controlled game.  This allows tyrant-format to easily pring
strings based on turn so the game need not figure it out.
@item tyrant-dont-restore-position
Default value: nil. Set locally inside tyrant key press to allow games
to hook upward in removing where the cursor should be.
@end table

A function to be familiar with is @code{tyrant-format}.  This function
will format a string with special tokens via the sformat driver.  The
tokens allowed are:
@table @asis
@item %u
player one's username.
@item %U
player two's username.
@item %n
player one's preferred name.
@item %N
player two's preferred name.
@item %p
choose player based on local variable tyrant-turn.
@item %P
choose player based on local variable tyrant-turn and use pref name
@end table

The username is that persons login name, and a preferred name is that
found with the finger information.

The rest of the tyrant-mode features are used to invisibly simulate the
normal functioning of you game over a network.

game-lib control variables which you may use are:

@table @code
@item game-lib-replace
Default value: t. In most cases, we wish to replace characters for
games, rarely, we need a little hook in so we may insert (end of lines,
etc)
@item game-lib-use-colors
Default value: (Depends on your system). Set this to nil if you never
wish to use colors, otherwise, always use colors when you have windows
@item game-lib-player1-face-color
Color of player 2s face in window environ.
@item game-lib-player2-face-color
Color of player 2s face in window environ.
@end table

Some functions which are handy to use are:

@table @code
@item game-lib-add-mouse-support
Parameters: keymap. Adds mouse support to a game.  It puts a call to
game-lib-handle-mouse into KEYMAP entries for FUNCTION which will be
used to handle the mouse events.  This must be done this way so
mouse-related actions can be sent over the network.  The event [mouse]
can't be transferred as a character.

  FUNCTION should receive the list (p e m) where P is the position in
the buffer, and e is the event type (mouse-1, mouse-2, mouse-movement)
and m is a list of modifiers (down, click, drag, etc) Your average game
will probably skip many of these types.
@item game-lib-clear-buffer
Parameters: (&optional buffer). Take the current buffer and delete
everything in it.  This also will delete any overlays existing in the
buffer.
@item game-lib-insert-string
Parameters: (pnt string color). Take STRING and place into buffer at
PNT, replaceing what was there, and making sure that face color is COLOR
(being a symbol containing a face)  If the variable
@code{game-lib-replace} is non-nil, then also replace what was under the
text, up to the first new-line.
@item game-lib-win
Parameters: (who etalk-message solo-message). Declare WHO winner
handling tyrant problems.  If tyranted, use the ETALK-MESSAGE,
otherwise, use SOLO-MESSAGE, where the etalk message contains
tyrant-format controls, and solo-message may contain one %d which will
be filled in by WHO.  Just before printing the message, tyrant-turn is
set to WHO, thus allowing use of %P etc in tyrant messages even when it
isn't tyrant-turn's turn.
@item game-lib-swap-turns
Parameters: (etalk-message solo-message). Swap turns handling tyrant
problems.  If tyranted, use the ETALK-MESSAGE, otherwise use
SOLO-MESSAGE, where the etalk messasge contains tyrant-format controls,
and solo-message may contain one %d which will be give the current turn
number.
@item game-lib-quit
Parameters: (kill). Covers over icky tyrant mode stuff needed to quit a
game.  If KILL, then kill the buffer when done.
@end table

@node  Log Buffer, Finger Mode, Tyrant Mode, Top
@chapter Log Buffer
@cindex log buffer

The buffer @samp{*ETALK LOG*} is the buffer the etalk server subprocess
is linked to.  All output from this program, unless specifically
requested, is logged here.  Any bugs relating to interfacing with the
etalk process are best when accompanied by a copy of the log which may
describe what emacs and the etalk process know as true.  If possible, a
@samp{DEVICE} or @samp{USER} list may also prove useful.

To get an obscene amount of information out of etalk, simply define
@samp{DEBUG_2} to add lots of extra print statements into the device
read loop, and rc file reading.

Any key pressed in this buffer will bring up the minibuffer prompt
@samp{Command:}. The other keys are:
@table @kbd
@item RET
rebuild the windows for the users you are currently talking to.
@item C-c C-c
The emergency destroy key, which will delete the etalk process.
@end table

Available commands to send the etalk binary are:
@table @samp
@item ABORT
If there is a call currently active, this will abort that call, and
perform the clean up necessary to allow a new outgoing call.
@item ANNOUNCE user[@@machine][ tty]
Send a talk announcement to the specified user.  They will not be able
to connect to you.  The response message is printed in the log.
@item CALL UID user[@@machine][ tty]
Go through the talk protocol to attach to user.  UID is a user ID which
is received by creating a TCP connection to the etalk process through
the local port.
@item CLEAN
Go through all devices, and user structures, and remove all structures
labeled as DEAD.
@item CONNECT UID socket user[@@machine][ tty]
If the socket of another talk process is available, we can use this
command to simply connect there directly.
@item DELETE announce|invite [host]
Send a DELETE command to host, and print the response message.
@item ECHO
This command simply echoes whatever you type right back.  Useful if you
are unsure etalk is responding to typed commands.
@item HANGUP UID
This command will hang up on the user specified by UID, where UID is
received when a TCP connection is made to the local port.
@item HELP
Print out help for each command.
@item LEAVE user[@@machine][ tty]
This command will leave an invite for user on your machine.  The
response message is printed out.
@item LOOKUP user[@@machine][ tty]
This command will request a lookup response to see if you are invited by
user.  The response message is printed out.
@item TEST [VERBOSE]
Execute a test for the current system.  This is usually used during
building to aid in configuration and make sure nothing is installed
unless the binary works.  Typing this command will automagically test
the system for BSD 4.3 talk unless your system is in a @file{hosts.talk}
entry as OTALKD or something else.  The option VERBOSE flag turns
verbosity on just before the test, and also prints the runtime status.
The test is described more elsewhere.
@item QUERY
This test command sends a QUERY message to the GNU talk daemon, which
asks for whoever may be calling you at the moment.  Used for testing
purposes.
@item QUIT
This closes all ports and exits the etalk process.
@item READ [FILE]
Reads the FILE parameter, or re-read the files @file{/etc/hosts.talk}
and @file{~/.hosts.talk} for any new hosts, or changed information.
Allows a VERBOSE setting during a read if there are problems.
@item REPLY UID
Attaches the given UID to whoever happens to be ringing you at this
time.  The protocol asks for whoever is calling, and this command
reports back the name and machine of the person to connect to.
@item SET [OPTIONS]
This command lets you SET some feature or variable.  See the table of
SET options after this table.
@item SHOW [OPTION]
This command will print out information relating to the OPTION
parameter.  The information provided could be an internal list, or the
value of some variable.
@item WAIT UID user[@@machine][ tty]
If we have a method to communicate with another emacs talk process,
(such as @code{etalk-mail}) then we may not wish to use the TALK
protocol.  In this case, wait will simply hang out and wait for another
process to connect to it via this user id.
@end table

The command @samp{SET} can be used with the following optionas of
sub-commands.
@table @asis
@item APPLICATION [name]
This option lets you dynamically change the name of the application.  It
defaults to nothing.  If the remote user you are talking to has gtalkd
isntalled, then this name will be displayed when the deamon prints a
message, such as: respond with "booger zappo@@choochoo.ultranet.com"
instead of: respond with "talk zappo@@choochoo.ultranet.com"
@item CLIENT UID DEFAULT|ETALK|YTALK
Set the type of of client UID is using to the default, or etalk.  Ytalk
is provided for the future when I understand how to determine that
someone is using it.
@item EDITCHAR 123
This changes the active edit characters used in the etalk process.
Sequences such as @samp{^H} will parsed to ASCII(8).  The order is
1 DELETE-CHAR, 2 DELETE-LINE, 3 DELETE-WORD.
@item HELP
Print out help for each command.
@item NAME
Set the name you wish to use.  This name is what is printed in the etalk
request message.
@item RINGER ON|OFF
This command will set the ringer on or off.  This creates the .ringer
file read by the GNU talk daemon which allows it to connect to you.
@item VERBOSE [Verbosity level]
Toggles the verbosity of the program.  This includes the printing of
statuses of all daemon related messages, plus other useful stuff.  An
optional parameter will set the value of the verbosity flag to the
desired level.
@end table

This table shows all the options available when using the @samp{SHOW} command.
@table @asis
@item COPYRIGHT
This will display the copyright information for etalk.  It's the typical
message found at the beginning of GNU source code.
@item DEVICE
This command will print a formatted list of all devices created within
the context of this talk process.  It will contain TCP and UDP sockets
active or closed to remote and local machines.
@item HELP
Print out help for each command.
@item HOSTS
This prints a list of all hosts read into the program, and their known
statistics, including if they were read from a local, or system RC file,
or added at run time.
@item STATUS
Print out the compile status, and all run time statuses that might prove
interesting.
@item USERS
This prints a formatted list of all user structures created which have
not been cleaned.
@item VERSION
Display the current running version of ETALK.  It is the same string
printed when etalk starts.
@end table


The @samp{SHOW} commands @samp{DEVICE}, @samp{HOSTS} and @samp{USER} are
useful when debugging, and interesting to view statistically.  The
commands @samp{ANNOUNCE}, @samp{DELETE}, @samp{LEAVE}, @samp{LOOKUP},
and @samp{QUERY} are academically for testing functions for the TALK
protocol, but can prove useful when debugging talk servers and the like.
The @samp{ECHO} command is purely debugging, and is handy when you just
want to verify that the process is alive.

The @samp{TEST} command is for the @samp{check:} rule in the
@file{Makefile} to provide configuration aid.  It can also be accessed
from the command line via: @samp{etalk -t}

@node Finger Mode, Hooks and Variables, Log Buffer, Top
@chapter Finger mode
@cindex finger-mode
@findex finger

@dfn{finger} is a networking command which allows a user to access
log-on information on different machines via TCP.  The result is a list
of users, their TTYs, idle time, and other truly nifty bits of
information.

The @code{finger} emacs command queries the user for a node name, then
runs finger on that node.  There is minor completion allowed on this
command line based on rules described in the etalk minibuffer commands
section.  @xref{etalk completion}

Once loaded, all extraneous information is nuked from the top.
(Welcomes, disk utilization, errors and the like) The header is then
parsed to determine how the columns line up dependant on that systems
architecture.

The keystrokes to manuver in the finger buffer are:

@table @kbd
@item n, C-n, SPC
Move forward one line in the finger buffer.
@item p, C-p, DEL
Move  backward one line in the finger buffer.
@item f
Call finger on the username specified on the current line.  This returns
more information such as selected shell, mail, and all sorts of other
goodies.
@item g
Get new finger buffer.  Basically, get any updates.
@item m
Send mail to the user on the current line.  Initializes the mail buffer
with that individuals user name. (See Mail under emacs info file)
@item q, x
Quit finger mode, and delete the buffer.
@item t
Talk to user on the current line (No wonder this is documented under
etalk.)  Initializes the prompt to the user on the current line.
@xref{etalk}
@end table

@node  Hooks and Variables, Configuration Files, Finger Mode, Top
@appendix Customization
@cindex customization

Some general configuration hooks are:

@table @code
@item etalk-hooks
Default @code{nil}.  This hook is run after the windows are setup from
initiating a new talk connection.
@item etalk-mode-local-hooks
Default turns on @code{auto-fill}. This hook is called after
initialization of the local talk buffer.
@item etalk-mode-remote-hooks
Default @code{nil}.  This is run after a remote buffer is created.
@item etalk-mode-hooks
This is run after any etalk buffer is created.
@item etalk-log-mode-hooks
Default @code{nil}.  This is run after the etalk log buffer is created.
The etalk log buffer does not count as an etalk-buffer.
@item etalk-mail-hooks
Default @code{nil}.  Run this after an etalk mail function has been called.
@end table

Some generic customization variables are:

@table @code
@item etalk-hangup-redo-windows
Default @code{t}. Non-nil means that when a connection closes, to redo
windows to exclude it from the screen.  This has the side affect of
mangling any other window geometry that may have been setup.
@item etalk-process-file
Default @samp{"etalk"}. If etalk is not on your path, then it is
necessary to set this to it's true file name.
@item etalk-process-parameters 
Default @samp{nil}. This contains a list of strings to use as arguments
to the etalk program when it is started. eg: '("-v")
@item etalk-log-buffer-name
Default @samp{"*ETALK LOG*"}.  This string represents the buffer name of
the talk log buffer within which etalk logs all process transactions.
@item etalk-local-buffer-name
Default @samp{"%P"}. The name given to a local talk buffer.  Follows
rules for etalk-format.
@item etalk-remote-buffer-name
Default @samp{"%u@@%:1m %t"}. The name given to a local talk buffer.
Follows rules for etalk-format.
@item etalk-remote-display-preferred-name
Default @samp{"@{%:2p@}"}. Non-nil, display the remote's preferred name in
the minibuffer after connection.  This string is simply appended to
etalk-remote-buffer-name, and follows the rules for etalk-format.
@item etalk-inhibit-startup-message
Default @samp{nil}. If non-nil, don't print startup message about
etalk.
@item etalk-goofy-message-delay
Default @samp{5}. Initial length of time between goofy messages. 0 means
turn off.  Goofy messages have not been re-implemented under the new
etalk binary.
@item etalk-buffer-logging-directory
Default @samp{nil}. Where conversations are logged.  Nil is no logging,
NAME logs files in this directory where the file name = username.
@item etalk-clear-buffer-on-call
Default @samp{nil}. Clear buffers if non-nil for remote.
@item etalk-announce-as
Default @samp{(user-login-name)}. This string contains a name passed to
the remote talk daemon as your username.  Changing this means you
announce yourself with a different name.  Most sysadmins would probably
be upset if you did this to unknowing users.
@item etalk-preferred-name
Default @samp{(user-full-name)}. The user name you wish to use as your
preferred name.
@item etalk-C-x4t-to-global-map
Default @samp{t}. Should i add etalk-setup-windows to the keystroke
C-x4t???
@item etalk-log-all-minibuffer-messages
Default @samp{t}. Dictate whether message from tcp processes are logged
in the log buffer.
@item etalk-edit-characters-mine
Default @samp{"^?^K^W"}. This string represents the characters used when
sending edit characters to remote system.  This variable must be changed
if you wish to change key bindings.
@end table

Some etalk process control variables are:

@table @code
@item etalk-process-string-internal
Default @samp{"etalk-process"}. String used to identify the single
running version of etalk.
@item etalk-local-host
Default @samp{(system-name)}.  This variable identifies your local
machine.  Used when opening sockets to the etalk process.  Beware
because some systems are finicky about using names vs numbers.
@item etalk-tcp-string-internal
Default @samp{"talk-tcp-%u-%M-%T"}. String used to identify multiple TCP
connections to the talk binary.  It follows the rules of etalk-format.
@end table

Some minibuffer completion variables are:

@table @code
@item etalk-finger-backup-command
Default @samp{"finger %s"}. Command used to do a finger if the regular
finger command doesn't work.
@item etalk-idle-pester-limit
Default @samp{10}. The upper time limit reached before talk asks if you
really want to talk to someone because they have been idle for so
long. (In minutes)
@item etalk-host-file-size-limit
Default @samp{10000}. Maximum size of file /etc/hosts.talk before the question
is asked to really read from it.  Setting this to NIL never reads it.
@item etalk-morehosts-file
Default @samp{"~/.hosts.talk"}. File containing more remote nodes for
talk completion.  Doubles as a table of daemon types for the etalk
binary.
@end table

Some variables controlling aspects of editing are:

@table @code
@item etalk-nice-fill-offset
Default @samp{5}. Any SPC after (fill-column - etalk-nice-fill-offset)
inserts a CR automatically.
@item etalk-hard-fill-offset
Default @samp{5}. Any char after (fill-column + etalk-hard-fill-offset)
column will fill that line down right away.
@item etalk-insert-pester-limit
Default @samp{1000 }. Limit at which talk pesters you about inserting
_THAT MUCH_ across the network during any of the insert-file commands.
@end table

And finally, some tyrant mode/emacs 18 specific variables are:

@table @code
@item etalk-tyrant-vt100-enable
Default @samp{t}. Should the vt100 style arrow keys be remapped to emacs
control directionals within tyrant mode?
@item game-lib-use-colors
Default is set based on existence of window-system, emacs19, and
font-lock feature being available.  Set this to nil to never use colors,
or to t to force loading of font lock.
@item game-lib-player1-face-color
Default is a list defined by font-lock-make-face.  The color used for
player one in most games.  Its value is set based on the existence of a
light or dark background.
@item game-lib-player2-face-color
Default is a list defined by font-lock-make-face.  The color used for
player one in most games.  Its value is set based on the existence of a
light or dark background.
@end table

For the cards lib, and checkers, these colors were not enough, and they
defined thier own extended colors.  (See sources)

The following faces are defined in game lib and are settable via your
Xdefaults.

@table @code
@item game-lib-player1-face
Player 1's face.
@item game-lib-player2-face
Player 2's face.
@item game-lib-player1-face-R
Reversed of player1 face.
@item game-lib-player2-face-R
Reversed of player2 face.
@item checkers-player1-face
Player 1's face in checkers.
@item checkers-player2-face
Player 2's face in checkers
@item checkers-black-face
Black squares in checkers
@item cards-backing
Face used on the backs of cards
@item cards-reds
Face used for the front of red cards
@item cards-blacks
Face used for the front of black cards
@item gess-select-face
Selected region in gess
@item gess-go-face
Valid move squares in gess
@end table

For those variables which follow @code{etalk-format}, the format
parameters are as follows:

@table @code
@item %u
Remote's username. *
@item %m
Remote's machine name. *
@item %M
Remote's machine name up to first '.'
@item %t
Remote's tty |
@item %T
Remote's tty without the TTY prefix. |
@item %p
Remote's preferred name. *
@item %P
Your preferred name. *
@end table

Where a @samp{*} represents that it takes integer arguments.  When @code{c} is
the format character, and #1 and #2 are two numbers, the form

@example
%#1c    or
%:#2c   or
%#1:#2c
@end example

Means to take the string represented by c, and make sure it has a
maximum of #1 characters, and a maximum of #2 words.  When both are
specified, then fill out the string with pad characters.

The symbol @samp{|} indicates that the word argument #2 being > 0 adds a
conditional preceding space, thus

@example
%:1t
@end example

@noindent
will print " tty01" if the tty is "01", and will print nothing if it
does not exist.  Lack of the word argument means no space will be added.

@node Configuration Files, Programmer Goodies, Hooks and Variables, Top
@chapter Configuration Files
@cindex configuration files

There are two configuration files used by etalk, both have the same
format.  They are @file{/etc/hosts.talk} and @file{~/.hosts.talk}.  Both
files are much like the file @file{/etc/hosts} with the exception of the
number of fields.  Each line starting with a @kbd{#} symbol is a
comment, and blank lines are ignored.  The columns are:

@enumerate
@item
IP address.  This is technically unnecessary, but it may someday be used
for something more useful. (Like machine which can't parse names)
Currently it is for compatibility with the format in @file{/etc/hosts}
@item
Host name.  This is the verbose machine name, such as "choochoo.ultranet.com"
which is used for minibuffer completion and for etalk daemon type
matching.  It must be the complete name as would be returned by the C
function "gethostbyname".
@item
Daemon type.  This field is used by the etalk binary to determine what
talk version to use while contacting this machine.
@end enumerate

These files are useful on the system and local level to aid in making
etalk faster.  The files are used in completion, which makes everyone
happy, as well as in the etalk binary.

If your system has a combination of suns and other ntalk compatible
machines, you can enter the nodes you contact most and list what daemon
type each has.  This way etalk need not waste it's time trying to
different talk protocols before finding the correct one.

Valid prototype strings are @dfn{OTALKD}, @dfn{NTALKD}, @dfn{GTALKD}
where OTALKD is typically used by suns, NTALKD is the most recent BSD
standard, and GTALKD does not exist yet.

@node Programmer Goodies, Index, Configuration Files, Top
@appendix Goodies for other Programmers
@cindex reusable extensions

There are several files used under emacs talk which could be used to
extend other programs under emacs.  They are:

@file{etalk-mini.el}

This file has been redone to be completely self contained from etalk but
is, however, dependant on sformat (described next.)  It provides the read
commands @code{etalk-read-username}, and @code{etalk-read-host}.  They
allow completion on usernames, and hostnames respectivly.  The only
unfortunate part is the configuration files for the machine name
completion is based on talk data.  Otherwise, a lot of work has gone into
making this package able to read from a large number of different finger
sources, including VMS.

@file{sformat.el}

This file contains a souped up formatter.  Its goal is to allow user
definable strings with the popular c-syntax arguments.  The goal is to
provide the same type of configurability as the emacs mode line
formatting with greater ease, and tons o' options.  (What else to be
expected from an emacs program, but tons o' options?)

More documentation is available from the function's doc string.

@file{games/game-lib.el}

This file is more specific to tyrant mode games.  It provides a simple
way for games to provide nifty colors, and tyrant mode support with
minimal effort.

@file{etalk-x.el}, @code{etalk-x-list-2-menu}

This single function I have found handy in other situations when I wish
to select an object from any list easilly.  It does some neat things,
but was not placed in it's own file because it is so short.

@node  Index, , Programmer Goodies, Top
@unnumbered Concept Index
@printindex cp

@bye
