Using engines running outside of the browser

Last update: May 11, 2022

External engine (ALPHA)

Using engines running outside of the browser on https://lichess.org/analysis.

Work in progress 🔧 🔨

  • Implement MVP
  • Complete lichess-org/lila#10867
  • Implement safe-uci adapter
  • Build easily installable local providers

Official providers

remote-uci

Reference implementation in Rust. Cross platform command line application wrapping an UCI engine. Secure, but not robust against denial of service.

Minimal GUIs with bundled Stockfish for Linux, Windows and Mac

Planned

Protocol (still subject to change)

Overview

Lichess provides a reference implementation for an external engine provider. Third parties can also implement their own engine providers.

An external engine provider is a WebSocket server. To inform the client about the connection details, it triggers a navigation to an authorization endpoint, where the user can confirm that their client should use the given engine provider. The client will then open a WebSocket connection for each session with a chess engine.

The client sends UCI commands as text messages over the WebSocket connection. Each command is sent in its own WebSocket message, containing no line feeds or carriage returns.

The provider responds as if the client were exclusively communicating with a UCI engine, by sending UCI commands as individual WebSocket messages. copyprotection and registration are not supported.

Important considerations for providers

The most straight-forward implementation would be to forward all WebSocket messages to a UCI engine as a thin proxy. However, some important considerations arise that require dealing with UCI specifics and tracking the engine state.

  • ⚠️ With many engines, a malicious user who can execute arbitrary commands will be able to damage the host system, cause data loss, exfiltrate data, or even achieve arbitrary code execution.

    Recommendation: Use the safe-uci adapter as a wrapper around UCI engines. If possible, bind the server only on the loopback interface to limit the attack surface. Generate a strong secret for the engine registration and do not forget to check it.

  • Analysis is resource intensive. Be sure to put limits on CPU and memory usage and inforce them, in order for your system to stay responsive.

  • Network connections can be interrupted.

    Recommendation: Send pings over all WebSocket connections at intervals. If a client times out or disconnects, stop ongoing searches in order to prevent deep or infinite analysis from consuming resources indefinitely.

  • Clients may open multiple connections.

    Recommendation: Manage shared access to a single engine process. At each point, one of the WebSocket connections has an exclusive session with the engine. Track the engine state and options associated with each session.

    When receiving a message (except stop) on a connection, an exclusive session is requested for that connection. In order to switch sessions, end any ongoing search in the previous session (by injecting stop) and wait until any outstanding engine output has been delivered. Then issue ucinewgame, to ensure the following session is clean, and reapply any options associated with the session.

Register external engine

To inform the client about connection details, trigger a navigation to

https://lichess.org/analysis/external

with the following query parameters:

name default example description
url required ws://localhost:9670/ URL of the provider server. External engine registrations are stored in local storage, so this may refer to localhost without breaking on other devices.
secret required A secret token that the client should include in every connection request.
name required Stockfish 15 Short engine or provider name to show on the client.
maxThreads 1 8 Maximum number of threads supported for setoption name Threads .... Make sure to respect limits of the engine as well as the machine.
maxHash 16 1024 Maximum number of memory supported for setoption name Hash ... (MiB). Make sure to respect limits of the engine as well as the machine.
variants chess,atomic Comma-separated list of variants supported by setoption name UCI_Variant ..., if any.

Accepting connections

The client will open WebSocket connections to the url as provided in the registration above. It will set the following additional query parameters:

name description
secret The secret token as provided in the registration above. The provider must check and reject connection attempts if the token does not match.
session Each new tab or session will have a different identifier. Reconnections will reuse the identifier.

Engine requirements

To properly work on the Lichess analysis board, engines must support:

  • UCI_Chess960
  • MultiPV
  • info with
    • depth (reaching 6 must be fast)
    • multipv
    • score
    • nodes (with order of magnitude comparable to Stockfish)
    • time
    • pv

GitHub

https://github.com/lichess-org/external-engine
You might also like...

Modrinth API is a simple library for using, you guessed it, the Modrinth API in Rust projects

Modrinth API is a simple library for using, you guessed it, the Modrinth API in Rust projects. It uses reqwest as its HTTP(S) client and deserialises responses to typed structs using serde.

May 24, 2022

Some tools for streaming frames to rpi-rgb-led-matrix using ZeroMQ, written in Rust.

led_matrix_zmq Some tools for streaming frames to rpi-rgb-led-matrix using ZeroMQ, written in Rust. This repository includes: Rust client and server l

Nov 7, 2021

A translation of Brendan Galea's Vulkan tutorial into Rust using the ash crate

A translation of Brendan Galea's Vulkan tutorial into Rust using the ash crate

Rust Light Vulkan Engine This is a translation of Brendan Galea's Vulkan tutorial into rust using the Ash crate. Original tutorial: Brendan Galea's Yo

Jan 12, 2022

Cross-platform GUI written in Rust using ADB to debloat non-rooted android devices

Cross-platform GUI written in Rust using ADB to debloat non-rooted android devices

Cross-platform GUI written in Rust using ADB to debloat non-rooted android devices. Improve your privacy, the security and battery life of your device.

May 26, 2022

This contract implements simple vote for the best coffe in indonesia using near protocol.

