Rejecting xboad features

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Fulvio
Posts: 395
Joined: Fri Aug 12, 2016 8:43 pm

Rejecting xboad features

Post by Fulvio »

I was looking at pychess code for the xboard protocol:
https://github.com/niklasf/python-chess ... e.py#L1615

I am confused about what is the expected outcome of rejecting a feature.
For example:
the engine sends "feature reuse=0"
the GUI/controller replies "reject reuse"
or
engine >> "feature usermove=1"
controller >> "reject usermove"
and then is the engine supposed to accept the moves even if they are not prefixed with "usermove"?
User avatar
hgm
Posts: 27788
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Rejecting xboad features

Post by hgm »

There are no official specs for this, but I suppose there are some features the GUI is not supposed to reject. A sort of a minimum requirement for protocol v2 support. There isn't any real alternative; reuse=0 basically notifies the GUI of an engine defect: that it does not properly react to the 'new' command to start a second game, and has to be restarted as a work-around. If the engine could play multiple games, there would have been no need for it to say reuse=0 in the first place. A GUI that doesn't support restarting the engine, but tries to make it play a second game, simply cannot run such an engine. So I suppose the alternative would be to unload the engine, and present the user with an error message that this engine is not fit for running with this GUI. Telling the engine the option was rejected is not helpful. Unless you would expect the engine to quit in that case with a tellusererror message.

So I would say that a GUI should only send 'protover 2' in the first place if it provides all 'essential features', such as reuse=0, usermove=1, setboard=1, draw=0, sigint=0, sigtem=0. Requiring engines that request 'usermove' to also support parsing of bare moves would completely defeat the purpose, as the usermove command was introduced for no other reason than to simplify move parsing by the engine.

When a feature gets rejected for which the engine requested the default value, the engine can always ignore the reject, because compliant GUIs must use the default method if they offer no choice. Otherwise engines that do no specify the feature relying on the default value would be treated wrong without ever receiving a 'rejected' command.

There are also features that specify whether the GUI can send some commands that did not exist in earlier versions of the protocol. Such as ics, name, playother, ping, memory, smp, egt. If you requested their sending against the default, but get rejected because they are not implemented in the GUI, you will simply not get those commands. If the commands were supposed to supply some essential information, like for 'memory' or 'smp', you better make sure suitable defaults are used when they get rejected. (E.g. hard-coded, or reading from a config file.) It is conceivable that you normally start the engine with minimal hash (say 1MB) awaiting the desired setting, so that you don't have to re-allocate large chuncks of memory. It is conceivable that you might want to reallocate a more reasonable size (like 64MB) when 'reject memory' tells you no 'memory' command will be forthcoming.

When you requested suppressing commands that by default would be sent (e.g. name, colors, time), the best way would be to ignore those commands. That doesn't seem very much to ask. (But I guess that when you would do that, there would not have been a reason to ask for their suppression). Of course it isn't very much to ask from the GUI either to suppress those commands on request. In any case, you should make sure your engine would not crash on any command that it doesn't know.

Rejection of 'option' features should usually not be a cause for concern, if the engine uses proper defaults (possibly configurable through a config file).

Of course receiving 'protover 1' would count as a sort of advance rejection of any feature you had intended to send. Not receing protover as the first thing you receive after 'xboard', likewise. But I guess things also depend on whether you want the engine to be able to run under v1 of the protocol. The whole feature mechanism was designed to allow newer, enhanced GUIs to keep running older engines. It seems acceptable for an engine author to specify his engine is v2 only.
Fulvio
Posts: 395
Joined: Fri Aug 12, 2016 8:43 pm

Re: Rejecting xboad features

Post by Fulvio »

hgm wrote: Thu May 07, 2020 10:08 am Rejection of 'option' features should usually not be a cause for concern, if the engine uses proper defaults (possibly configurable through a config file).
Thanks for the detailed explanation.
Honestly it is a bit of a mess, I suppose it is the result of many adjustment over the years.
I think I'll just do what cutechess does:
https://github.com/cutechess/cutechess/ ... e.cpp#L484
Accept few options and reject everything else (including draw, sigint, sigtem).
"reuse" and "time" are true by default, everything else defaults to false.
I think most of engine authors would have used cutechess for testing (btw there is a list of active xboard engines?)
User avatar
hgm
Posts: 27788
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Rejecting xboad features

Post by hgm »

I think part of the mess is due to an attempt to cater to existing non-compliant engines. For instance, it makes no sense at all to suppress sending of certain commands; the specs require the engine to respond with "Unknown command..." to any such command, and GUIs usually ignore that anyway. So why should sending of time/otim be suppressible by the non-default feature time=0 ? It only makes sense if the engine does implement a time command that has a different meaning, and provide an easy fix for that by just printing one extra line at startup. (One suspects GNU Chess in such cases...)

The whole system was designed to prevent exposing engines to commands that did not exist yet when these engines were written, and later abused for other purposes. (Such as requesting work-arounds that otherwise would have to be requested by the user from the GUI directly (reuse).) It would have been much better to simply require the engines to be fixed instead of allowing them to request a work-around. Perhaps the idea was that anyone could add a printf statement for a feature line in an open source engine, without any knowledge of the engine's inner workings.

At least there is a reason for suppressing the draw command, as it used to be relayed instantly, and could thus arrive when the engine was thinking. Simple implementations of handling input during search were not resistant to that, and the feature was provided for those to protect themselves from commands during search that were not intended to terminate the search instantly. Of course for a GUI that doesn't relay draw offers in the first place, the feature is meaningless.

To not implement sigint=0 and sigterm=0 is a GUI bug. It would make most engines crash under Linux on their first move if the GUI sent them a sigint. When you never send sigint, other engines could hang when pondering, because they rely on sigint to terminate the ponder search and start looking for input. I suppose CuteChess gambles on the latter type not being common anymore (as there is no such thing as signals on Windows, and most authors would also want their engine to work on Windows), and in violation of the specs never sends sigint. Or perhaps it provides a GUI option for the user to specify use of sigint.

The remaining features I mentioned as 'essential' all seem to be supported.