### Clone Lichess Repository and Setup Dependencies
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
Clone the Lichess repository and install necessary tools like corepack for pnpm. This is the initial step for setting up the development environment.
```sh
git clone --recursive https://github.com/lichess-org/lila.git
cd lila
corepack enable
```
--------------------------------
### Setup Lichess-Fishnet for Computer Play
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
Clone and run the lila-fishnet server to enable playing against Stockfish. This is separate from the analysis setup.
```sh
git clone https://github.com/lichess-org/lila-fishnet.git
cd lila-fishnet
sbt app/run -Dhttp.port=9665
```
--------------------------------
### Start Lichess SBT Console
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
Start the Lichess SBT console to manage the application. After the console boots, type 'compile' to build the project and 'run' to start the HTTP server.
```sh
./lila.sh
```
--------------------------------
### Setup Sound Test Buttons
Source: https://github.com/lichess-org/lila/blob/master/public/oops/sounds.html
Initializes the sound test interface by creating buttons for each sound set and basic sound effect. It uses jQuery (via 'cash.min.js') to manipulate the DOM and attach click event listeners to play sounds. The setup is delayed by 250ms.
```javascript
const soundSets = ['standard', 'futuristic', 'lisp', 'nes', 'piano', 'robot', 'sfx', 'woodland'];
const basics = [
'genericNotify', 'move', 'capture', 'explosion', 'lowTime', 'victory', 'defeat', 'draw', 'berserk', 'check', 'checkmate', 'newChallenge', 'newPM', 'confirmation', 'error', 'practiceComplete', 'practiceWrong', 'tournament1st', 'tournament2nd', 'tournament3rd', 'tournamentOther',
...[...Array(11).keys()].reverse().map(i => 'CountDown' + i),
];
setTimeout(function () {
soundSets.forEach(s => {
$('
').appendTo($('table.common tbody'));
$.each(soundSets, function (i, soundSet) {
$('')
.append(
$('')
.on('click', () => playSound(soundSet, name))
.text(name),
)
.appendTo(tr);
});
}
[
['good', 'PuzzleStormGood'],
['wrong', 'Error'],
['end', 'PuzzleStormEnd'],
].forEach(([name, sound]) => {
var tr = $('').appendTo($('table.storm tbody'));
$('')
.append(
$('')
.on('click', () => playSound('lisp', sound))
.text(name),
)
.appendTo(tr);
});
}, 250);
```
--------------------------------
### Complete SCSS Theme File Example
Source: https://github.com/lichess-org/lila/blob/master/ui/lib/css/theme/README.md
A full example of an SCSS theme file, demonstrating the import of default definitions, definition of tentpole colors, and overriding CSS variables for a specific theme class ('ugly').
```scss
// ugly theme
@import 'default'; // for default defs and shared-color-defs mixin
$c-font: #f00; // these are your tentpole colors
$c-bg: #00f;
$c-primary: #0f0; // anything you don't specify here will be inherited from default
html.ugly {
// the 'ugly' class is added to the html element by the theme switcher
@include shared-color-defs;
--c-bg-variation: #f0f;
--c-bg-header-dropdown: #ff0;
--c-border: #0ff;
@include ugly-mix;
// ugly-mix is a mixin created by ui/build that contains color mixes specified
// elsewhere in your scss. these reflect the scss variable values above, so
// `background: $m-font_bg--mix-50;` will give a purple background
}
```
--------------------------------
### Enable and Start Bloop Systemd Service
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-With-Bloop
Commands to enable and start the Bloop userland systemd service. Ensure Bloop is installed via your package manager before running these commands.
```bash
systemctl --user enable bloop
```
```bash
systemctl --user start bloop
```
--------------------------------
### Install and Run Lila
Source: https://github.com/lichess-org/lila/blob/master/README.md
Use this script to install and run the Lila application. It acts as a thin wrapper around sbt.
```bash
./lila.sh # thin wrapper around sbt
run
```
--------------------------------
### Start Docker Infrastructure
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding-(IntelliJ-on-Linux)
Use Docker Compose to start the defined services (Redis and MongoDB). This command spins up the necessary backend services for Lichess.
```bash
docker-compose up
```
--------------------------------
### Start MongoDB and Redis Servers
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
Start the MongoDB and Redis servers, which are required for Lichess to function. These should be run in separate terminals or as daemons.
```sh
mongod
```
```sh
redis-server
```
--------------------------------
### Install Python Dependencies
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development---customizing-your-db
Installs required Python packages like pymongo and requests using pip3. Ensure Python 3.9+ is installed.
```bash
python -m ensurepip --upgrade
# NOTE - On windows it might be "py -m ensurepip --upgrade"
pip3 install pymongo requests
```
--------------------------------
### Setup Stockfish Client for Computer Play
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
Clone and run the fishnet client to play against the computer via the lila-fishnet server. Requires a recent Rust toolchain. The --endpoint flag points to the lila-fishnet server.
```sh
git clone --recursive https://github.com/lichess-org/fishnet.git
cd fishnet
cargo run -- --endpoint http://localhost:9665/fishnet/
```
--------------------------------
### Setup Lichess Websocket Server
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
Clone and set up the lila-ws server, which handles real-time communication via websockets. This server lives outside the main lila repository.
```sh
git clone https://github.com/lichess-org/lila-ws.git
cd lila-ws
sbt run -Dcsrf.origin=http://localhost:9663
```
--------------------------------
### Setup Stockfish Analysis Client
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
Clone and build the fishnet client for Stockfish analysis. Requires a recent Rust toolchain. The --endpoint flag specifies the connection point for the analysis server.
```sh
git clone --recursive https://github.com/lichess-org/fishnet.git
cd fishnet
cargo run -- --endpoint http://localhost:9663/fishnet/
```
--------------------------------
### Get SpamDB Usage Help
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development---customizing-your-db
Navigates to the spamdb directory and displays the help message for the spamdb.py script. This shows available command-line options.
```bash
cd spamdb
python3 ./spamdb.py --help
```
--------------------------------
### Build UI Assets
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding-(IntelliJ-on-Linux)
Compile CSS and JavaScript assets for the Lichess user interface. This command should be run before starting the application.
```bash
./ui/build
```
--------------------------------
### Git Configuration for Enhanced Workflow
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
Recommended Git configurations to simplify the development workflow. These settings automate branch setup for merging and pushing, potentially reducing manual steps.
```bash
git config [branch.autoSetupMerge](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt-branchautoSetupMerge) inherit
```
```bash
git config [push.autoSetupRemote](https://git-scm.com/docs/git-push#Documentation/git-push.txt-pushautoSetupRemote) true
```
```bash
git config [push.default](https://git-scm.com/docs/git-push#Documentation/git-push.txt-pushdefault) current
```
--------------------------------
### Compile and Run Lila with Bloop
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-With-Bloop
Commands to compile and run the Lila project using Bloop after initial setup. Replace '/path/to/lila/.bloop' with the actual path to your Bloop configuration directory.
```bash
sbt bloopInstall
```
```bash
bloop compile lila
```
```bash
bloop run lila -m lila.app.Lila -c /path/to/lila/.bloop
```
--------------------------------
### Run Lila Application via SBT
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding-(IntelliJ-on-Linux)
Start the Lichess application using the SBT run command within the project's SBT shell. Ensure infrastructure and UI assets are built first.
```bash
run
```
--------------------------------
### Run Lichess Application with SBT
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
Start the Lichess application using the SBT run command. Specify the CSRF origin for the development environment. This command should be run in a separate terminal within the cloned `lila-ws` repository.
```sh
sbt run -Dcsrf.origin=http://localhost:9663
```
--------------------------------
### Scala Usage: Direct Translation
Source: https://github.com/lichess-org/lila/wiki/How-translations-work
Shows how to directly use a translation key in Scala to get a translated string fragment, optionally passing arguments for placeholders.
```scala
trans.theKey("abc", 42)
```
--------------------------------
### tsc Barrel Export Resolution
Source: https://github.com/lichess-org/lila/blob/master/ui/README.md
Example of 'exports' configuration for a specific sub-path ('./ceval') within a package, enabling imports from barrel files.
```json
"exports": {
"...": {
"./ceval": {
"types": "./dist/ceval/index.d.ts",
"import": {
"source": "./src/ceval/index.ts",
"default": "./dist/ceval/index.js"
}
}
}
}
```
--------------------------------
### Docker Compose Configuration for Infrastructure
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding-(IntelliJ-on-Linux)
Define Docker services for Redis and MongoDB. This configuration allows for easy setup and management of the required database infrastructure using Docker Compose.
```yaml
version: "3.3"
services:
redis:
image: "redis:alpine"
ports:
- 6379:6379
mongo:
image: mongo
restart: always
ports:
- 27017:27017
```
--------------------------------
### Scala Usage: Plural Plain Text Translation
Source: https://github.com/lichess-org/lila/wiki/How-translations-work
Shows how to get a pluralized translation as plain text using `pluralTxt`. The count determines the plural form, and arguments fill placeholders.
```scala
trans.theKey.pluralTxt(count, "abc", 42)
```
--------------------------------
### Troubleshoot PrimaryUnavailableException
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
This error indicates that MongoDB's primary node is not available. Ensure mongod is running and check its log file for specific errors. Insufficient disk space or stale lock files can prevent mongod from starting.
```text
[PrimaryUnavailableException$: MongoError['No primary node is available!']]
```
--------------------------------
### Build UI Assets
Source: https://github.com/lichess-org/lila/blob/master/ui/README.md
Use the ui/build script to compile client assets. Run with -w to enable watch mode for continuous rebuilding.
```bash
ui/build --help
```
```bash
ui/build -w
```
--------------------------------
### Configure SBT Options and Application Settings
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding-(IntelliJ-on-Linux)
Copy default SBT options and application configuration files to enable custom settings. This step is necessary when working with IDE SBT features instead of the SBT wrapper.
```bash
cp .sbtopts.default .sbtopts
cp conf/application.conf.default conf/application.conf
```
--------------------------------
### Build UI Assets
Source: https://github.com/lichess-org/lila/wiki/Tips-for-UI,-translations,-insights,-swiss,-accessibility
Command to build UI assets. Refer to custom package.json properties for details on asset building and linking.
```bash
ui/build --help
```
--------------------------------
### Scala Translation Key Definition
Source: https://github.com/lichess-org/lila/wiki/How-translations-work
Example of how translation keys are defined in Scala, mapping to the XML keys. These are used for programmatic access to translations.
```scala
object I18nKeys:
val `someSiteKey`: I18nKey = "someSiteKey"
// ...
object swiss:
val `swissTournaments`: I18nKey = "swiss:swissTournaments"
// ...
```
--------------------------------
### Create Game Index Mapping
Source: https://github.com/lichess-org/lila/wiki/Enable-Lila-search
Manually create the index mapping for games before playing or analyzing. This is a required step for manual indexing.
```bash
curl -XPOST http://localhost:9673/mapping/game
```
--------------------------------
### Create Users with Background Images using spamdb.py
Source: https://github.com/lichess-org/lila/wiki/Lichess-and-Firefox-Multi-Account-Containers
Use the `--user-bg` option with the `spamdb.py` script to create development users with random background images. This helps visually differentiate users in the UI.
```python
spamdb.py --user-bg 400
```
--------------------------------
### Run make-grammar script
Source: https://github.com/lichess-org/lila/blob/master/ui/voice/README.md
Execute the make-grammar script with specified frequency, count, and lexicon prefixes. Default values for --freq and --count are shown.
```bash
./pnpm make-grammar --freq=.002 \
--count=6 \
moves-en
```
--------------------------------
### Clone and Run lila-search
Source: https://github.com/lichess-org/lila/wiki/Enable-Lila-search
Clone the lila-search repository and run the application using sbt. This is a prerequisite for enabling search functionality.
```bash
git clone https://github.com/lichess-org/lila-search
cd lila-search
sbt app/run
```
--------------------------------
### Reset Search Indices via CLI
Source: https://github.com/lichess-org/lila/wiki/Enable-Lila-search
Reset the search indices for forum, team, and study using the Lichess development CLI. These commands should be run after starting Lichess and logging in as the lichess user.
```bash
forum search reset
team search reset
study search reset
```
--------------------------------
### Troubleshoot TimeoutException
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
A timeout exception, often occurring with MongoDB, suggests that the database might not be running or that the connection timeout is too short, especially on cold starts on macOS. Restarting Lila after ensuring MongoDB is running is recommended.
```text
java.util.concurrent.TimeoutException: Future timed out after [5 seconds]
```
--------------------------------
### XML String with Placeholder
Source: https://github.com/lichess-org/lila/wiki/How-translations-work
Illustrates how to define strings with placeholders marked by %s. These can be replaced with dynamic content.
```xml
%s started streaming
```
--------------------------------
### Import Insights Sample Data
Source: https://github.com/lichess-org/lila/wiki/Tips-for-UI,-translations,-insights,-swiss,-accessibility
Command to import insights sample data into a MongoDB database. Ensure the 'insight.bson' file is available.
```bash
mongorestore --db lichess-insight --collection insight insight.bson
```
--------------------------------
### Build Lichess Client
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
Build the Lichess client-side code. Use the -w flag to automatically recompile on changes and observe them in the browser after a refresh.
```sh
ui/build
```
```sh
ui/build -w
```
--------------------------------
### Load Manifest and Scripts
Source: https://github.com/lichess-org/lila/blob/master/public/oops/sounds.html
Fetches the manifest file to determine the correct script hashes and dynamically loads the required JavaScript files for the application. Ensure the manifest.dev.json is accessible.
```javascript
document.body.setAttribute('data-socket-domains', location.host);
window.site = {};
window.site.load = new Promise(r => document.addEventListener('DOMContentLoaded', r));
window.fetch('/assets/compiled/manifest.dev.json')
.then(r => r.json())
.then(manifest => {
[
`/assets/compiled/manifest.${manifest.js.manifest.hash}.js`,
`/assets/compiled/site.${manifest.js.site.hash}.js`,
`/assets/hashed/cash.${manifest.hashed['javascripts/vendor/cash.min.js'].hash}.min.js`,
].forEach(url => {
const script = document.createElement('script');
script.src = url;
script.type = 'module';
document.body.appendChild(script);
});
});
```
--------------------------------
### Hash Configuration with String Globs
Source: https://github.com/lichess-org/lila/blob/master/ui/README.md
Use string globs to specify files for hashing. Ensure paths begin with \"/public\".
```json
"hash": [
"/public/lifat/background/montage*.webp",
"/public/npm/*",
"/public/javascripts/**"
]
```
--------------------------------
### Basic Git Commands for Lichess Contribution
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
Essential Git commands for cloning the repository, setting up remotes, creating branches, staging and committing changes, and pushing to your fork. These commands are fundamental for contributing to the Lichess project.
```bash
git clone https://github.com/YOUR-GITHUB-USERNAME/lila # fetch the sources
```
```bash
git remote add upstream origin https://github.com/lichess-org/lila # link your repo to lichess-org/lila
```
```bash
git checkout -b YOUR-BRANCH-NAME # branches are human readable & dash separated, otherwise your choice
```
```bash
git add -A . # recursively stages all changes within the current directory
```
```bash
git commit -m 'your commit message' # commit previously staged changes to your host repo
```
```bash
git push origin YOUR-BRANCH-NAME # push the state of your local repo to your fork.
```
```bash
# notice that git push's output contains a URL you can visit to create your Pull Request
```
--------------------------------
### Create Database Indexes with MongoDB
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
Create essential database indexes for Lichess using mongosh. Ensure MongoDB is running before executing this command.
```sh
mongosh lichess < bin/mongodb/indexes.js
```
--------------------------------
### Convert PNG to WebP using cwebp
Source: https://github.com/lichess-org/lila/blob/master/bin/flair/README.md
Use the cwebp command-line tool to convert PNG images to the WebP format required for Lichess flairs. Ensure the output file path is correctly specified.
```shell
cwebp path/to/horsey.png -o lila/public/flair/img/activity.lichess-horsey.webp
```
--------------------------------
### Seed Local Database with Dummy Data
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
Clone the lila-db-seed repository and use the spamdb.py script to populate your local database with dummy data. Requires Python 3.9+.
```sh
git clone https://github.com/lichess-org/lila-db-seed
cd lila-db-seed
python3 spamdb/spamdb.py --help
```
--------------------------------
### Synchronize npm Package Assets
Source: https://github.com/lichess-org/lila/blob/master/ui/README.md
Configure filesystem copies for assets, such as large npm package files like WebAssembly modules, to be placed in the /public/npm folder. This allows them to be fetched and imported dynamically without being bundled.
```json
{
"sync": {
"node_modules/*stockfish*/*.{js,wasm}": "/public/npm"
},
}
```
--------------------------------
### XML String with Multiple Placeholders
Source: https://github.com/lichess-org/lila/wiki/How-translations-work
Shows how to use numbered placeholders like %1$s and %2$s for multiple dynamic values within a single string.
```xml
%1$s started following %2$s
```
--------------------------------
### Fetch and Display Lichess Flairs
Source: https://github.com/lichess-org/lila/blob/master/public/oops/flair.html
Fetches a list of flairs from a URL, parses the text to categorize them, and then dynamically creates HTML elements to display each flair with its corresponding image. Ensure the `flairBaseUrl` is correctly set.
```javascript
const flairBaseUrl = '/assets/______4/flair';
fetch(`${flairBaseUrl}/list.txt?nocache=${Math.random()}`)
.then(r => r.text())
.then(text => {
let categs = {};
text
.split('\n')
.filter(x => x)
.forEach(flair => {
const categName = flair.split('.')\[0\];
if (!categs\[categName\]) categs\[categName\] = \[flair\];
else categs\[categName\].push(flair);
});
const container = document.createElement('div');
container.className = 'categs';
Object.entries(categs).forEach(([categName, flairs]) => {
const categDiv = document.createElement('div');
categDiv.className = 'categ';
const h2 = document.createElement('h2');
h2.textContent = categName;
categDiv.appendChild(h2);
const flairsDiv = document.createElement('div');
flairsDiv.className = 'flairs';
for (const flair of flairs) {
const a = document.createElement('a');
a.href = '#' + flair;
a.id = flair;
a.textContent = flair;
const i = document.createElement('img');
i.loading = 'lazy';
i.src = `${flairBaseUrl}/img/${flair}.webp`;
i.title = flair;
a.appendChild(i);
flairsDiv.appendChild(a);
}
categDiv.appendChild(flairsDiv);
container.appendChild(categDiv);
});
document.body.appendChild(container);
});
```
--------------------------------
### Generate Licon Icons
Source: https://github.com/lichess-org/lila/wiki/Tips-for-UI,-translations,-insights,-swiss,-accessibility
Script to generate licon icons. Use the --help flag for more options.
```bash
bin/gen/licon.py --help
```
--------------------------------
### Optimize PNG with oxipng
Source: https://github.com/lichess-org/lila/wiki/Flag-icons-for-user-location
Optimize the final flag PNG file using oxipng to reduce its size. The '-o max' flag applies the highest level of optimization.
```bash
oxipng -o max
```
--------------------------------
### Apply Shiny Overlay with ImageMagick
Source: https://github.com/lichess-org/lila/wiki/Flag-icons-for-user-location
Use ImageMagick to composite a 24px shiny overlay onto a flag PNG. Ensure the overlay file and the flag PNG are in the correct directory.
```bash
magick composite 24.png YOUR_FLAG_NAME.png FINAL_FLAG_NAME.png
```
--------------------------------
### Run UI Tests
Source: https://github.com/lichess-org/lila/blob/master/ui/README.md
Execute tests using the ui/test script, which is a wrapper for Node's test runner. Supports watch mode and filtering tests by name.
```bash
ui/test # build ui/*/tests/**/*.ts
```
```bash
ui/test -w # watch ui/*/tests/**/*.ts
```
```bash
ui/test winning # ui/lib/tests/winningChances.test.ts
```
```bash
ui/test mod once # ui/mod/tests/**/*.ts ui/lib/tests/once.test.ts
```
--------------------------------
### Define JavaScript Entry Points with Glob Pattern
Source: https://github.com/lichess-org/lila/blob/master/ui/README.md
Use a glob pattern to specify multiple JavaScript source files that will be bundled into named entry points. Each matched file is processed into a flattened ES6 module in the /public/compiled folder with a content hash in its filename.
```json
{
"build": {
"bundle": "src/**/analyse.*ts"
}
}
```
--------------------------------
### Detect 64-bit Architecture
Source: https://github.com/lichess-org/lila/blob/master/public/oops/diagnostics.html
Checks if the browser is running on a 64-bit system by examining the user agent and platform strings. Useful for determining compatibility with 64-bit specific features.
```javascript
function is64Bit() { const x64 = ['x86_64', 'x86-64', 'Win64', 'x64', 'amd64', 'AMD64']; for (const substr of x64) if (navigator.userAgent.includes(substr)) return true; return navigator.platform === 'Linux x86_64' || navigator.platform === 'MacIntel'; }
```
--------------------------------
### Run Playwright Tests
Source: https://github.com/lichess-org/lila/blob/master/tests/README.md
Execute all Playwright tests. Use the --ui flag for an interactive testing experience.
```bash
npx playwright test
```
```bash
npx playwright test --ui
```
--------------------------------
### Scala Method Calling Conventions
Source: https://github.com/lichess-org/lila/wiki/Lilaisms
Provides guidelines for calling methods in Scala, emphasizing clarity and avoiding ambiguous syntax. Parentheses are generally required for methods with arguments or when not using infix notation.
```scala
obj.method(arg) // yes, best
obj method arg // yes if cute and not confusing
obj.method {
argBlock
}
obj.method (arg) // no
obj method (arg) // no
obj method(arg) // no
obj.method(arg1, arg2) // yes
obj.method (arg1, arg2) // no
obj method (arg1, arg2) // no
obj method(arg1, arg2) // no
obj.methodWithoutArg // yes
obj methodWithoutArg // no
```
--------------------------------
### Parallel Future Execution in Scala
Source: https://github.com/lichess-org/lila/wiki/Lilaisms
Shows how to execute a list of futures in parallel and collect their results into a single future containing a list of values.
```scala
val futures: List[Future[Int]]
futures.parallel: Future[List[Int]] // executes all futures and return one with a list of values
```
--------------------------------
### Configure Bundling with Inline Scripts
Source: https://github.com/lichess-org/lila/blob/master/ui/README.md
Configure bundling using an object format for more control. The 'module' path specifies the source module, while the 'inline' path identifies a TypeScript source for emitting JavaScript statements into a manifest file. These inline statements are injected into a script tag to manipulate the DOM before rendering, avoiding FOUC.
```json
{
"bundle": [
"src/site.*Embed.ts",
{
"module": "src/site.ts",
"inline": "src/site.inline.ts"
}
],
}
```
--------------------------------
### Sequencing Futures and Effects in Scala
Source: https://github.com/lichess-org/lila/wiki/Lilaisms
Illustrates sequencing futures using `>>` (flatMap) and `andDo` for side effects. Multiple `andDo` calls execute sequentially.
```scala
fu >> otherFu // fu.flatMap(_ => otherFu) // sequence without using first result
fu andDo effect // fu andThen { case _ => effect } // run a side effect after completion
fu1 >> fu2 andDo effect1 andDo effect2 // sequences f1 and f2, then runs effect1 then effect2
```
--------------------------------
### Generate Playwright Tests
Source: https://github.com/lichess-org/lila/blob/master/tests/README.md
Launch Playwright's code generation tool to interactively create new tests.
```bash
npx playwright codegen
```
--------------------------------
### Configure Git Hooks for Code Formatting
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
Add git hooks to automatically format staged files with prettier/eslint before each commit. This ensures code consistency across the project.
```sh
pnpm add-hooks
```
--------------------------------
### Clone Lila Repositories
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding-(IntelliJ-on-Linux)
Clone the main Lichess project and its WebSocket component. Ensure the main repository is cloned recursively to include submodules.
```bash
git clone --recursive https://github.com/lichess-org/lila.git
git clone https://github.com/lichess-org/lila-ws.git
```
--------------------------------
### WebAssembly Information
Source: https://github.com/lichess-org/lila/blob/master/public/oops/diagnostics.html
Gathers detailed information about WebAssembly support, including its availability, validation capabilities, MVP support, SIMD features, and SharedArrayBuffer functionality. It also tests memory sharing and growability.
```javascript
function wasmInfo() { var info = { WebAssembly: typeof WebAssembly, SharedArrayBuffer: typeof SharedArrayBuffer, Atomics: typeof Atomics, }; if (info.WebAssembly !== 'object') return info; info.validate = typeof WebAssembly.validate; if (info.validate !== 'function') return info; var source = Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00); info.mvp = WebAssembly.validate(source); if (!info.mvp) return info; info.simd = { 'i32x4.dot_i16x8_s': WebAssembly.validate( Uint8Array.of( 0, 97, 115, 109, 1, 0, 0, 0, 1, 5, 1, 96, 0, 1, 123, 3, 2, 1, 0, 7, 8, 1, 4, 116, 101, 115, 116, 0, 0, 10, 15, 1, 13, 0, 65, 0, 253, 17, 65, 0, 253, 17, 253, 186, 1, 11, ), ), 'i32x4.trunc_sat_f64x2_u_zero': WebAssembly.validate( Uint8Array.of( 0, 97, 115, 109, 1, 0, 0, 0, 1, 6, 1, 96, 1, 123, 1, 123, 3, 2, 1, 0, 7, 5, 1, 1, 97, 0, 0, 10, 9, 1, 7, 0, 32, 0, 253, 253, 1, 11, ), ), }; if (info.SharedArrayBuffer !== 'function') return info; var mem = new WebAssembly.Memory({ shared: true, initial: 8, maximum: 16 }); info.sharedMem = mem.buffer instanceof SharedArrayBuffer; try { window.postMessage(mem, '*'); info.structuredCloning = 'ok'; } catch (e) { info.structuredCloning = e.toString(); } try { mem.grow(8); info.growableMem = 'ok'; } catch (e) { info.growableMem = e.toString(); } return info; }
```
--------------------------------
### Hash Configuration with Object Form
Source: https://github.com/lichess-org/lila/blob/master/ui/README.md
Use object form for more control over hashing, including omitting from client manifests or transforming catalog files.
```json
"hash": { "path": "", "omit": true, "catalog": "" }
```
--------------------------------
### Enable Search in application.conf
Source: https://github.com/lichess-org/lila/wiki/Enable-Lila-search
Add this line to your lila configuration file to enable the search feature.
```hocon
search.enabled = true
```
--------------------------------
### Troubleshoot ArrayIndexOutOfBoundsException
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
This error during game creation may be related to an outdated MongoDB version. Verify that your MongoDB version meets the project's requirements.
```text
[ERROR] p.c.s.n.PlayDefaultUpstreamHandler Cannot invoke the action
java.lang.ArrayIndexOutOfBoundsException: 101
```
--------------------------------
### Future Operations in Scala
Source: https://github.com/lichess-org/lila/wiki/Lilaisms
Demonstrates `dmap` and `dforeach` for efficient future mapping and iteration, and `void` and `inject` for result manipulation. These operations are optimized to run on the same thread.
```scala
val fu: Future[Int]
val f: Int => Boolean
fu dmap f // fu map f // but runs on the same thread (perf tweak)
fu dforeach f // fu foreach f // but runs on the same thread (perf tweak)
fu.void // fu.map(_ => ()) // discards the result, returns Funit
fu inject "foo" // fu.map(_ => "foo") // replaces the result
```
--------------------------------
### Scala Usage: Plain Text Translation
Source: https://github.com/lichess-org/lila/wiki/How-translations-work
Illustrates retrieving a translated string as plain text using the `txt` extension method. Arguments are passed for placeholders.
```scala
trans.theKey.txt("abc", 42)
```
--------------------------------
### Index Data with spamdb
Source: https://github.com/lichess-org/lila/wiki/Enable-Lila-search
Use the spamdb script with the --es flag to connect to Elasticsearch and index games, posts, and teams. This is an alternative to manual index creation.
```python
spamdb/spamdb.py --es
```
--------------------------------
### esbuild Import Resolution with Exports
Source: https://github.com/lichess-org/lila/blob/master/ui/README.md
Configures 'exports' for esbuild, which primarily uses the 'source' value within an 'import' property for bundling. Ignores 'types' and '.js' files.
```json
"exports": {
"./boo/*": {
"import": {
"source": "./src/boo/*.ts"
}
}
}
```
--------------------------------
### Build Watch Mode Command
Source: https://github.com/lichess-org/lila/blob/master/ui/lib/css/theme/README.md
Command to run the LILA build script in watch mode, which keeps all assets synchronized during development.
```bash
ui/build -w
```
--------------------------------
### Recompile Playframework Routes
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-With-Bloop
Command to recompile Playframework routes after editing 'conf/routes'. This is a workaround as Bloop does not automatically watch and recompile these routes.
```bash
sbt playRoutes
```
--------------------------------
### Scala Translation Extension Methods
Source: https://github.com/lichess-org/lila/wiki/How-translations-work
Demonstrates extension methods available on `I18nKey` in Scala for retrieving translated strings. Includes methods for plain text, plurals, and fragments.
```scala
object I18nKey:
// ...
def txt(args: Any*)(using trans: Translate): String = // ...
def pluralTxt(count: Count, args: Any*)(using trans: Translate): String = // ...
def pluralSameTxt(count: Long)(using trans: Translate): String = pluralTxt(count, count)
def apply(args: Matchable*)(using trans: Translate): RawFrag = // ...
def plural(count: Count, args: Matchable*)(using trans: Translate): RawFrag = // ...
def pluralSame(count: Int)(using trans: Translate): RawFrag = plural(count, count)
```
--------------------------------
### Troubleshoot SBT 'Killed' Error
Source: https://github.com/lichess-org/lila/wiki/Lichess-Development-Onboarding
If `sbt` exits with 'Killed', it typically means there was insufficient RAM available to compile the project. Ensure your system has enough free memory before attempting to compile.
```text
sbt prints `Killed` and exits
```
--------------------------------
### Basic XML String Definition
Source: https://github.com/lichess-org/lila/wiki/How-translations-work
Defines a simple string with a name and its English text. Used for basic translations.
```xml
Play with a friend
```
--------------------------------
### Accessing Translations in JavaScript
Source: https://github.com/lichess-org/lila/wiki/How-translations-work
Demonstrates how to access translated strings, pluralized strings, and formatted strings from the global `i18n` object in JavaScript. Ensure translation assets are loaded via script tags.
```javascript
const translated = i18n.site.someString;
```
```javascript
const pluralTranslation = i18n.site.somePlural(count);
```
```javascript
const translatedAndFormatted = i18n.site.someFormatStringXY(xarg, yarg);
```
```javascript
const asArray = i18n.site.someFormatStringXY.asArray(xarg, yarg);
```
--------------------------------
### Generate Flair List with TypeScript
Source: https://github.com/lichess-org/lila/blob/master/bin/flair/README.md
Execute the TypeScript script to generate the `list.txt` file, which Lichess uses to update its flair database. This script is typically run after adding new flair images.
```shell
pnpx tsx bin/flair/generate.ts
```
--------------------------------
### Inline Print and Pass Utility in Scala
Source: https://github.com/lichess-org/lila/wiki/Lilaisms
The 'pp' function prints a value to standard output and returns the value itself. It's useful for inline debugging. It can also take a context string to prefix the output.
```scala
"foo".pp // prints "foo" to stdout, and returns "foo"
player.pp.make(move.pp).pp // behaves like player.make(move), but prints
// player, move, and the result of player.make(move)
"foo".pp("context") // prints "context: foo" to stdout, and returns "foo"
```
--------------------------------
### Scala Usage: Simplified Plural Plain Text Translation
Source: https://github.com/lichess-org/lila/wiki/How-translations-work
Demonstrates the `pluralSameTxt` method for retrieving pluralized translations as plain text when the count is the same value used for placeholder replacement.
```scala
trans.theKey.pluralSameTxt(count)
```
--------------------------------
### Link Local Package with pnpm
Source: https://github.com/lichess-org/lila/wiki/Lichess-UI-Development
Use `pnpm link` to connect a local package to a project. Ensure you are in the directory of the module that will use the linked package. This command modifies `pnpm-lock.yaml`.
```bash
cd /ui/site
pnpm link ../../../pgn-viewer # relative path to your local package
```
--------------------------------
### Generate Translation Keys
Source: https://github.com/lichess-org/lila/wiki/Tips-for-UI,-translations,-insights,-swiss,-accessibility
Command to regenerate translation keys for Scala after updating British English source files.
```bash
pnpm run i18n-file-gen
```