Lesser fork of lichess. https://spacecruft.org/deepcrayon/lila
 
 
 
 
 
 
Go to file
Thibault Duplessis a2b098ad7c improve puzzles according to community feedback 2014-02-09 14:36:57 +01:00
app improve puzzles according to community feedback 2014-02-09 14:36:57 +01:00
bin moar puzzle stuff 2014-02-06 21:36:41 +01:00
cljs/puzzle improve puzzles according to community feedback 2014-02-09 14:36:57 +01:00
conf improve puzzles according to community feedback 2014-02-09 14:36:57 +01:00
doc update readme 2014-01-27 23:38:00 +01:00
modules improve puzzle selector performance 2014-02-09 09:47:05 +01:00
project smarter selector for anon 2014-02-08 12:43:41 +01:00
public improve puzzles according to community feedback 2014-02-09 14:36:57 +01:00
serve Use the /serve directory to expose large files with the webserver 2012-05-29 00:33:28 +02:00
test upgrade reactivemongo and fix games winner ID 2013-12-16 16:27:41 +01:00
.gitignore more progress on puzzles 2014-02-03 19:53:10 +01:00
.gitmodules show user timeline on homepage 2013-05-24 15:49:02 +02:00
README.md fix readme credits 2014-02-09 14:06:51 +01:00
todo improve puzzles according to community feedback 2014-02-09 14:36:57 +01:00

README.md

lichess.org

It's a free online chess game focused on realtime and simplicity.

It haz a search engine, computer analysis, tournaments, forums, teams, puzzles, and a weird monitoring console. The UI is available in 72 languages thanks to the community.

Lichess is written in Scala 2.10, and relies on Play 2.2 for the routing, templating, and JSON. Pure chess logic is contained in scalachess submodule. The codebase is fully asynchronous, making heavy use of Scala Futures and Akka 2 actors. Lichess talks to Stockfish 4 using a FSM Actor to handle AI moves and analysis. It uses MongoDB 2.4 to store about 20 million games, which are indexed by elasticsearch 0.90. HTTP requests and websocket connections are proxied by nginx 1.4. New client-side features are written in ClojureScript.

Join us on #lichess IRC channel on freenode for more info.

Installation

I am not happy to see lichess clones spreading on the Internet. This project source code is open for other developers to have an example of non-trivial scala/play2/mongodb application. You're welcome to reuse as much code as you want for your projects, and to get inspired by the solutions I propose to many common web development problems. But please don't just create a public lichess clone. Also, if you are building a website based on lichess, please mention it in the footer with Based on <a href="http://lichess.org">lichess</a>. Thank you!

Also note that if I provide the source code, I do not offer free support for your lichess instance. I will probably ignore any question about lichess installation and runtime issues.

This is full-stack application, not a library, and it may not be straightforward to get it fully running. I assume you run a Unix with nginx, mongodb, elasticsearch and stockfish installed.

git clone git://github.com/ornicar/lila
cd lila
git submodule update --init

Configuration

cp conf/application.conf.dist conf/application.conf

application.conf extends base.conf and can override any value. Note that application.conf is excluded from git index.

Websocket proxying and language subdomains

When accessed from the root domaing (e.g. lichess.org), the application will redirect to a language specific subdomaing (e.g. en.lichess.org). Additionally, lichess will open websockets on the socket. subdomain (e.g. socket.en.lichess.org).

Here is my local nginx configuration for l.org, assuming lila is installed in /home/thib/lila and runs on 127.0.0.1:9663 /etc/nginx/l.org.conf

And here is my local /etc/hosts file

Run it

Launch the play console:

sbt play -Dhttp.port=9663

From here you can now run the application (run).

API

GET /api/user/<username> fetch one user

> curl http://en.lichess.org/api/user/thibault
{
  "username": "thibault",
  "url": "http://lichess.org/@/thibault",   // profile url
  "rating": 1503,                           // global Glicko2 rating
  "progress": 36,                           // rating change over the last ten games
  "online": true,                           // is the player currently using lichess?
  "playing": "http://lichess.org/abcdefgh", // game being played, if any
  "engine": false                           // true if the user is known to use a chess engine
}

Example usage with JSONP:

$.ajax({
  url:'http://en.l.org/api/user/thibault',
  dataType:'jsonp',
  jsonp:'callback',
  success: function(data) {
    // data is a javascript object, do something with it!
    console.debug(JSON.stringify(data));
  }
});

GET /api/user fetch many users

All parameters are optional.

