As I wrote WatchBot, I am frequently asked How to write a FICS bot? This is the first of a few articles intended to give the detailed explanation.
It can be also of some interest for people wishing to write a FICS client interface (playing program), and maybe even for those wanting to write some program interacting with another telnet-based game server, be it ICC, WCL, or something else (as far as I know some go and backgammon servers also work similarly).
A bot concept
A bot is an automated program running on FICS (or ICC, or WCL, or IRC channel, or ....) to perform some task. There are many bots on FICS - Mamer is managing tourneys, Relay is transmitting grandmaster games, LectureBot is replaying lectures, TeamBot is handling consultation games, STCBunch helps manage slow-time tournaments etc. Bots are not playing, bots are not chatting (except replying to the commands), they just perform the tasks they were programmed to do.
Before you start writing your own bot, make sure that:
- you have some clear idea what do you want to achieve,
- your bot will be useful for other players and will fit the FICS purpose (do not forget that FICS is about playing chess)
- your bot won't waste server resources without a need.
Do not write a spam sender, do not write yet another massive game downloader, do not write a poker playing program. FICS is a great gift for chessplayers all around the world, respect it.
Interacting with FICS
Before we start coding, let's get some idea how are all programs (both bots and client interfaces) interacting with FICS.
If you are using Linux, run:
$ telnet freechess.org 5000
If you are on Windows, run Telnet program, and ask it to connect to freechess.org
. You will see something like this:
Trying 69.36.243.188...
Connected to freechess.org.
Escape character is '^]'.
_ __ __ __
| | / /__ / /________ ____ ___ ___ / /_____
| | /| / / _ \/ / ___/ __ \/ __ `__ \/ _ \ / __/ __ \
| |/ |/ / __/ / /__/ /_/ / / / / / / __/ / /_/ /_/ /
|__/|__/\___/_/\___/\____/_/ /_/ /_/\___/ \__/\____/
^^__ _____________________ _ _ _
/ - \_ / ____/ _/ ____/ ___/ _ | || || |
<| __< / /_ / // / \__ \ (_) |_______|
<| \ / __/ _/ // /___ ___/ / _ \__ ___ /
<| \ /_/ /___/\____//____/ (_) |___|_|
<|______\ |_|___|
_|____|_ ====================================== |___|_|
(________) freechess.org ---- 69.36.243.188 (_______)
/________\ ====================================== /_______\
(Login screen designed by Alefith)
****** Welcome to the Free Internet Chess Server at freechess.org ******
Webpage: http://www.freechess.org
Head admin : Chessty Complaints to : [email protected]
Server location: freechess.org Server version : 1.25.17
If you are not a registered player, enter guest or a unique ID.
(If your return key does not work, use cntrl-J)
login:
Enter guest
and confirm logging in as guest, or - if you prefer - enter your normal FICS nickname and password. If logged as guest, you will be bombarded with seek ads. Type
set seek 0
and press Enter to ged rid of them. You will see sth like this:
GuestSLCJ (++++) seeking 5 0 unrated blitz f ("play 49" to respond)
fics%
GuestBXBD (++++) seeking 1 0 unrated lightning ("play 63" to respond)
fics% set seek 0
You will not see seek ads.
fics%
Try issuing some commands. For example, type help
and press Enter, type who
and press Enter, type games
and press Enter, type tell mamer help
and press Enter, type sought
and press Enter.
This is exactly what both bots and client interfaces do. They make telnet connection to FICS, then exchange text messages with the server. When you ask BabasChess to display your game history, it just sends a history
command, awaits reply, parses it, and displays the results in a popup window. When you have a seek table displayed, your playing program either issues sought
periodically, or issues set seek 1
and then updates the window whenever it receives a seek ad.
Pick some number from the games
list and issue command like observe 360
. You should see sth like:
You are now observing game 360.
Game 360: AEGC (2016) chessbadboy (2156) rated standard 15 60
Game 360 (AEGC vs. chessbadboy)
---------------------------------
8 | | | | | | | | | Move # : 39 (Black)
|---+---+---+---+---+---+---+---|
7 | *P| | | | | | R | | White Moves : 'Kh2 (0:00)'
|---+---+---+---+---+---+---+---|
6 | | | | | | | *P| |
|---+---+---+---+---+---+---+---|
5 | | | | | | | | | Black Clock : 21:19
|---+---+---+---+---+---+---+---|
4 | | P | | | | P | | P | White Clock : 23:08
|---+---+---+---+---+---+---+---|
3 | | | | | | *K| | P | Black Strength : 7
|---+---+---+---+---+---+---+---|
2 | | | | | | | | K | White Strength : 9
|---+---+---+---+---+---+---+---|
1 | *R| | | | | | | |
---------------------------------
a b c d e f g h
Yes, it is the oldest way of playing on FICS, this is how people played before client interfaces were written. Watch for a moment (whenever some player makes a move, you would see a new board), then issue
unobserve
If you are brave, you can try playing a game using this interface. Either match some colleague (issue command like match Mekk
) or issue sought
, pick one of the offers and issue command like play 27
. To make a move, issue a command like
e2-e4
(or e2e4
, or e4
, FICS is rather forgiving). During a game you may need commands like resign
, draw
(draw offer), say Some Thing
(chat with opponent), accept
(accept opponent offer).
Started to understand what is happening here?
For automated programs another way of sending the board positions is more suitable. Issue command
set style 12
and then start observing some game (observe 97
for example). You should see something like:
You are now observing game 197.
Game 197: chessbadboy (2146) SevenChecks (2132) rated standard 60 0
<12> rnbqk--r ppp--ppp -----n-- ---p--N- --P-p--- B-P---P- P--PPP-P R--QKB-R B -1 1 1 1 1 1
197 chessbadboy SevenChecks 0 60 0 36 36 3511 3086 7 B/c1-a3 (0:45) Ba3 0 1 0
The somewhat cryptic text starting with <12>
denotes the position on the board, clock status and all other game characteristics. We will discuss it later.
Simplest interfaces - Winboard and XBoard - are doing very little except:
spotting lines starting with
<12>
in the text sent from FICS, filtering them out from the text sent to the user console, parsing them and updating the graphical board according to the information received,accepting moves made on the graphical board and sending them to FICS as commands.
Issue some more commands, then end the session with quit
.
Note Do not forget about the telnet program. Running sessions like this one is the best way to check how exactly is FICS behaving in different situations, to grab and save example notifications or replies, to test your command syntax.
Tool selection - which language to use
There is no single best tool to write FICS bots and interfaces. People were writing them in C, C++, Java, Perl, Python - and probably more. Whichever tool you pick, it should provide you with:
A telnet client library
While handling telnet manually is not hopelessly difficult, there is no point in loosing time on this.
Good support for regular expressions
Noticeable part of a bot code is about parsing text sent by FICS and extracting data from it. Regular expressions proved to be the best tool for the job.
If you do not know what regular expressions are or are afraid of them, take a break, learn them, and then come back. There is an excellent book Mastering Regular Expressions available.
Good support for asynchronous code execution
You could already spot it - FICS does not sync with you. Notifications, tells, announcements, moves may come at any moment, whatever is your program doing. You may issue some command and get two seek ads, some tell and only then the reply to this command. If you want to be responsive, you should not stop listening to tells while performing some calculation. And so on.
My preferences
A trivial bot can survive without truly solving this problem (your networking library will buffer FICS messages while you are busy, some applications do not need to match replies with commands issued), but more advanced tools must either use threads, or some asynchronous processing model.
My personal preferences are:
-
Perl with Net::Telnet module for simple tasks (like old TeamChess tool which logged to FICS to grab players rating, or old OCL bot which worked just to send announcements to selected channels)
-
Python with Twisted framework for complicated bots (this is how WatchBot is written)
There will be code examples in those two languages in my articles.
Bot hosting (or where do they run)
Bots do not need to run on the FICS computer. In fact, my bots have been running either on my home Linux PC, or on VPS server I rent. This is also the way you are most likely to run your bots.
Some most important bots (like Mamer) are running on the same computer on which FICS server is running, but this is just an optimization, to ensure no network problems or delays.
Bot accounts
Bots are usually developed and tested using guest account. Only after they start doing something useful, it is a time to approach FICS administration staff and ask for the bot account (you should prepare some description of what is the bot to do, and why is it to be useful for FICS, and be ready to support it).
Some bots (namely those, which do not interact with players) do not need an account at all. If the bot is not receiving commands (tells) from players, it does not need a persistent name.
Summary
This should be enough for the first lesson. I hope you get some basic understanding of how FICS works and can be interacted.
In the next lesson, I will start giving some code examples.