vote-coffe-near Description This contract implements simple vote for the best coffe in indonesia using near protocol. Contract in contract/src/lib.rs

Nov 15, 2021

Telegram bot for searching in Arch User Repository ( AUR ); Implemented using rust.

AurSearchBot A Telegram Inline Search Bot Written in Rust Introduction Telegram Bot that can search AUR ( Arch User Repository ) in inline mode. This

Feb 15, 2022

A custom frontend for the TradeOgre exchange, written using Iced

Forest A custom frontend for the TradeOgre exchange, written using Iced. Why TradeOgre? It's a simple, non-KYC exchange that I found out about recentl

Jan 16, 2022

Simple async library for triggering IFTTT events using webhooks.

IFTTT Webhook A simple Rust async library for triggering IFTTT events using webhooks. Installation Installation can be performed using cargo add: carg

Mar 11, 2021

An experimental Discord bot using Serenity.

VoidBot An experimental Discord bot using Serenity. Environment Variables Can be set with a .env file. DISCORD_TOKEN: The token for your bot. (require

May 21, 2022
Comments
  • 1. Fix the parsing of spin options

    This patch fixes the parsing of the Threads and Hash options by skipping all tokens not matching b"max", and then skipping the token itself before parsing the max value.

    Reviewed by mhouppin at 2022-05-16 11:00
  • 2. no method named `as_slice` found for struct `std::slice::Split`

    ❯ rustup update
    info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
    
      stable-x86_64-unknown-linux-gnu unchanged - rustc 1.60.0 (7737e0b5c 2022-04-04)
    
    info: cleaning up downloads & tmp directories
    ❯ cargo run --release -- stockfish
       Compiling remote-uci v0.1.0 (/home/thib/external-engine/remote-uci)
    error[E0599]: no method named `as_slice` found for struct `std::slice::Split` in the current scope
       --> src/engine.rs:117:72
        |
    117 |                         info.name = Some(String::from_utf8_lossy(parts.as_slice()).into_owned())
        |                                                                        ^^^^^^^^ method not found in `std::slice::Split<'_, u8, [[email protected]/engine.rs:113:40: 113:67]>`
    
    error[E0599]: no method named `trim_ascii_start` found for reference `&[u8]` in the current scope
      --> src/engine.rs:24:18
       |
    24 |                 .trim_ascii_start()
       |                  ^^^^^^^^^^^^^^^^ method not found in `&[u8]`
    
    error[E0599]: no method named `trim_ascii_start` found for reference `&[u8]` in the current scope
      --> src/engine.rs:51:18
       |
    51 |                 .trim_ascii_start()
       |                  ^^^^^^^^^^^^^^^^ method not found in `&[u8]`
    
    For more information about this error, try `rustc --explain E0599`.
    error: could not compile `remote-uci` due to 3 previous errors
    ❯ rustc --version
    rustc 1.60.0 (7737e0b5c 2022-04-04)
    
    Reviewed by ornicar at 2022-05-07 08:30
A thread pool for running multiple tasks on a configurable group of threads.
A thread pool for running multiple tasks on a configurable group of threads.

Threadfin A thread pool for running multiple tasks on a configurable group of threads. Extra features: Dynamic pool size based on load Support for asy

May 7, 2022
Web Browser Engineering

This is a port of Web Browser Engineering series from Python to Rust done by Korean Rust User Group.

May 3, 2022
Play Onitama in your browser, compete with friends or lose to a bot

Play Onitama in your browser, compete with friends or lose to a bot

Apr 6, 2022
dm-jitaux is a Rust-based JIT compiler using modified auxtools, dmasm and Inkwell LLVM wrapper for boosting Byond DM performance without any hassle!

dm-jitaux is a Rust-based JIT compiler using modified auxtools, dmasm and Inkwell LLVM wrapper for boosting Byond DM performance without any hassle (such as rewriting/refactroing your DM code).

May 3, 2022
A Simple, But amazing telegram bot, Made using the Rust language!

Telegram bot in Rust A fun Telegram bot made using Rust language.

Dec 21, 2021
Rust bindings to Cloudflare Worker KV Stores using wasm-bindgen and js-sys.

worker-kv Rust bindings to Cloudflare Worker KV Stores using wasm-bindgen and js-sys

May 14, 2022
Showing how to deploy a Terra smart contract using Chainlink Data Feeds

Chainlink Terra Developing Requirements This demo requires the following components: Rust: rustup with cargo 1.44.1+. rustc and cargo 1.44.1+. Install

Apr 10, 2022
Private swaps for Secret Network using a private entropy pool & differential privacy.

WIP SecretSwap: Anon Edition Private swaps for Secret Network! Uses private entropy pool for differential privacy when reporting pools sizes. Swap amo

Apr 5, 2022
A template for kick starting a Cloudflare worker project using workers-rs.

Getting Started A template for kick starting a Cloudflare worker project using workers-rs. This template is designed for compiling Rust to WebAssembly

Oct 13, 2021
twilight-interactions is a set of macros and utilities to work with Discord Interactions using twilight.

Twilight interactions twilight-interactions is a set of macros and utilities to work with Discord Interactions using twilight. Note: This crate is not

May 17, 2022