Correct UCI ponder behaviour.

Discussion of chess software programming and technical issues.

Moderator: Ras

likeawizard
Posts: 37
Joined: Fri Aug 05, 2022 7:58 am
Full name: Arturs Priede

Correct UCI ponder behaviour.

Post by likeawizard »

I would like to clarify the exact ponder protocol with uci.
Say my engine was told to search a move and we have something like this: (with lines > indicating this is sent to the gui and < is sent from the gui to the engine)

Code: Select all

>bestmove e2e4 ponder e7e5
<position fen XXXX moves .... e2e4 d7e5 (sets up the position to ponder)
< go ponder wtime xx btime ....
At this point there can be two options either 'ponderhit' e7e5 was played or 'stop'. Another move was played.
So if ponderhit was sent to my understanding the gui will now wait for the engine to stop pondering and return a bestmove command...

Is it correct so far?

What if stop is called? Should the engine still emit 'bestmove' that it found pondering, that is kinda useless for the gui as the game did not progress that way or should it supress the bestmove on stop when pondering? stop silently and wait from the gui to feed it a new position and go command.
User avatar
hgm
Posts: 28353
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Correct UCI ponder behaviour.

Post by hgm »

The engine always must end a search by sending 'bestmove'. Even when the move is not to be used. The command also acts as confirmation that the engine has seen the stop command, so that any later output it sends can only be a result of later commands. Otherwise the theoretical possibility exists that the engine would still be sending output of the ponder search while the GUI has already sent the position-go for the next search, and would not know to which search the output belongs. Of course you could just put any random move in the bestmove command in that case.
User avatar
phhnguyen
Posts: 1524
Joined: Wed Apr 21, 2010 4:58 am
Location: Australia
Full name: Nguyen Hong Pham

Re: Correct UCI ponder behaviour.

Post by phhnguyen »

likeawizard wrote: Wed Nov 16, 2022 4:58 pm I would like to clarify the exact ponder protocol with uci.
Say my engine was told to search a move and we have something like this: (with lines > indicating this is sent to the gui and < is sent from the gui to the engine)

Code: Select all

>bestmove e2e4 ponder e7e5
<position fen XXXX moves .... e2e4 d7e5 (sets up the position to ponder)
< go ponder wtime xx btime ....
At this point there can be two options either 'ponderhit' e7e5 was played or 'stop'. Another move was played.
So if ponderhit was sent to my understanding the gui will now wait for the engine to stop pondering and return a bestmove command...

Is it correct so far?
Correct!
likeawizard wrote: Wed Nov 16, 2022 4:58 pm What if stop is called? Should the engine still emit 'bestmove' that it found pondering, that is kinda useless for the gui as the game did not progress that way or should it supress the bestmove on stop when pondering? stop silently and wait from the gui to feed it a new position and go command.
Your engine must return a bestmove ASAP. That is a rule by UCI protocol.

Once a chess GUI flags that it is waiting for a bestmove, it may ignore other commands from and postpone sending other tasks to your engine. It may consider your engine as being crashed without bestmove responding after a while.

If your engine can't produce the best move, you may use '0000' (as a null move) but using any legal move is much better.

In the case of BanksiaGUI, it may send "stop" to your engine when it is pondering if:
- The game is over: timeout for your engine; the rival crashed or resigned; users finished/closed/reset the game. The move of your bestmove is not important and will be ignored
- The user pressed the button "Move Now" (he doesn't want to wait any longer and wants the engine to make a move immediately). The move of your bestmove is useful and will be used
https://banksiagui.com
The most features chess GUI, based on opensource Banksia - the chess tournament manager
likeawizard
Posts: 37
Joined: Fri Aug 05, 2022 7:58 am
Full name: Arturs Priede

Re: Correct UCI ponder behaviour.

Post by likeawizard »

Thank you both for your answers.

Is there maybe a good reference for the UCI protocol that has such things explained in excruciating detail? I find that it can at times be a bit vague and seems like different GUIs have slightly different interpretations.
these are ones I found googling good references but at times they seem to lack explicit details like in my OP:

http://wbec-ridderkerk.nl/html/UCIProtocol.html
http://page.mi.fu-berlin.de/block/uci.htm

For example I was running my engine on cutechess and after any position command it would always send isready before issuing a go command. Howver, I am running my bot on lichess with their official bot client https://github.com/ShailChoksi/lichess-bot and it does not seem to be issuing the isready command after position. that means I need to implement some additional internal flag / check if my engine is ready to search and not setting up some options / position.
User avatar
hgm
Posts: 28353
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Correct UCI ponder behaviour.

Post by hgm »

I don't get that. An engine should always know when it finished processing a command it received, so it can start processing the next. The only processing 'isready' requires is printing 'readyok' without further delay. It should not affect the engine's state in any way. You print 'readyok', and continue with the next command.
likeawizard
Posts: 37
Joined: Fri Aug 05, 2022 7:58 am
Full name: Arturs Priede

Re: Correct UCI ponder behaviour.

Post by likeawizard »

That was my mistake. I was under the assumption that when the gui would send a command like setoption or position it would always follow it up with a isready as a 'blocking' call. I had set it up as all commands are executed in a separate thread and they would turn on a flag that would state it's in a not-ready state and I was counting on a isready command to be called that blocks until the flag is cleared and ready and then replies 'readyok'.

I now changed the code so that all / most. commands that can't be executed in parallel are waiting on the internal flag to proceed. Should be working in a more predictable manner now. But that's just me misunderstanding the uci protocol and expecting the gui to always validate the readiness before sending further commands.