name type default description
team string - filter users by team
nb int 10 maximum number of users to return
> curl http://en.lichess.org/api/user?team=coders&nb=100
{
  "list": [
    {
      "username": "thibault",
      "url": "http://lichess.org/@/thibault",   // profile url
      "rating": 1503,                           // global Glicko2 rating
      "progress": 36,                           // rating change over the last ten games
      "online": true,                           // is the player currently using lichess?
      "engine": false                           // true if the user is known to use a chess engine
    },
    ... // other users
  ]
}

Example usage with JSONP:

$.ajax({
  url:'http://en.l.org/api/user',
  data: {
    team: 'coders',
    nb: 100
  },
  dataType:'jsonp',
  jsonp:'callback',
  success: function(data) {
    // data is a javascript object, do something with it!
    console.debug(JSON.stringify(data.list));
  }
});

GET /api/game fetch many games

Games are returned by descendant chronological order. All parameters are optional.

name type default description
username string - filter games by user
rated 1 or 0 - filter rated or casual games
nb int 10 maximum number of games to return
token string - security token (unlocks secret game data)
> curl http://en.lichess.org/api/game?username=thibault&rated=1&nb=10
{
  "list": [
    {
      "id": "x2kpaixn",
      "rated": false,
      "status": "mate",
      "clock":{          // all clock values are expressed in seconds
        "limit": 300,
        "increment": 8,
        "totalTime": 540  // evaluation of the game duration = limit + 30 * increment
      },
      "timestamp": 1389100907239,
      "turns": 44,
      "url": "http://lichess.org/x2kpaixn",
      "winner": "black",
      "players": {
        "white": {
          "userId": "thibault"
          "rating": 1642,
          "analysis": {
            "blunder": 1,
            "inaccuracy": 0,
            "mistake": 2
          }
        },
        "black": ... // other player
      }
    },
    {
      ... // other game
    }
  ]
}

(1) All game statuses: https://github.com/ornicar/scalachess/blob/master/src/main/scala/Status.scala#L16-L25

POST /api/game/new create a new game

You can create a new casual game by just POSTing to this url. You get back two links, for the white player and for the black player. One could use that API to provide chess capabilities to an online chat, for instance.

> curl -XPOST http://en.lichess.org/api/game/new
{
  "white": "http://l.org/8pmigk36t1hp",
  "black": "http://l.org/8pmigk36ov6m"
}

GET /api/analysis fetch many analysis

Analysis are returned by descendant chronological order. All parameters are optional.

name type default description
nb int 10 maximum number of analysis to return
> curl http://en.lichess.org/api/analysis?nb=10
{
  "list": [
    {
      "analysis": [
        {
          "eval": -26, // board evaluation in centipawns
          "move": "e4",
          "ply": 1
        },
        {
          "eval": -8,
          "move": "b5",
          "ply": 2
        },
        {
          "comment": "(-0.08 → -0.66) Inaccuracy. The best move was c4.",
          "eval": -66,
          "move": "Nfe3",
          "ply": 3,
          "variation": "c4 bxc4 Nfe3 c5 Qf1 f6 Rxc4 Bb7 b4 Ba6"
        },
        // ... more moves
      ],
      "game": {
        // similar to the game API format, see above
      },
      "uci": "e2e4 e7e5 d2d4 e5d4 g1f3 g8f6" // UCI compatible game moves
    }
  ]
}

Read the move stream

Lichess streams all played moves on http://en.lichess.org/stream using chunked HTTP response and the following format:

ChunkSize                # size of the next chunk, in hexadecimal
GameId UciMove IpAddress # actual chunk of data

UciMove format

([a-h][1-8]){2}x?(+|#)?

where x indicates a capture, + a check and # a checkmate.

Try it with netcat

> echo "GET /stream HTTP/1.1\nHost: en.lichess.org\n" | netcat en.lichess.org 80

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 16 Oct 2013 20:01:11 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding

1a
4om0thb7 d1e1 91.121.7.111
1b
o2eg9xu3 c8c2x 89.77.165.159
18
g3ag6xm6 g7f7+ 83.149.8.9
1b
hl0zbh3g c4c5# 109.237.157.8
1a
g3ag6xm6 c2c3x+ 91.121.7.111
1c
tj2u3hus a7a6x# 117.199.47.140

By comparing game IDs, you can guess who plays against who.

Note that 91.121.7.111 and 198.50.141.73 are AI servers.

Credits

Big thanks go to lichess community for the support, inspiration, bug reports, and amazing translation efforts.

Special thanks go to:

Thanks to all players for feeding the database.