xmj, mj-server, mj-player - programs for playing Mah-Jong
xmj [--id idnumber]
[--show-wall | --no-show-wall]
[--animate | --no-animate]
[--dialogs-popup | --dialogs-below | --dialogs-central]
[--use-system-gtkrc | --no-use-system-gtkrc]
mj-server [--server address] [--timeout seconds]
[--random-seats | --id-order-seats]
mj-player [--id idnumber] [--name playername]
[--server address] [--password password]
A set of three programs to play Mah-Jong on Unix systems, against
people or programs, over the Internet.
is the program that handles communications and control of the
game; the rules and scoring are enforced there. Players, human
or computer, connect to a server via the network.
is a computer player. At present, it is fairly simplistic,
having only offensive tactics with no knowledge of defensive
xmj is the X client for human players.
If you don’t want to read this long document: to start a game against
three computer players, start xmj, select "New local game..." from the
"Game" menu, and click "Start Game". (Wait about ten seconds for
everything to start up.)
specifies the network address to listen on (for mj-server) or to
connect to (for mj-player and xmj). If address contains a
colon, it specifies an Internet socket, and should have the form
host:port . If address does not contain a colon, it is
interpreted as a Unix file name and a Unix socket is used. The
default value for address is localhost:5000 . address can also
be set in a dialog box in xmj.
xmj and mj-player
The server assigns a unique integer ID (which is currently just
1 to 4 in order of connection) to each player. This ID should be
quoted when reconnecting to a game in progress (after, for
example, losing a network connection or accidentally killing
xmj). The default ID is 0, which denotes no pre-assigned ID.
Players can give themselves names which will be used by client
programs. This option specifies the name. For xmj, the default
is the value of the environment variable LOGNAME, or failing
that the username of the logged in user. For mj-player, the
default is "Robot(PID)" where PID is the process id.
By default, xmj does not automatically connect to a server, but
waits for the user to connect via a menu. If this option is
specified, xmj immediately connects.
Tells xmj (not) to display the wall. By default, the wall is
shown only if running on a big enough screen. This option is
also controllable via the Display Options preference panel.
This option adjusts the size of the main window. It should be
thought of as the length of a tile rack, measured in tiles. The
default, and the largest value accepted, is 19, or 18 if on an
800x600 display. The smallest usable value is 14. This option is
also controllable via the Display Options preference panel.
If the --show-wall option is given, a --size smaller than 19
will have no effect.
This option switches on (off) some animation. Not all tile
movements are animated: only those that involve moving tiles to
or from a hand from outside. This option is also controllable
via the Display Options preference panel.
xmj needs pixmaps to display the tiles and the tong box. This
option tells it which directory to find them in. The default is
set at compilation time; the default default is to use the
This gives a colon-separated (or semicolon-separated under
Microsoft Windows) list of directories in which to look for the
directory named by the --tileset option.
By default, most of the dialog boxes for player actions are part
of the main window. If this option is used, they will instead
appear as separate transient windows.
By default, dialog boxes appear in the centre of the table. If
this option is given, dialogs (apart from some popups) are
positioned below the table area. Please let me know which style
The default: dialog boxes appear in the middle of the table.
These options are also controllable via the Display Options
If xmj is compiled with GTK+2, this option specifies a GTK rc
file to be used instead of the program’s compiled-in style file.
This may be used to change the appearance of the program. See
description under the Display Options... panel for more details.
The file should be an absolute filename; if it is relative, it
will be sought in the current directory (Unix) or the program
directory (Windows). This option is also controllable via the
Display Options preference panel.
When xmj is compiled with GTK+2, by default it ignores the
system provided settings, to ensure a consistent behaviour
across systems. If you wish it to use your system settings, set
this option. This option is also controllable via the Display
Options preference panel.
If this option is given, xmj will echo to stdout all the
protocol messages received from the server. This option is for
use in debugging.
If this option is given, xmj will send any text given on stdin
to the server. This option is for use in debugging.
If this option is given, xmj will send requests to the server
only in direct response to user actions; it will take no action
itself (and hence all auto-declaring and playing is also
disabled). This option is for use in debugging.
When a discard is made, there is a limit on the time players
have to claim it. This option sets the timeout; a value of zero
disables it. The default is 15 seconds.
This value can also be set via a GameOption request from a
This will make the server enforce a delay of deciseconds/10
seconds between each action in the game; the purpose is to slow
programmed players down to human speed (or, in a teaching
situation, to slow the game even more). The current server
considers that 50 (i.e. 5 seconds) is the maximum reasonable
value for this option. The option can also be requested by
players, via a PlayerOption protocol request.
By default, players are seated in order of connection to the
server. This option seats them randomly. It will become the
This option causes the players to be seated in numerical order
of their ids. It is used by the xmj program to make the New
local game.. work as expected.
This specifies the penalties applied by the following option for
players who disconnect before the end of a game. N1 is the
penalty for disconnecting in the middle of a hand; N2 at the end
of a hand but in the middle of a round; N3 at the end of a round
(other than end of game). They all default to 0 if not
If this option is given, a disconnection by one player will
gracefully terminate the game. Mid-hand, the hand is declared a
wash-out; after Mah-Jong has been declared, then if a losing
player disconnects, their tiles are shown, the hand is scored,
and then the game ends; if a winning player disconnects, the
hand is a wash-out. The disconnecting player may be assigned a
penalty, according to the --disconnect-penalties option, which
will be included in the scores printed out by the server. (The
penalties will not be visible to the other players.)
If this option is given, the server will quit if any player
disconnects, rather than waiting indefinitely for reconnection.
If this option is given, the server will save the state of the
game if it quits as a result of a player disconnecting. (It will
not save the state if it quits as the result of an internal
This names a file of protocol commands which will be applied to
every game when it starts. Its main purpose is to set non-
default game options, via the GameOption protocol message (note
that this is a CMsg, not a PMsg). However, users will normally
set options and preferences via the xmj control panel, not by
This names a file containing a saved game (as a suitable
sequence of protocol commands). The server will load the game;
clients connecting will be treated as if they had disconnected
and rejoined the game.
In the most common case of resuming a saved game, namely one
human playing against three robots, the robots will not have the
same names or ids as the robots in the original game. This
option tells the server that if it cannot match a reconnecting
player by id or name, it should anyway match it to one of the
previously disconnected players. (In this case, the human
normally connects first with the same name, so is correctly
Usually, the first player to connect becomes the game manager,
and can change all the game settings. If this option is given,
no player will be allowed to change the game settings.
This provides basic (insecure, since the password is transmitted
in plaintext) authorization: the player with id id must give the
specified password to connect. Note that if this argument is
given, it must be given four times, once for each authorized
player - any player id not mentioned will not be allowed to
connect. A player may be allowed to connect without a password
by making password empty.
This enables various debugging features. In particular, it
enables protocol commands that allow one to change the tiles in
The server will write a complete record of the game to file;
this will be quite large, and is only useful for automatic
comparison of different computer players.
This option suppresses the scoring of points and doubles for
flowers and seasons. It is primarily intended for running tests
of different players; for human use, a game option will be
provided to eliminate the specials altogether.
This option specifies the seed for the random number functions.
Used for repeatable tests.
This names a file containing space separated tile codes giving
the wall; used for repeatable tests. (This is a testing option;
it is not robust.)
This is an option to facilitate certain automatic analyses; if
set, a history of each hand is dumped to the file hand-NN.mjs .
Another option only used in automatic comparison: this saves
some CPU time by disabling the book-keeping required to allow
players to disconnect and reconnect.
sets the password if basic authorization is in use.
The player has some options which can be used to change its
"personality". The meanings are rather approximate, since they
actually change parameters which are used in a rather complex
way, but the idea is right. These options, each of which takes a
floating point value in the given range, are:
--chowness -1.0 .. 1.0
This affects how much the player likes chows: at 1.0, it will go
all out for the chicken hand, at -1.0 it will never chow. The
default is 0.0.
--hiddenness 0.0 .. 1.0
Increasing this makes the player reluctant to make exposed sets.
At 1.0, it will never claim (except possibly to go mah-jong).
The default is 0.0.
--majorness 0.0 .. 1.0
Increasing this biases the player towards collecting major
tiles. At 1.0, it will discard all minor tiles, if possible. The
default is 0.0.
--suitness 0.0 .. 1.0
Increasing this makes the player try to go for one-suit hands.
The default is 0.0
In practice, the --majorness option seems not to be very useful, but
the other options change the personality without completely destroying
the playing ability.
In fact, all these options take a comma-separated list of values, which
allows the specifications of a set of strategies, which the player will
switch between. In this case, the --hysteresis hhh option specifies how
much better a strategy should be to switch to it. However, use of this
option, and multiple strategies, is probably only useful if you first
read the code to see how it works.
USING THE XMJ PROGRAM
The main window contains a menu-bar and a table area; the table is in a
tasteful shade of dark green. The table displays a stylized version of
the game: stylized in that there is no jazzy graphics or perspective,
and the tiles are not intended to be pictures of real objects, and so
on. Otherwise, the layout is as one would expect of a real game.
However, the wall may or may not be displayed, depending on option
settings and screen size. (See above.)
Specifically, the four players are arranged around the four edges of
the table, with "us" at the bottom. For each player, the concealed
tiles are displayed nearest the edge of the table; our own tiles are
visible, the other players’ tiles are face-down. In front of the
concealed tiles are (to the player’s left) any declared sets, and (to
the player’s right) flowers and seasons, and the tong box if the player
is East. The tong box displays the wind of the round in a white circle.
If necessary, the flowers and seasons will overflow into the concealed
The discards are displayed face-up in the middle of the board: they are
laid down in order by each player, in the natural orientation. TODO:
add options to display discards randomly, or face-down. If animation
(see --animate option) is not being used, then the most recent discard
will be highlighted in red.
The name of a face-up tile can be displayed by right-clicking in the
tile. Alternatively, the Tiletips display option can be set, in which
case the name of a tile is displayed whenever the mouse enters it.
Our tiles are displayed in sorted order, which happens to be Bamboos
(1-9), Characters (1-9), Circles (1-9), Winds (ESWN), Dragons (RWG),
Flowers, Seasons. We can also arrange the tiles ourselves - see the
"Sort tiles in hand" display preference described below.
Actions are generally carried out by clicking a button in a dialog box
that appears in the middle of the board. For many actions, a tile must
be selected. A tile is selected or unselected by single-clicking it;
when selected, it appears as a depressed button. The program will
generally pre-select a sensible tile: specifically:
during the initial declaration of special tiles, the rightmost special
after we draw a tile from the wall, the drawn tile is selected;
when declaring concealed sets after going Mah Jong, the first
undeclared tile is selected.
To describe the possible actions, let us run through the course of a
First select "New local game..." from the "Game" menu. A panel will
appear. The default options are to play a game against the computer, so
click "Start Game". After a second or two, a game will start. (NOTE:
this assumes correct installation. If this fails, start a server and
players manually, and use the "Join server..." menu item.)
The first thing that happens is a dialog box "Ready to start next
hand". The server will not start playing a hand until all players have
indicated their willingness to continue play.
Next, the tiles are dealt. Then each player in turn is expected to
declare flowers and seasons. When it is our turn, a dialog will appear
with the following buttons:
declare the selected flower or season. (Note: the program auto-
selects the rightmost special tile.) If no tile is selected,
this finishes declarations. This button will not appear if the
game is being played without flowers and seasons.
Kong If we have a concealed kong, we can declare it now with this
Finish Finish declaring specials and kongs.
When all players have finished declaring specials and kongs, a dialog
box appears, asking (on East’s behalf) permission to continue.
During play, when we draw a tile from the wall, it will be auto-
selected. We may also of course select a different tile. A dialog will
appear giving us the following possibilities:
discard the selected tile. This button also serves to declare a
flower or season, and the label changes to "Declare" when one is
discard the selected tile and declare a calling hand. This
button is only shown when calling is allowed (by default, only
Original Call is allowed).
Kong declare a concealed kong of the selected tile, or add the
selected tile to an exposed pung, as appropriate
declare Mah Jong! (no selection needed)
If the wall is not being shown, the dialog will note the number of
tiles left in the live wall.
A tile can also be discarded simply by double-clicking it.
When another player discards, a dialog appears to allow us to claim it.
If the dialogs are in the middle of the table, the dialog displays the
tile in a position and orientation to indicate the player who
discarded; if the dialogs are at the bottom, this is not done, to save
space. In any case the dialog displays the name of the tile, and
buttons for the possible claims. (Note: in the default case, it is
possibly confusing that the discarded tile can be seen both on the
table and in the dialog box. Opinions are sought on this point.) If
the wall is not being shown, the dialog will note the number of tiles
left in the live wall. Note: there appear to be subtle bugs in GTK,
which mean that sometimes the name of the tile does not appear
properly. I have completely failed to track this down; if it happens,
just iconify (that’s minimize in Windoze-speak) the window and open it
again. There is also a ‘progress bar’ which shows how time is running
out. The buttons use one variant of traditional English terminology,
we don’t claim this tile. If there is no timeout in operation,
it is necessary to click this to indicate a "pass", and in any
case it is desirable to speed up play.
Chow claim for a sequence. If our claim is successful and there is
more than one possible sequence to be made, a dialog will appear
asking us to specify which one.
Pung claim for a triplet.
Kong claim for quadruplet.
claim for Mah Jong. If the claim succeeds, a dialog box will
appear asking whether we want the tile for "Eyes", "Chow",
"Pung", or a "Special Hand" (such as Thirteen Unique Wonders).
(The term "Eyes" is used instead of "Pair" so that when keyboard
accelerators are implemented, E is different from P! Is it
better to stick to "Pair"?)
When a player (including us) claims, the word "Chow!" etc. will appear
(in big letters on a yellow background, if things are correctly set up;
please tell me if this doesn’t happen) for a couple of seconds above
the player’s tiles.
When all players have claimed, or timed out, the successful claim is
implemented; no additional announcement is made of this. (Should it
If a player adds a tile to an exposed pung, and that tile would give us
Mah Jong, then a dialog box pops up to ask whether we wish to rob the
After somebody goes Mah Jong, we are asked to declare our concealed
sets. A dialog appears with buttons for "Eyes", "Chow", "Pung". To
declare a set, select a tile, which must be the first tile in the set
for a chow, and click the appropriate button. (If we are going Mah
Jong, the first undeclared tile is auto-selected.) When finished, click
"Finished" to reveal the remaining tiles to the other players. If we
are the winner, there will be a button for "Special Hand": this is used
to declare hands of non-standard shape, such as Thirteen Unique
Wonders. (Note: the Seven Pairs hand, if in use, should be declared by
means of the "Eyes" button, not the "Special Hand" button.)
At this point, a new top-level window appears to display the scoring
information. The scoring is done entirely by the server, not by the
players; the server sends a text description of the score calculation,
and this is displayed for each player in the Scoring window. The
information in the Scoring window remains there until the next hand is
scored; the window can be brought up at any time via the "Show" menu.
Finally, the "continue with next hand" dialog appears. The hand just
completed will remain visible on the table until the next hand starts.
There are keyboard accelerators for all the actions in the course of
play. For selecting tiles, the Left and Right arrow keys can be used to
move the selection left or right along the row of tiles. In all
dialogs, Space or Return will activate the shadowed button, which is
usually the commonest choice. Each button can also be activated by
typing the underlined letter. (In the Windows GTK1 build, use l (ell)
and r instead of Left and Right. The button accelerators do not work,
for reasons unknown to me.)
The menus are also accessible via accelerators. To open a menu, press
Meta-X (Alt-X on Windows), where X is the underlined letter in the menu
name. (Meta-X is often (confusingly) Alt-X on Linux systems.) Then
each entry has an underlined letter which if pressed will activate it.
An additional top-level window showing the state of the game can be
obtained by selecting "Game info" from the "Show" menu.
There is also a facility for sending text messages to the other
players. Select "Messages" from the "Show" menu, and a window will
appear: in the top is a display of all messages sent, and below is a
single line in which you can enter your message. It will be sent when
you hit Return. The message window pops up automatically whenever a
message is received, unless prevented by a display preference. If the
"Display status and messages in main window" display option is set,
then this window will instead appear in the main window, above the
table. In that case, there is a checkbox "Keep cursor here" next to the
message entry line. Checking this box will ensure that the keyboard
focus stays in the message entry field, even when you click on buttons
in the game. (Consequently, you will be unable to use keyboard
accelerators while this option is checked.)
Starting games and re-connecting
The "Game" menu has the "New local game..." item to start a new game on
your local computer, and the "Join server..." item to connect to an
existing game. The dialogs for both these have the following entries:
Checkboxes for Internet/Unix server
These specify whether the server is listening on an Internet
socket or a Unix socket. If an Internet (TCP) socket, the host
name ("Join Game..." only) and port number should be entered in
the appropriate boxes; if a Unix socket, the file name of the
socket should be entered. These fields are remembered from game
"Player ID" and "Name" fields
The "Player ID" should be left at 0, unless reconnecting to an
existing game, in which case it should be the ID assigned by the
server on first connecting to that game. The "Name" field can be
anything. When reconnecting to an existing game, if the ID is
given as 0, the server will try to use the "Name" to identify
the player. (This may not be true in future.) The "Name" field
is remembered from game to game.
The "Join server..." dialog then simply has a "Connect" button to
establish the connection. The "New local game..." has the following
For each of three further players,
A checkbox to say whether to start a computer player. (Some of)
these should be unchecked if you wish other humans to join the
games. If checked, there is a text entry to set the players’
names, and a text entry field in which options can be given to
the players; the latter should only be used if you understand
An "allow disconnection" checkbox
If this is checked, the server that is started will continue to
run even if players disconnect. If it is not checked, the server
will quit if any player disconnects. If you are playing one
against the computer, this should generally be left unchecked,
in order to avoid server processes accidentally being left lying
around. If playing against people, it should be checked, to
allow players to go away, or to guard against network outages.
As "save game state on exit" checkbox
If this is checked, the server will save the game state (see
below on on saving and resuming games) when a player disconnects
and causes it to quit.
A "seat players randomly" checkbox
If this is left unchecked, players will be initially seated as
East, South, West, North in order of connection. (We always
connect first.) If it is checked, the seating will be random.
A numeric entry field
to specify the time limit for claiming discards. If set to 0,
there will be no time limit.
A button to start the game
Note that it takes a few seconds to start a game, during which
time the dialog stays up with the button pressed. (TODO: fix
Saving and resuming games
At any time during the play of a game, you can choose the "Save" entry
from the "Game" menu. This causes the server to save the current state
of the game in a file. The file will be named game-date.mjs by default;
if a name has previously been specified, or if the game was resumed
from a file, that name will be used. To specify a name, use the "Save
as..." entry in the "Game" menu. Note that for security, directories
cannot be specified (except by resuming a game), so the file will be
created in the working directory of the server.
To resume a saved game, use the "Resume game..." entry from the "Game"
menu. This is just like the "New local game..." panel, but it has a box
to specify the file containing the saved game. At present, you must
type the name of the file into this box. TODO find a file selector
widget for this.
Setting display and game options
The "Options" menu of xmj brings up panels to set various options
related to the display and to the game rules. Most of these options
can be stored in the preferences file, which is .xmjrc in your home
directory on Unix, and xmj.ini in your home (whatever that means)
directory on Microsoft Windows.
This panel controls options related to the local display. At the
bottom are three buttons: "Save & Apply" applies changes and saves them
in the preferences file for future sessions; "Apply (no save)" applies
any changes, but does not save them; "Cancel" ignores changes. Note
that many display options can also be controlled by command-line
arguments; if an option is specified both in the preferences file and
on the command line, the command line takes priority.
Position of action dialogs.
This determines where the dialogs for user actions in the game
are popped up; see the description of the --dialogs-central etc.
options above. This option is stored in the preferences file as
Display DialogPosition posn
where posn is one of "central", "below" or "popup".
determines whether tile movements are animated (see the
--animate option above). This option is stored in the
preferences file as
Display Animate bool
where bool is "0" or "1".
Display status and messages in main window
puts the game status and message (chat) windows in the main
window, above the table, instead of having separate popup
windows. This option is stored in the preferences file as
Display InfoInMain bool
where bool is "0" or "1".
Don’t popup scoring/message windows
will prevent the automatic popup of the scoring window at the
end of a hand, the message window on the arrival of a message,
and the game status window at the end of the game. This option
is stored in the preferences file as
Display NoPopups bool
where bool is "0" or "1".
Tiletips always shown
means that the name of a tile is displayed whenever the mouse
enters it, and the name of the selected tile is always shown.
(Otherwise, right-click to display the name.) This option is
stored in the preferences file as
Display Tiletips bool
where bool is "0" or "1".
This drop-down list specifies the size of the display. The size
should be thought of as the length of a tile rack. This is only
relevant if the wall is not being displayed. Values range from
14 to 19; if "(auto)" (the default) is specified, the client
tries to choose a size as big as will fit in the display. This
option can also be specified by the command line --size
argument. This option is stored in the preferences file as
Display Size n
Show the wall
"always" is equivalent to the --show-wall option; "never" is
equivalent to the --no-show-wall option; and "when room" is the
default. This option is stored in the preferences file as
Display ShowWall when
where when is one of "always", "when-room" or "never".
Sort tiles in hand
By default, the program maintains your own tiles in sorted
order. If you prefer to leave them unsorted (which is often
recommended in real life, to avoid giving information to your
opponents), or to arrange them yourself, you can set this option
to "never", or to "on deal" if you want them to be sorted at the
beginning, but then left alone. To rearrange tiles, use the
Shift-Left and Shift-Right (i.e. the left and right arrow keys
while holding Shift) - these move the selected tile left or
right in your hand. (In the Windows GTK1 build, use L (Shift-l)
and R (Shift-r) instead.) On GTK2 builds, you can also drag a
tile to its new position with the mouse. This option is stored
in the preferences file as
Display SortTiles when
where when is one of "always", "deal" or "never".
Iconify all windows with main
If this option is set (the default), then when the main xmj
window is iconified, (almost) all other open windows such as
dialogs will also be iconified; when the main window is
uniconified, the other windows will also be uniconified. If it
is not set, all windows are independent of one another. This
option is stored in the preferences file as
Display IconifyDialogs bool
This option is not currently supported under Microsoft Windows.
this is the tile pixmap directory, also given by the --tileset
option. This option is stored in the preferences file as
Display Tileset dirname
this is the search path for tileset directories, also given by
the --tileset-path option. This option is stored in the
preferences file as
Display TilesetPath search-path
Main font selection...
This button brings up a font selection dialog to choose the font
used in buttons, menus, etc. in the client. This option is
stored in the preferences file as
Display MainFont font-name
where font-name is a font name, which may be an X LFD in the
Unix GTK+1 version, or a Pango font name in the Windows and Unix
Text font selection...
This button brings up a font selection dialog to choose the font
used in text display (such as scoring info and chat) in the
client. This option is stored in the preferences file as
Display TextFont font-name
Table colour selection...
Unaccountably, not everybody likes my choice of dark green for
the table background. This button brings up a colour selection
box to allow the table colour to be changed.This option is
stored in the preferences file as
Display TableColour col
where col is a GTK colour specification. The format depends on
whether xmj is built with GTK+1 - in which case it is an X color
of the form rgb:RRRR/GGGG/BBBB - or GTK+2 - in which case it is
a GTK2 color of the form #RRRRGGGGBBBB. GTK+2 programs will
convert an old GTK1 specification.
In the GTK+2 build, xmj by default ignores completely the system
and user settings for look and feel, and uses its own built in
settings. These settings use the Clearlooks theme, if it is
available, to provide a simple but clean look with slightly
rounded tiles; and fall back to a plain theme, as compact as
possible with the standard engine. If you wish, you can use this
option to specify the name of a GTK rcfile which will be read
instead of the built in settings. A minimal set of settings
will be read before your file is read. Such a file can specify
many details of the appearance, provided that you know how to
write a GTK rcfile. You will need to know that xmj uses the
following styles and bindings:
gtk-font-name = fontname
can be used to change the overall font used by widgets. This
will overridden by the font specified by the Main Font option,
is used to give the green (or whatever you set) colour to the
table. All widgets that should have this style are named
"table", so the appropriate binding (already set in the minimal
widget "*.table" style "table"
is used to give the white text colour to the player status
labels in the corners of the board (if shown). All widgets that
should have this style are named "playerlabel", so the
appropriate binding (already set in the minimal set) is
widget "*.playerlabel" style "playerlabel"
is used in the default settings for all widgets named "tile",
which are all tiles except the tiles in your own concealed hand.
This style is not used in the minimal settings, but if set it
should be bound with
widget "*.tile" style "tile"
is used in the default settings for the concealed tiles in your
hand, which are active buttons. These tiles are all named
"mytile". This style is not used in the minimal settings, but if
set it should be bound with
widget "*.mytile" style "mytile"
is used to set the yellow background and large font of the claim
announcement popups. These popups are named "claim", so the
appropriate binding (already set in the minimal set) is
widget "*.claim" style "claim"
is used to change the font for the text widgets such as message
boxes and input fields. In the minimal settings, it is empty,
but is defined and bound to the relevant widgets. The binding
should not be changed, but the style itself can be redefined. If
the Text Font option is set, this style will be redefined in
order to implement it.
is defined and bound to the top-level window to implement the
use of the left and right arrow keys to change the selected
tile. It is probably not helpful to change this.
The distribution contains three example gtkrc files, called
gtkrc-minimal, gtkrc-plain, and gtkrc-clearlooks, which contain
the program’s compiled in settings.
This option is stored in the preferences files as
Display Gtk2Rcfile file-name
Note that if the file-name is relative, it will be interpreted
relative to the current directory in Unix, or the program
directory in Windows.
Use system gtkrc
As noted above, xmj does not normally load the system settings
in the GTK+2 build. If this option is checked, it will (after
the minimal settings, but before the default or user-specified
settings). This option is stored in the preferences files as
Display UseSystemGtkrc bool
where bool is 0 or 1.
Note for GTK+1 builds
Under a GTK+1 build, xmj does what any other application does.
This should allow the use of a .gtkrc file to change colours,
using the styles and bindings given above. However, this is not
a supported activity.
This panel controls what actions the client may take on your behalf.
The first (and currently only) section specifies when the client should
declare tiles and sets for you. It has the following checkboxes:
flowers and seasons
if checked, will be automatically declared as soon as drawn.
if this is checked, then when somebody else goes out, the client
will declare your closed sets. It declares in the order pungs,
this is the same for when you go out.
The panel has "Save & Apply", "Apply (no save)" and "Cancel" buttons,
as in the display options panel.
Game Option Preferences
This panel controls preferred game options which will be sent to the
server when a game starts. Preferences will only be applied if we are
the game manager, or the game has no manager. (Normally, the first
human player to connect to the server becomes the game manager.)
For details of options and their meanings, see the Game Options section
in the rules.
The panel has two action buttons, "Save Changes" and "Cancel", with the
obvious meanings. Note if a game is in progress, changed preferences
are NOT applied to it; however, there is a button in the Current Game
Options panel to apply preferences.
The main body of the panel is a scrollable window listing all the known
options. If no preference is stored for the FooBar option, then there
is an "Add pref" button next to a description of the FooBar option. If
this button is clicked, an entry for setting the option appears. The
format of this entry depends on the type of the option (see the Game
Options section of the rules for details of types):
Boolean (on/off) options
have a checkbox.
have a spinbutton for numerical entry: the value can be typed
in, or the up and down arrows can be used to change it
have radio buttons for selecting Limit, Half-Limit, or other;
for other, the number of doubles and/or points is entered with
spinbuttons. (Note: the underlying protocol allows percentages
(possibly more than 100%) of limits to be specified for scores;
however, the current graphical interfaces allow only limits or
half-limits. Even half-limits are pretty strange, but some
bizarre sets of rules, such as those of the British Mah-Jong
Association (which plays a weird American/Western/Chinese mix),
allow other fractions of limits.)
have a simple text entry field.
All option entries have a "Reset" button which returns the entry to its
A preference is removed by clicking the "Remove pref" button.
Current Game Options
When there is a connected game, this panel allows its game options to
be modified (if we have permission to do so). The three action buttons
are "Apply changes", which applies the panel’s settings to the current
game; "Apply prefs", which applies our preferences (as described above)
to the current game; and "Cancel".
The body of the panel contains entries for all the options of the
current game, in the same format as the preferences panel (see above).
The latest release of the Unix Mah-Jong programs should be available at
The game currently implemented is a version of the classical Chinese
game. The most convenient and comprehensive set of rules is that
provided by A. D. Millington, "The Complete Book of Mah-Jongg",
Weidenfield & Nicolson (1993), ISBN 0 297 81340 4. In the following, M
103 denotes item 103 of the rules laid out in Chapter 3 of that book. I
here describe only the differences from these rules, some of which
differences are consequences of using computers, and some of which are
points where my house rules differ from Millington’s version. In due
course, all variations (of Chinese classical) will be accommodated, if
there is sufficient desire.
Classification of tiles (M 1-8): the tiles are a standard Chinese set.
The tiles do not have Arabic numerals, except for the flowers and
seasons, where the identifying Chinese characters are too small to be
legible. A numbered set is included in the distribution and can be used
via the Tileset display preference.
The flowers and seasons may be removed from the tile set by unsetting
the Flowers game option.
Preliminary (M 9-10): nothing to say.
Duration of the game (M 11-14): standard rules. In particular, the
title of East does not pass after a wash-out.
Selection of seats (M 15): the players are seated in the order they
connect to the server, or randomly, according to the option given to
The deal etc. (M 16-27): There is no attempt to simulate the usual
dealing ritual (M 16-20, 23-26); the wall is built randomly by the
server. The dead wall is also maintained by the server.
The existence of a dead wall is controlled by the DeadWall game option;
normally there is a dead wall.
The deal wall is either 14 tiles and kept at 13 or 14 during play (as
in most authors), or is 16 tiles, not extended during play (per
Millington (M 22)), according to the DeadWall16 game option.
Replacement tiles for kongs are always taken from the loose tiles, but
replacements for bonus tiles may be drawn from the live wall (M 31), or
from the loose tiles, according to the FlowersLoose game option.
Object of game (M 28-31): all winning hands must comprise four sets and
a pair, with the exception of the Thirteen Unique Wonders. If the
SevenPairs game option is set, then a hand of any seven pairs is also
allowed as a winning hand.
Bonus tiles (M 31): M requires that bonus tiles must be declared in the
turn in which they are drawn; otherwise the player may not exchange or
score them (and thus they cannot go out). We do not make this
restriction, as it is (a) pointless (b) unenforceable in real life.
Bonus tiles may be declared at any time after drawing from the wall.
(Obviously, there is no reason not to declare them immediately.)
Commencement of the Game (M 32-33): standard.
Playing procedure (M 34-38): standard. In particular, the other
players have to give permission for east to start playing (M 34). The
display of discards cannot be controlled by the server; the current X
client displays them in an organized fashion, rather than the random
layout required by M 35.
Chow (M 39-42): standard.
Pung (M 43-45): standard.
Kongs (M 46-52): M distinguishes three types of kong: concealed,
claimed (by Kong), and annexed (formed by adding a discard to an
exposed pung), and allows claimed kongs to be counted as concealed for
the purposes of doubling combinations. I have not seen this anywhere
else; normally, a claimed kong is treated as exposed for all purposes.
We follow the normal convention; however, the game option KongHas3Types
can be set to implement M’s rules. In this case, the xmj program will
distinguish claimed kongs by displaying them with the last tile face
down, whereas annexed kongs are all face up.
Players may declare a concealed kong, or add to a pung, only when they
have just drawn a tile from the wall (live or dead); not just after a
claiming a discard. (A silly restriction in my view, but one that all
rule sets seem to have (M 51).)
Calling and Mah Jong (M 53-54): standard. (I.e. there is no "Calling"
NOTE: M permits players to change their mind about making a claim (M
69); we do not, and all claims are irrevocable. Question: should we
Original Call (M 55): the Original Call declaration must be made
simultaneously with the first discard, rather than afterwards. NOTE:
the server does *not* check that the declarer does indeed have a
calling hand, as a mistaken original call does not damage the other
players or the progress of the game. The server does, however,
thereafter prevent the declarer from changing their hand; therefore a
mistaken original call will make it impossible to go out. (Note: in M,
an Original Caller may change their hand, but will thereby lose the
ability to go out (M 55(b)); is this a better way to treat it?) Note
also: as per M, an original call can be made even if another player has
claimed a discard before, unlike the Japanese version.
Robbing a Kong (M 57-60): Robbing a kong is implemented. However, as
with discards, we require that kongs are robbed before anything else
happens, and in particular before the konger draws a replacement tile.
Therefore, after a kong, all other players must either claim Mah Jong
or pass. (The provided programs will pass automatically if robbing is
not possible.) As for discards, there is a time limit.
Precedence of claims for discard (M 61-65): Many rules allow a discard
to be claimed up until the time the next discard is made. M does this,
with elaborate rules for the precise specification. For ease of
implementation, we do not allow this: instead, all players are required
to make a claim or pass, and once all players have claimed, the
successful claim is implemented irrevocably. The server imposes a time
limit; players that do not claim within the limit are deemed to have
passed. This defaults to 15 seconds, but can be changed or disabled by
the Timeout game option.
Irregularities in Play (M 66-81): the server does not permit unlawful
moves, and so no irregularities can arise.
False Declaration of Mah Jong (M 82-83): such declarations are not
permitted by the server.
False Naming of Discards (M 84-88): this also cannot happen.
Incorrect Hands (M 89): cannot happen.
Letting Off a Cannon (M 90-96): as in M. However, if a player makes a
dangerous discard, but has no choice, the server will determine this;
it is not necessary to plead "no choice" explicitly, and neither is the
player’s hand revealed to the other players.
Wash-Out (M 97-99): standard.
Points of Etiquette (M 100-102): not applicable.
Displaying the Hand (M 103-106): The format of display is a matter for
the client program, and cannot be controlled by the server.
After Mah Jong, the players are responsible for declaring concealed
sets in whatever way they wish. The winner, of course, is required to
declare a complete hand; but the losers may declare as they wish. Once
a set is declared, it cannot be revoked. Note that the losers may
declare multiple scoring pairs.
Procedure in Settlement (M 107-111): The settlement is classical: that
is, the winner gets the value of their hand from all players; the
losers pay one another the differences between their scores; except all
payments to or from East are doubled; and if players let off a cannon,
they pay everybody’s debt. Unlike normal play (M 110), all hands are
scored by the server, rather than by the players. Settlement is also
computed by the server. Some variations in settlement are provided: if
the LosersSettle game option is set to false, there are no payments
between losers; if the EastDoubles game option is set to false,
payments to or from East are not doubled; if the DiscDoubles game
option is set to true, then the discarder of the tile that gave Mah-
Jong will pay double to the winner, and a self-draw is paid double by
Method of Scoring (M 112-122): The method is standard (M 112), viz
calculate points obtained from sets and bonuses, and then apply
The following points are given for tiles:
4 each (M 114(a))
Pungs: 2 for exposed minor tiles; 4 for exposed major or concealed
minor; 8 for concealed major. (M 114(b))
Kongs: 8 for exposed minor; 16 for exposed major or concealed minor; 32
for concealed major. (M 114(c))
Chows: no score. (M 114(d))
Pair: 2 for a pair of Dragons, Own Wind, or Prevailing Wind. A pair
that is both Own and Prevailing Wind scores 4. (M 114(e)) Non-
winning hands may score more than one pair.
the winner gets 20 points for going Mah Jong. This can be
changed by the MahJongScore game option (M 115(a) has 10
Seven Pairs hand:
If Seven Pairs hands are allowed, they receive an additional
score of 20 points, changed by the SevenPairsVal game option.
Winning from wall:
if the final tile is drawn from the wall, 2 points are added (M
Filling the only place:
if the final tile is the only denomination that could have
completed the hand, 2 points are added (M 115(c)). NOTE: As in
M, if all four copies of a tile are exposed on the table, it
does not count as available for completing the hand.
Fishing the eyes:
a player who completes by obtaining a pair gets 2 points if the
pair is minor, or 4 if major (M 115(d)). Note: to obtain these
points for a discard, the player must actually claim the discard
for a pair: e.g. if waiting on 5677, and 7 is discarded, the
player must claim for the pair, not the chow.
The following doubles apply to all hands. All possible clauses apply
unless stated otherwise.
Having own flower or own season.
No extra score. Changed by the FlowersOwnEach game option.
Having own flower AND own season,
1 double. (M 116(a)). Changed by the FlowersOwnBoth game option.
Having all four flowers,
1 double. (M 116(b)). Changed by the FlowersBouquet game option.
Having all four seasons,
1 double. (M 116(b)). Changed by the FlowersBouquet game option.
Each set of dragons,
1 double. (M 116(d))
A set of the player’s own wind,
1 double. (M 116(e))
A set of the prevailing wind,
1 double. (M 116(f))
"Little Three Dragons": two sets and a pair of dragons.
1 double. (M 116(g))
"Big Three Dragons": three sets of dragons.
2 doubles. (M 116(h))
"Little Four Winds": three sets and a pair of winds.
1 double. (M 116(i))
"Big Four Winds": four sets of winds.
2 doubles. (M 116(j))
(Note: the definitions of these last four doubles when applied
to non-winning hands are subject to wide variations. Possibly
there should be options to allow other possibilities.)
Three concealed pungs:
1 double. (M 116(k)) (Note: if the KongHas3Types game option is
set, a claimed kong counts as concealed for this hand; see the
note above under "Kongs".)
The following doubles apply to the winning hand only:
No score hand: four chows and a non-scoring pair.
1 double. (M 117(a)) (Note: like M, we allow any of the extra
points (Fishing the Eyes, etc) to go with this double. Some
rules say that the extra points invalidate this hand. Possibly
there should be an option for this.)
1 double. (M 117(b))
1 double (M 117(c)), changeable with the ConcealedFully game
option. (Note: this means a hand that is fully concealed after
going out. Another common value for this is 3 doubles, in which
case 1 double is usually given for a semi-concealed hand (see
below).) (Note: if the KongHas3Types game option is set, a
claimed kong counts as concealed for this hand; see the note
above under "Kongs".)
The following doubles normally apply to the winning hand only; however,
the LosersPurity game option can be set to allow losing hands to score
them (this is a highly deprecated American feature, but has been
requested by a user).
no doubles, changeable with the ConcealedAlmost game option.
(Not in M) (Note: this means a winning hand that is concealed up
to the point of going out, or, if enabled, a concealed losing
hand. According to a discussion on rec.games.mahjong, a winning
semi-concealed hand is classically awarded one double (with
three given for fully concealed). One book in my possession
(U.S.A., early 1920s) awards this double only to a hand that is
concealed except for the pair.) (Note: if the KongHas3Types
game option is set, a claimed kong counts as concealed for this
hand; see the note above under "Kongs".)
One suit with honours:
1 double. (M 117(d))
One suit only:
3 doubles. (M 117(e))
1 double. (M 117(f))
All honours (in an unlimited game):
2 doubles. (M 117(g)) (Note: such a hand will also score the
double for all majors.)
All terminals (in an unlimited game):
2 doubles. (Not in M) (Note: such a hand will also score the
double for all majors.)
The following doubles apply only to the winning hand:
Winning with loose tile:
1 double. (M 117(h)) (Note: with the default settings,
replacements for bonus tiles come from the live wall. Hence this
double applies only to winning after Kong.)
Winning from the bottom of the sea (winning with last tile),
1 double. (M 117(i))
Catching a fish from the bottom of the sea (winning with last discard),
1 double. (M 117(j))
Robbing a kong,
1 double. (M 117(k))
Completing Original Call,
1 double. (M 117(l))
Limit (M 118-120): the limit is 1000 by default, and can be changed by
the ScoreLimit game option. The NoLimit game option can be used to play
a game "with the roof off".
The following hands are limit hands:
Heaven’s Blessing: East wins with dealt hand. (M 122(a))
Earth’s Blessing: player wins with East’s first discard. (M 122(b))
Gathering Plum Blossom from the Roof: winning with 5 Circles from the
loose wall. (M 122(c))
Catching the Moon from the Bottom of the Sea: winning with 1 Circle as
the last tile. (M 122(d)) (Note: M says that the tile must be
drawn. It seems more reasonable also to allow it to be the last
discard, which is what we do. Objections?)
Scratching a Carrying Pole: robbing a kong of 2 Bamboos. (M 122(e))
(Note: these last three limits are rather arbitrary, but of the
arbitrary limits they are apparently the most common. There
should be options to disable them.)
Kong upon Kong: making a Kong, making another Kong with the loose
tile, and with the second loose tile obtaining Mah Jong. (Also,
of course, with three or four successive kongs.) (M 122(f))
Four Kongs. (M 122(g))
Buried Treasure: all concealed and no chows. (M 122(h))
The Three Great Scholars: three sets of dragons and no chows. (M
(Note: in most rules I have seen, there is no restriction to a
no chow hand. Since in M’s rules, three sets and a chow scores
at least (10 (M has 10 for Mah Jong) + 12 (at least 3 pungs))
times 8 (2 for each set of dragons) times 4 (for Big Three
Dragons) = 704, this is significant with the default limit. For
us, with 20 for going out, Big Three Dragons is over the default
Four Blessings o’er the Door: four sets of winds and a pair. (M 122(j))
All Honours. (M 122(k))
Heads and Tails: all terminals. (M 122(l))
Imperial Jade: contains only Green Dragon and 2,3,4,6,8 Bamboo. (M
(Note: another rather arbitrary hand, but widely adopted.)
Nine Gates: calling on 1-1-1-2-3-4-5-6-7-8-9-9-9 of one suit. (M
Wriggling Snake: 1-1-1-2-3-4-5-6-7-8-9-9-9 plus 2, 5 or 8 of
one suit (M 122(o)). (Note: another rather arbitrary hand.)
Concealed Clear Suit: one suit only and all concealed. (M 122(p))
Thirteen Unique Wonders: one of each major tile, and a match to any of
them. (M 122(q))
East’s 13th consecutive Mah-Jong. (M 122(r))
General note: there are many other doubles and limits kicking around. I
welcome opinions on which should be possible options; and also on which
of the above I should eject from the default set. I dislike Imperial
Jade, Wriggling Snake, and the ones depending on a specific tile
(Gathering Plum Blossom, Catching the Moon, Scratching a Carrying
Pole): which of these are so commonly adopted that they should be in
even a fairly minimalist default set?
This section describes the options that can be set in the game. Whether
an option can be used, depends on the version of the programs. This is
described by a "protocol version number"; this is not strictly speaking
a version just of the communication protocol, but a version number
reflecting the combination of protocol and programs. When playing by
oneself, this does not matter, but in the case of a networked game,
players might have different versions of the software, in which case
the game is played according to the lowest version of any player.
Game options can be controlled in two ways: the --option-file argument
to the mj-server program gives options to be applied to the game, or
options can be set by the players, using the interface described in the
manual section for xmj.
In the user interface, the options are referred to by a one line
description, but each option also has a short name, given here.
Options are of several types:
bool boolean, or on/off, options.
int integer options
nat non-negative integer options
string is a miscellaneous type, whose values are strings of at most 127
characters which must not contain white space
score is the type used for options that give the score of some
combination or feature in a hand. A score is either a limit (or
a half-limit; the underlying protocol supports percentages of
limits, but the current user programs only support limits and
half limits); or a number of doubles to be awarded; or a number
of points to be added. It is possible (though never needed) to
have both points and doubles. If points/doubles are specified as
well as a limit, they will be used in a no-limit game. (The
server implements a hard limit of 100000000 on all scores to
avoid arithmetic overflow, but that’s unlikely to worry
Currently supported options
The following options are implemented in the versions of the program
with which this document is distributed. If playing against people with
older versions of the software, some options may not be available. The
list gives for each option the short name, type, and short description,
followed by a detailed explanation.
Timeout (nat) time limit for claims
This is the time in seconds allowed to claim a discard, or to
rob a kong. If set to zero, there is no timeout. The default is
TimeoutGrace (nat) grace period when clients handle timeouts
This period (in seconds) is added to the Timeout above before
the server actually forces a timeout. This is for when clients
handle timeouts locally, and allows for network lags. If this
option is zero, clients are not permitted to handle timeouts
locally. The current server also only allows players to handle
timeouts locally if all of them wish to do so.
ScoreLimit (nat) limit on hand score
This is the limit for the score of a hand. In a no-limit game,
it is the notional value of a "limit" hand. The default is 1000.
NoLimit (bool) no-limit game
If this option is set, the game has no limit on hand scores. The
default is unset.
MahJongScore (score) base score for going out
This is the number of points for obtaining Mah-Jong. The
default is 20.
SevenPairs (bool) seven pairs hand allowed
If this option is set, then Mah-Jong hands of seven pairs (any
seven pairs) are allowed. The default is unset.
SevenPairsVal (score) score for a seven pair hand
This gives the score (in addition to the base Mah-Jong score)
for a seven pairs hand. The default is 20.
Flowers (bool) play using flowers and seasons
If this option is set, the deal includes four flowers and four
seasons in the Chinese Classical style. If unset, only the 136
standard tiles are used. The default is set.
FlowersLoose (bool) flowers replaced by loose tiles
If playing with flowers, this option determines whether flowers
and seasons are replaced from the live wall (unset), or by loose
tiles (set). The default is unset.
FlowersOwnEach (score) score for each own flower or season
This option gives the score for having one’s own flower or
season. If one has both, this score will be given twice. The
default is no score.
FlowersOwnBoth (score) score for own flower and own season
This is the score for having both one’s own flower and one’s own
season. Note that this is awarded in addition to twice the
previous score. The default is 1 double.
FlowersBouquet (score) score for all four flowers or all four seasons
This is the score for having all four flowers or all four
seasons. The default is 1 double.
DeadWall (bool) there is a dead wall
This determines whether there is a dead wall, so that play ends
when it is reached (set), or whether all tiles may be drawn
(unset). The default is set.
DeadWall16 (bool) dead wall is 16 tiles, unreplenished
If this option is set, then the dead wall initially has 16
tiles, and does not have any more tiles added to it (this is the
set-up described by Millington). If the option is unset, then
the dead wall initially has 14 tiles, and after two loose tiles
have been taken, two tiles are moved from the live wall to the
dead wall (this is the set-up described by almost everyone
else). The default is unset in versions 1.1 onwards, and set
previously. (To be precise, the protocol level default is set,
but all servers from 1.1 onwards will change this to unset.)
ConcealedFully (score) score for fully concealed hand
This is the score for a winning hand with no open sets. The
default is 1 double.
ConcealedAlmost (score) score for almost concealed hand
This is the score for a hand that is concealed up to the point
of going out. The default is no additional score.
LosersPurity (bool) losing hands score doubles for pure, concealed etc.
If this option is set, losing hands will score various doubles
for one suit, almost concealed, etc. See the rules for details.
This option is an (Anglo-)Americanism alien to Chinese Classical
(see Foster for a spirited but faulty argument in its favour,
and Millington for the rejoinder). The default is unset.
KongHas3Types (bool) claimed kongs count as concealed for doubling
If this option is set, claimed kongs count as concealed for
various doubling combinations, although they score as exposed
for basic points. See the note above under "Kongs". The default
LosersSettle (bool) losers pay each other
If this option is set, the losers pay each other the difference
between their scores. If it unset, they pay only the winner.
The default is set.
EastDoubles (bool) east pays and receives double
If this option is set, payments to and from East Wind are
doubled, as in the Chinese Classical game. The default is set.
DiscDoubles (bool) the discarder pays double
If this option is set, the settlement procedure is changed to a
style common in Singapore. That is, if the winning player wins
off a discard, the discarder pays double the hand value, and the
other players pay the hand value. If the winner wins from the
wall, then all other players pay double the hand value. The
default is unset. Note: EastDoubles and DiscDoubles can be set
together, but nobody plays such a rule.
ShowOnWashout (bool) reveal tiles on washout
If this option is set, the players’ hands will be revealed in
the event of a washout.
NumRounds (nat) number of rounds to play
This option says how many rounds to play in the game. For
aesthetic reasons, the possible values are 1, 2, or a multiple
of 4. In the 2 round case, the East and South rounds will be
played. It defaults to the usual 4 rounds.
Option file format
Both in the option file and in the .xmjrc file, options are recorded in
the format used by the server protocol. This is a line of the form
GameOption 0 name type minprot enabled value desc
The meanings of the elements are:
identifies this as a game option line (the 0 is an irrelevant
field from the protocol).
name is the name of the option.
type is the type of the option.
is the minimum protocol version with which the option can be
used (which is not necessarily the version at which it was
will always be 1.
value is the value: a decimal (signed) integer for nat and int; 0 or 1
for bool; the string for string; and for score, if the score is
c centi-limits, d doubles and p points, the value is c*1000000 +
d*10000 + p.
desc is a short description of the option, which is not required but
is usually copied in from the server.