Hello, World! Link to heading

A technical overview of the software powering bgammon.org


Introduction Link to heading

In this post I share my experience with creating the bgammon.org server and client using free and open source tools. This includes Linux, the Go programming language and the VSCodium IDE.

While lots of free and open source backgammon software exists, all of the servers that were available in late 2023 were proprietary. I have enjoyed playing chess on Lichess for several years, and have always admired their model: free and open source, no ads, no paid benefits and no registration requirement. They say immitation is the sincerest form of flattery.

I created Boxcars, a graphical client for playing backgammon online, originally for the FIBS backgammon server in late 2021. The project was essentially feature-complete but never found a user base. Fast-forward two years to late 2023, and an idea for a project that has been brewing in the back of my head for some time begins to seem not just possible, but important: to make it possible to play backgammon online using free software.

I created bgammon, the server component of bgammon.org, and adapted Boxcars to connect to this new server instead. Using the insight I gained as a FIBS client author of things that work well and things that were (in my experience) difficult to understand or implement, I wrote the specification for a protocol that is inspired by FIBS while also being distinct in ways such as the use of a standard data interchange format (JSON) for messages sent by the server.

In the rest of this blog post, I will describe the more technical aspects of the creation of the bgammon.org server and client.

Server Link to heading

The server was created with efficiency in mind from the beginning. There are some low-hanging optimization fruits yet to be picked, but I have done my best to choose a data format and scheme which is efficient in its use of processor and memory resources. This is partly done just as good software design practice, but it is also important to make games and network traffic efficient because bgammon.org does not have any advertisements or sponsorships. The infrastructure for the server needs to be light-weight to keep the cost to the author as little as possible.

Therefore, the state of the board is stored as an array of integers, where the value of each cell specifies how many checkers are on a board space. Positive integers represent player 1 (black) and negative integers represent player 2 (white). This array is referenced and copied and mutated many times as the server evaluates all of the possible moves a player can make to determine which legal moves are available. In backgammon, if you can make a move that allows you to then make a second move, but you could instead make a move where you are only able to make one move and then end your turn, you are requred to make a move that allows you to then make a subsequent move.

Unlike chess, where spaces have the same name regardless of whether it is from white or black’s perspective of the board, backgammon spaces are numbered from the perspective of each player. This means when black moves 24/22, if white were to move in the opposite direction from black’s 22 to 24, white would perceive the move as 3/1. To simplify handling this, the server only stores the board state from the perspective of player 1, and flips the state sent to player 2 and moves received from player 2. Thus, the board is represented to player 2 appropriately without requiring duplication of logic everywhere the server analyzes the board state.

User commands consist of a single line of plain text, where the command is the first word of the line, and the command parameters make up the rest of the line. For instance, to connect, a client might send loginjson boxcars rocket9 s3cr3t to log in using a client named boxcars.

Server messages are sent to clients in JSON format. This makes it easy for clients to parse and validate data sent by the server. While it is a format designed to be used by computers, JSON is still very human-readable and it is not difficult to read and understand a log of bgammon.org network traffic.

Client Link to heading

The official client utilizes more libraries than any other project I have created. At the time of writing this blog post, it uses 12 libraries directly, several of which I authored to help facilitate creating Boxcars, and 41 additional libraries indirectly.

Ebitengine - Game engine Link to heading

Ebitengine is an incredible game engine. It is easy to use and understand, the API design is simple, and it compiles to an amazing number of platforms. This includes WebAssembly and Android, which is very appealing to any developer who wishes to target multiple platforms from a single code base.

messeji - Text display and input Link to heading

messeji is a library for drawing text on the screen as well as handling textual user input. It features an efficient word wrapping implementation that allows very large text buffer sizes even when running in a single-threaded context.

kibodo - On-screen keyboard Link to heading

kibodo is a library that allows applications running on touch-enabled devices to accept keyboard input. This library is necessary because toggling the system on-screen keyboard is not supported by Ebitengine.

etk - GUI tool kit Link to heading

etk is a library that simplifies the creation of graphical user interfaces. It provides a widget framework that makes focus and user input propagation far easier to manage compared to implementing custom logic everywhere it is needed in the application. etk provides several widgets out of the box, but also makes it possible to create custom widgets that integrate seamlessly with the official widgets. The Grid widget, for instance, allows the creation of flexible screen layouts that function across desktop and mobile platforms.

tabula - Backgammon AI Link to heading

tabula is a library that analyzes backgammon positions and attempts to determine the best move. It accomplishes this by performing a series of weighted calculations which I describe in detail on this page.

Sometimes it wins, but it only looks one step ahead in the game, while more powerful backgammon engines will usually look many more steps ahead. tabula doesn’t do this because that takes a long time. While I do my best to make tabula as challenging as possible, it is within the constraint of taking only a few seconds at most to determine the best move on a low-powered Android phone.

-Trevor Slocum 2024/01/01