UCI
(=universal chess interface)
This is the
description of a new interface between a chess engine and a graphical user
interface called UCI. It was designed by Rudolf Huber and Stefan Meyer-Kahlen
and is used in the chess engines SOS 11/2000 and Shredder 5 as well as in the
Shredder 5 graphical user interface. Also the new version 6 of Chess Assistant
will support this engine interface. The UCI interface is free to use for
everyone, so you can use it in your own program without any licence fees or
restrictions. If you make any additions or modifications to the interface it
might be a good idea to contact me before so we can keep compatibility.
The interface
is similar to Winboard, keeping its easiness but eliminating the disadvantages
of it. It should be not much work to adept an chess engine to UCI especially if
it’s already supporting winboard. It is also possible to support both UCI and
winboard in the same exe file.
What are
the advantages of UCI compared to Winboard?
The
advantages to other engine interfaces are:
Below is
the “formal” definition of the engine interface, if you have any more question concerning UCI I will try to answer
them.
Stefan
-------------------------------------------------------------------------------------------------
Description
of the universal chess interface (UCI)
==================================================
* The
specification is independend of the operationg system. For Windows,
the engine is a normal exe file, either a
console or "real" windows application.
* all communication
is done via standard input and output with plain text commands,
* The
engine should boot and wait for input from the GUI,
the engine should wait for the
"isready" or "setoption" command to set up its internal
parameters
as the boot process should be as quick as
possible.
* the
engine must always be able to process input from stdin, even while thinking.
* all
command strings the engine receives will end with '\n',
also all commands the GUI receives should
end with '\n',
* The
engine will always be in forced mode which means it should never start
calculating
or pondering without receiving a
"go" command first.
* The
engine should never execute a move on its internal chess board
without being asked to do so by the GUI,
e.g. the engine should not execute the best move after a search.
* Before
the engine is asked to search on a position, there will always be a position
command
to tell the engine about the current
position.
* all the
opening book handling is done by the GUI,
but there is an option for the engine to ues
its own book ("OwnBook" option, see below)
Move
format:
------------
The move
format is in long algebraic notation.
Examples: e2e4, e7e5, e1g1 (white short castling),
e7e8q (for promotion)
GUI to
engine:
--------------
These are
all the command the engine gets from the interface.
* uci
tell engine to use the uci
(universal chess interface),
this will be send once as a
first command after program boot
to tell the engine to switch to
uci mode.
After receiving the uci command
the engine must identify itself with the "id" commmand
and sent the "option"
commands to tell the GUI which engine settings the engine supports if any.
After that the engine should
sent "uciok" to ackknowledge the uci mode.
If no uciok is sent within a
certain time period, the engine task will be killed by the GUI.
* debug [
on | off ]
switch the debug mode of the
engine on and off.
In debug mode the engine should
sent additonal infos to the GUI, e.g. with the "info string" command,
to help debugging, e.g. the
commands it the engine has reveived etc.
This mode should be switched off
per default and this command can be sent
any time, also when the engine
is thinking.
* isready
this is used to synchronize the
engine with the GUI. When the GUI has sent a command or
multiple commands that can take
some time to complete,
this command can be used to wait
for the engine to be ready again or
to ping the engine to find out if
it is still alive.
E.g. this should be sent after
setting the path to the tablebases as this can take some time.
This command is also required
once before the engine is asked to do any search
to wait for the engine to finish
initializing.
This command must always be
answered with "readyok"
* setoption
name <id> [value <x>]
this is sent to the engine when
the user wants to change the internal paramters
of the engine. For the
"button" type no value is needed.
One string will be sent for each
paramter and this will only be sent when the engine is waiting.
The name of the option in
<id> should not be case sensitive!
Here are some strings for the
example below:
"setoption name Nullmove value true\n"
"setoption name Selectivity value
3\n"
"setoption name
Style value Risky\n"
"setoption name Clear Hash\n"
"setoption name NalimovPath value
c:\chess\tb\4;c:\chess\tb\5\n"
* position
[fen <fenstring> | startpos ]
moves <move1> .... <movei>
set up the position described in
fenstring on the internal board and
play the moves on the internal
chess board.
if the game was played from the start postion the string
"startpos" will be sent
Note: no "new" command
is needed.
* go
start calculating on the current
position
There are a number of commands
that can follow this command, all will be sent in the same string.
If one command is not send its
value should be interpreted as it would not influence the search.
* searchmoves <move1> ....
<movei>
restrict
search to this moves only
* ponder
start
searching in pondering move.
Do
not exit the search in ponder mode, even if it's mate!
This
means that the last move sent in in the position string is the ponder move.
The
engine can do what it wants to do, but after a "ponderhit" command
it
should execute the suggested move to ponder on.
* wtime <x>
white
has x msec left on the clock
* btime <x>
black
has x msec left on the clock
* winc <x>
white
increment per move in mseconds if x > 0
* binc <x>
black
increment per move in mseconds if x > 0
* movestogo <x>
there are x moves to the next time control,
this
will only be sent if x > 0,
if
you don't get this and get the wtime and btime it's sudden death
* depth <x>
search
x plies only.
* nodes <x>
search x nodes only,
* mate <x>
search
for a mate in x moves
* movetime <x>
search
exactly x mseconds
* infinite
search
until the "stop" command. Do not exit the search without being told
so in this mode!
* stop
stop calculating as soon as
possible,
don't forget the
"bestmove" command when finishing the search!
* ponderhit
user has played the expected
move. This will be sent if the engine is pondering on the same move
the user has played. The engine should
continue searching but switch from pondering to normal search.
* quit
quit the program as soon as
possible
Engine to
GUI:
--------------
* id
* name <x>
this
must be sent after receiving the "uci" command to identify the
engine,
e.g.
"id name Shredder 5.0\n"
* author <x>
this
must be sent after receiving the "uci" command to identify the
engine,
e.g.
"id author Stefan MK\n"
* uciok
Must be sent after the id and
optional options to tell the GUI that the engine
has sent all infos and is ready
in uci mode.
* readyok
This must be sent when the
engine has received an "isready" command and has
processed all input and is ready
to accept new commands now.
It is usually sent after a
command that can take some time to be able to wait for the engine,
but it can be used anytime, even
when the engine is searching,
and must always be answered with
"isready".
* bestmove
<move1> [ ponder <move2> ]
the engine has stopped searching
and found the move <move> best in this position.
the engine can send the move it
likes to ponder on. The engine must not start pondering automatically.
this command must always be sent
if the engine stops searching, also in pondering mode if there is a
"stop" command, so for
every "go" command a "bestmove" command is needed!
Directly before that the engine
should send a final "info" command with the final search information,
the the GUI has the complete
statistics about the last search.
*
copyprotection
this is needed for copyprotected
engines. After the uciok command the engine can tell the GUI,
that it will check the copy
protection now. This is done by "copyprotection checking".
If the check is ok the engine
should sent "copyprotection ok", otherwise "copyprotection
error".
If there is an error the engine
should not function properly but should not quit alone.
The code in the engine can look
like this
TellGUI("copyprotection
checking\n");
// ... check the copy protection here ...
if(ok)
TellGUI("copyprotection ok\n");
else
TellGUI("copyprotection
error\n");
* info
the engine wants to send infos
to the GUI. This should be done whenever one of the info has changed.
The engine can send only
selected infos and multiple infos can be send with one info command,
e.g. "info currmove e2e4
currmovenumber 1".
Also all infos belonging to the
pv should be sent together
e.g. "info depth 2 score cp 214 time 1242 nodes 2124 nps 34928 pv e2e4 e7e5 g1f3
I suggest to start sending
"currmove" and "currmovenumber" only after one second to
avoid traffic.
Additional info:
* depth <x>
search
depth in plies
* seldepth <x>
selective
search depth in plies,
if
the engine sends seldepth there must also a "depth" be present in the
same string.
* time <x>
the
time searched in ms, this should be sent together with the pv.
* nodes <x>
x
nodes searched, the engine should send this info regularly
* pv <move1> ...
<movei>
the
best line found
* multipv <num>
this
for the multi pv mode.
for
the best move/pv add "multipv 1" in the string when you send the pv.
in
k-best mode always send all k variants in k strings together.
* score
*
cp <x>
the score from the engine's
point of view in centipawns
*
mate <y>
mate in y moves
*
lowerbound
the score is just a lower bound
*
upperbound
the score is just an upper bound
* currmove <move>
currently
searching this move
* currmovenumber <x>
currently
searching move number x, for the first move x should be 1 not 0.
* hashfull <x>
the
hash is x permill full, the engine should send this info regularly
* nps <x>
x
nodes per second searched, the engine should send this info regularly
* tbhits <x>
x
positons where found in the endgame table bases
* cpuload <x>
the
cpu usage of the engine is x permill.
* string <str>
any
string str which will be displayed be the engine,
if
there is a string command the rest of the line will be interpreted as
<str>.
* option
This command tells the GUI which
parameters can be changed in the engine.
This should be sent once at
engine startup after the "uci" and the "id" commands
if any parameter can be changed
in the engine.
The GUI should parse this and
build a dialog for the user to change the settings.
If the user wants to change some
settings, the GUI will send a "setoption" command to the engine.
For all allowed combinations see
the example below,
as some combinations of this
tokens don't make sense.
One string will be sent for each
paramter.
* name <id>
The
option has the name id.
This
can be sent in any language, the GUI will take care of the translation.
Certain
options have a fixed value for <id>, which means that the semantics of
this option is fixed
*
<id> = Hash, type is spin
the value in MB for memory for
hash tables can be changed,
this should be answered with the
first "setoptions" command at program boot
if the engine has sent the
appropiate "option name Hash" command,
which should be supported by all
engines!
So the engine should use a very
small hash first as default.
*
<id> = NalimovPath, type string
this is the path on the harddisk
to the Nalimov compressed format.
Multiple directories can be
concatenated with ";"
*
<id> = NalimovCache, type spin
this is the size in MB for the
cache for the nalimov table bases
These last two options should
also be present in the initial options exchange dialog
when the engine is booted if the
engine supports it
*
<id> = Ponder, type check
this means that the engine is
able to ponder.
The GUI will send this whenever
pondering is possible or not.
Note: The engine should not
start pondering on its own if this is enables, this option is only
needed because the engine might
change its time management algorithm when pondering is allowed.
*
<id> = OwnBook, type check
if this is set, the engine takes
care of the opening book and the GUI will never
execute a move out of its book
for the engine.
*
<id> = MultiPV, type spin
the engine supports multi best
line or k-best mode. the default value is 1
* type <t>
The
option has type t.
There
are 5 different types of options the engine can send
*
check
a checkbox that can either be
true or false
*
spin
a spin wheel that can be an
integer in a certain range
*
combo
a combo box that can have
different predefined strings as a value
*
button
a button that can be pressed to
send a command to the engine
*
string
a text field that has a string
as a value,
an empty string has the value
"<empty>"
* default <x>
the
default value of this parameter is x
* min <x>
the
minimum value of this parameter is x
* max <x>
the
maximum value of this parameter is x
* var <x>
a
predefined value of this paramter is x
Example:
Here are 5 strings for each of the 5
possible types of options
"option name Nullmove type check default true\n"
"option name Selectivity type spin
default 2 min 0 max 4\n"
"option name Style type combo default Normal var Solid var
Normal var Risky\n"
"option name NalimovPath type string default c:\\n"
"option name Clear Hash type button\n"
Example:
--------
This is how
the communication when the engine boots can look like:
GUI engine
// tell the
engine to switch to UCI mode
uci
// engine
identify
id name Shredder 5
id
author Stefan MK
// engine
sends the options it can change
// the
engine can change the hash size from 1 to 128 MB
option
name Hash type spin default 1 min 1 max 128
// the
engine supports Nalimov endgame tablebases
option
name NalimovPath type string name c:\
option
name NalimovCache type spin default 1 min 1 max 32
// the
engine can switch off Nullmoves and set the playing style
option name Nullmove type check default true
option name Style type combo
default Normal var Solid var Normal var Risky
// engine
has sent all parameters and is ready
uciok
// Note:
here the GUI can already send a "quit" command if it just wants to
find out
// details about the engine, so the engine
should not initialize its internal
// parameters before here.
// now the
GUI sets some values in the engine
// set hash
to 32 MB
setoption
name Hash value 32
// init tbs
setoption
name NalimovCache value 1
setoption
name NalimovPath value d:\tb;c\tb
// waiting
for the engine to finish initializing
// this
command and the answer is required here!
isready
// engine
has finished setting up the internal values
readyok
// now we
are ready to go
// tell the
engine to search infinite from the start position after 1.e4 e5
position startpos moves e2e4 e7e5
go infinite
// the
engine starts sending infos about the search to the GUI
// (only
some examples are given)
info
depth 1 seldepth 0
info
score cp 13 depth 1 nodes 13 time 15 pv
f1b5
info
depth 2 seldepth 2
info
nps 15937
info
score cp 14 depth 2 nodes 255 time 15
pv f1c4 f8c5
info
depth 2 seldepth 7 nodes 255
info
depth 3 seldepth 7
info
nps 26437
info
score cp 20 depth 3 nodes 423 time 15
pv f1c4 g8f6 b1c3
info
nps 41562
....
// here the
user has seen enough and asks to stop the searching
stop
// the
engine has finished searching and is sending the bestmove command
// which is
needed for every "go" command sent to tell the GUI
// that the
engine is ready again
bestmove
g1f3 ponder d8f6