The UCI protocol as publicised by Stefan-Meyer Kahlen (ShredderChess)
-
The specification is independent of the operating system. For Windows, the engine is a normal exe file, either a console or a “real” windows application.
-
All communication is done via standard input and output with text commands.
-
The engine should boot and wait for input from the GUI, the engine should wait for the
isreadyorsetoptioncommand 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.Note:
\ncan be0x0cor0x0a0cor any combination depending on your OS. If you use the engine and GUI in the same OS there should be no problem if you communicate in text mode, but be aware of this when for example running a Linux engine in a Windows GUI. -
The engine will always be in forced mode which means it should never start calculating or pondering without receiving a
gocommand first. -
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.
-
By default, all the opening book handling is done by the GUI, but there is an option for the engine to use its own book (
OwnBookoption, see below) -
If the engine or the GUI receives an unknown command or token it should just ignore it and try to parse the rest of the string.
-
If the engine receives a command which is not supposed to come, for example
stopwhen the engine is not calculating, it should also just ignore it.
Move format:
The move format is in long algebraic notation.
A null move from the Engine to the GUI should be sent as 0000.
Examples: e2e4, e7e5, e1g1 (white short castling), e7e8q (for promotion)
GUI to engine:
These are all the command the engine gets from the interface.
-
uciTell engine to use the uci (universal chess interface), this will be sent 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
idcommand and sendoptioncommands to tell the GUI which engine settings the engine supports if any. After that the engine should senduciokto acknowledge the uci mode. If nouciokis 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 send additional infos to the GUI, e.g. with the
info stringcommand, to help debugging, e.g. the commands that the engine has received etc. This mode should be switched off by default and this command can be sent any time, also when the engine is thinking. -
isreadyThis 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
readyokand can be sent also when the engine is calculating in which case the engine should also immediately answer withreadyokwithout stopping the search. -
setoption name [value]This is sent to the engine when the user wants to change the internal parameters of the engine. For the
buttontype no value is needed. One string will be sent for each parameter and this will only be sent when the engine is waiting. The name of the option in should not be case-sensitive and can include spaces like also the value. The substringsvalueandnameshould be avoided in and to allow unambiguous parsing, for example do not use “draw value”. 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 -
registerThis is the command to try to register an engine or to tell the engine that registration will be done later. This command should always be sent if the engine has sent
registration errorat program startup. The following tokens are allowed:-
laterThe user doesn’t want to register the engine now
-
nameThe engine should be registered with the name
-
codeThe engine should be registered with the code
Example:
register later register name Stefan MK code 4359874324
-
-
ucinewgameThis is sent to the engine when the next search (started with
positionandgo) will be from a different game. This can be a new game the engine should play or a new game it should analyse but also the next position from a testsuite with positions only. If the GUI hasn’t sent anucinewgamebefore the firstpositioncommand, the engine shouldn’t expect any furtherucinewgamecommands as the GUI is probably not supporting theucinewgamecommand. So the engine should not rely on this command even though all new GUIs should support it. As the engine’s reaction toucinewgamecan take some time the GUI should always sendisreadyafterucinewgameto wait for the engine to finish its operation. -
position [fen | startpos] moves ...Set up the position described in a FEN string on the internal board or play the specified moves on the internal chess board. If the game was played from the start position the string
startposwill be sentNote: no
newcommand is needed. However, if this position is from a different game than the last position sent to the engine, the GUI should have sent anucinewgamein between. goStart calculating on the current position set up with thepositioncommand. 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 ...movesRestrict search tomovesmoves onlyExample: After
position startposandgo infinite searchmoves e2e4 d2d4, the engine should only search the two moves e2e4 and d2d4 in the initial position. -
ponderStart searching in pondering mode.Do not exit the search in ponder mode, even if it’s mate! This means that the last move sent in the position string is the move to ponder. The engine can do what it wants to do, but after a
ponderhitcommand it should execute the suggested move to ponder on. This means that the move to ponder sent by the GUI can be interpreted as a recommendation about which move to ponder. However, if the engine decides to ponder on a different move, it should not display any mainlines as they are likely to be misinterpreted by the GUI because the GUI expects the engine to ponder on the suggested move. wtimeWhite hasxms left on the clockbtimeBlack hasxms left on the clockwincWhite increment per move in ms ifx> 0bincBlack increment per move in ms ifx> 0movestogoThere arexmoves to the next time control, this will only be sent ifx> 0, if you don’t get this and get thewtimeandbtimeit’s sudden deathdepthSearchxplies only.nodesSearchxnodes only,mateSearch for a mate inxmovesmovetimeSearch exactlyxmsinfiniteSearch until thestopcommand. Do not exit the search without being told so in this mode!
-
-
stopStop calculating as soon as possible, don’t forget the
bestmoveand possibly thepondertoken when finishing the search -
ponderhitThe user has played the expected move. This will be sent if the engine was told to ponder on the same move the user has played. The engine should continue searching but switch from pondering to normal search.
-
quitQuit the program as soon as possible
Engine to GUI:
id-
nameThis must be sent after receiving the
ucicommand to identify the engine, e.g.id name Shredder X.Y\n -
authorThis must be sent after receiving the
ucicommand to identify the engine, e.g.id author Stefan MK\n
-
-
uciokMust 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.
-
readyokThis must be sent when the engine has received an
isreadycommand 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 withisready. -
bestmove [ponder]The engine has stopped searching and found the best move 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
stopcommand, so for everygocommand abestmovecommand is needed! Directly before that the engine should send a finalinfocommand with the final search information, the GUI has the complete statistics about the last search. -
copyprotectionThis is needed for copy-protected engines. After the
uciokcommand the engine can tell the GUI, that it will check the copy protection now. This is done bycopyprotection checking. If the check is ok the engine should sendcopyprotection ok, otherwisecopyprotection error. If there is an error the engine should not function properly but should not quit alone. If the engine reportscopyprotection error, the GUI should not use this engine and display an error message instead! The code in the engine can look like thisTellGUI("copyprotection checking\n"); // ... check the copy protection here ... if (ok) TellGUI("copyprotection ok\n"); else TellGUI("copyprotection error\n"); -
registrationThis is needed for engines that need a username and/or a code to function with all features. Analog to the
copyprotectioncommand the engine can sendregistration checkingafter theuciokcommand followed by eitherregistration okorregistration error. Also, after every attempt to register the engine it should answer withregistration checkingand then eitherregistration okorregistration error. In contrast to thecopyprotectioncommand, the GUI can use the engine after the engine has reported an error, but should inform the user that the engine is not properly registered and might not use all its features. In addition, the GUI should offer to open a dialog to enable registration of the engineTo try to register an engine the GUI can send the
registercommand. The GUI has to always answer with theregistercommand if the engine sendsregistration errorat engine startup (this can also be done withregister later) and tell the user somehow that the engine is not registered. This way the engine knows that the GUI can deal with the registration procedure and the user will be informed that the engine is not properly registered. -
infoFor the engine 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 sent with one info command, e.g.
info currmove e2e4 currmovenumber 1 info depth 12 nodes 123456 nps 100000Also, 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 g1f3It is suggested to start sending
currmove,currmovenumber,currlineandrefutationonly after one second to avoid too much traffic. Additional info:-
depthSearch depth in plies
-
seldepthSelective search depth in plies, must always be sent together with
depth -
timeThe time searched in ms, this should be sent together with the pv.
-
nodesxnodes searched, the engine should send this info regularly -
pv <move>...The best move(s) found
-
multipvThis for the multi pv mode. For the best move/pv add
multipv 1in the string when you send the pv. In k-best mode always send all k variants in k strings together. scorecp- the score from the engine’s point of view in centipawns.mate- mate in y moves, not plies. If the engine is getting mated use negative values for y.lowerbound- the score is just a lower bound.upperbound- the score is just an upper bound.
-
currmoveCurrently searching this move
-
currmovenumberCurrently searching mov number x, for the first move x should be 1 not 0.
-
hashfullThe hash is
xpermill full, the engine should send this info regularly -
npsThe engine is searching at a rate of
xnodes per second, this info should be sent regularly -
tbhitsxpositions where found in the endgame table bases -
cpuloadThe cpu usage of the engine is
xpermill. -
stringAny string str which the engine would like the GUI to display, the rest of the line will be interpreted as the string to display
-
refutation <move> ...[refutation]<move>is refuted by the move<refutation>.Example: after move d1h5 is searched, the engine can send
info refutation d1h5 g6h5if g6h5 is the best answer afterd1h5isg6h5or ifg6h5refutes the moved1h5. If there is no refutation for d1h5 found, the engine should just sendinfo refutation d1h5Note: The engine should only send this if the option
UCI_ShowRefutationsis set to true. -
currline ...This is the current line the engine is calculating. is the number of the cpu if the engine is running on more than one cpu. If the engine is just using one cpu, this can be omitted. There is more than one current line, the engine should always send all k lines in k strings together.
Note: The engine should only send this if the option
UCI_ShowCurrLineis set to true.
-
-
optionThis command tells the GUI which parameters can be changed in the engine. This should be sent once at engine startup after the
uciand theidcommands 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. Note that not every option needs to appear in this dialog as some options likePonder,UCI_AnalyseMode, etc. are better handled elsewhere or are set automatically. If the user wants to change some settings, the GUI will send asetoptioncommand to the engine.Note that the GUI need not send the
setoptioncommand when starting the engine for every option if it doesn’t want to change the default value. For all allowed combinations see the example below, as some combinations of these tokens don’t make sense.One
optionstring will be sent for each parameter.nameThe option has the name id. Certain options have a fixed value, which means that the semantics of this option is fixed. Usually those options should not be displayed in the normal engine options window of the GUI but get a special treatment.Ponderfor example should be set automatically when pondering is enabled or disabled in the GUI options. The same forUCI_AnalyseModewhich should also be set automatically by the GUI. All those certain options have the prefixUCI_except for the first 6 options below. If the GUI get an unknown Option with the prefixUCI_, it should just ignore it and not display it in the engine’s options dialog.-
Hash, typespinThe value in MB for memory for hash tables can be changed, this should be answered with the first
setoptionscommand at program boot if the engine has sent the appropriateoption name Hashcommand, which should be supported by all engines! So the engine should use a very small hash first as default. -
NalimovPath, typestringThis is the path on the hard disk to the Nalimov compressed format. Multiple directories can be concatenated with “;”
-
NalimovCache, typespinThis 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
-
Ponder, typecheckThis 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 enabled, this option is only needed because the engine might change its time management algorithm when pondering is allowed.
-
OwnBook, typecheckThis means that the engine has its own book which is accessed by the engine itself. 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. If this is set to false by the GUI, the engine should not access its own book.
-
MultiPV, typespinThe engine supports multi best line or k-best mode. the default value is 1
-
UCI_ShowCurrLine, typecheck, should befalseby defaultThe engine can show the current line it is calculating. see
info currlineabove. -
UCI_ShowRefutations, typecheck, should befalseby defaultThe engine can show a move and its refutation in a line. see
info refutationsabove. -
UCI_LimitStrength, typecheck, should befalseby defaultThe engine is able to limit its strength to a specific Elo number, This should always be implemented together with
UCI_Elo. -
UCI_Elo, typespinThe engine can limit its strength in Elo within this interval. If UCI_LimitStrength is set to false, this value should be ignored. If UCI_LimitStrength is set to true, the engine should play with this specific strength. This should always be implemented together with
UCI_LimitStrength. -
UCI_AnalyseMode, typecheckThe engine wants to behave differently when analysing or playing a game. For example when playing it can use some kind of learning. This is set to false if the engine is playing a game, otherwise it is true.
-
UCI_Opponent, typestringWith this command the GUI can send the name, title, elo and if the engine is playing a human or computer to the engine. The format of the string has to be
[GM|IM|FM|WGM|WIM|none] [<elo>|none] [computer|human]Example:setoption name UCI_Opponent value GM 2800 human Gary Kasparow setoption name UCI_Opponent value none none computer Shredde
-
-
typeThe type of the option. There are 5 different types of options the engine can send:
Type Description checka checkbox that can either be true or false spina spin wheel that can be an integer in a certain range comboa combo box that can have different predefined strings as a value buttona button that can be pressed to send a command to the engine stringa text field that has a string as a value, an empty string has the value “” defaultThe default value of this parametermin- the minimum value of this parametermax- the maximum value of this parametervar- a predefined value of this parameter
Example:
Here are 5 strings for each of the 5 possible types of options
Type Example Option checkoption name Nullmove type check default truespinoption name Selectivity type spin default 2 min 0 max 4combooption name Style type combo default Normal var Solid var Normal var Riskybuttonoption name Clear Hash type buttonstringoption name NalimovPath type string default c:\chess\tb
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
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 default
option name NalimovCache type spin default 1 min 1 max 32
// the engine can switch off Nullmove 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
// the 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
// if the GUI is supporting it, tell the engine that is is
// searching on a game that is hasn't searched on before
ucinewgame
// if the engine supports the "UCI_AnalyseMode" option and the next search is supposted to
// be an analysis, the GUI should set "UCI_AnalyseMode" to true if it is currently
// set to false with this engine
setoption name UCI_AnalyseMode value true
// 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