Skip to content

Build with the Engine

The engine is a library. It calculates legal play, transforms game state and can choose a bot’s turn. Your application owns rendering, input, persistence and any network protocol. One Scala 3 rules implementation is compiled for JVM, JavaScript and WebAssembly, so each client can use the same rules without rewriting them in its UI language.

What you are buildingStart hereAPI
Browser game, Node.js bot or compatible JavaScript app@fortemate/dicechess-engineDiceChess, including legal turn trees and bots
Lightweight JS board tooling or basic rules operations@fortemate/dicechess-engine/rulesRules subset; no legal turn tree or bots
Scala service that validates and enumerates complete turnscom.fortemate:dicechess-rules_3Direct Scala API
Scala bot, Java or Kotlin applicationcom.fortemate:dicechess-engine_3Direct Scala API or JvmApi
JavaScript application targeting a WasmGC runtime@fortemate/dicechess-engine-wasmSame full JavaScript-facing API

The two rules-only paths are different. The Maven rules jar includes TurnGenerator; the lightweight npm ./rules entry does not include getLegalTurnTree. An interactive JavaScript game that follows complete legal turns should use the full npm entry. The artifact guide lists the exact boundaries.

Terminal window
npm install @fortemate/dicechess-engine
import { DiceChess } from '@fortemate/dicechess-engine';
// White has rolled a pawn and two knights. The seventh DFEN field holds the dice.
const rolled = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 PNN';
const turns = DiceChess.getLegalTurnTree(rolled);
const choices = Object.keys(turns); // Legal first actions, in UCI notation.
console.log(choices);
// The UI offers only keys of the current tree node.
const afterPawn = DiceChess.applyMove(rolled, 'e2', 'e4');
const continuations = turns['e2e4']; // Follow this branch for the rest of the turn.
console.log(afterPawn, Object.keys(continuations));

Generate the tree once for the roll and descend through it as actions are played. applyMove carries the unspent dice forward, but is not a complete legality validator. Recomputing first moves after each action loses the original turn’s constraints. At a leaf, check for king capture; if the game continues, call endTurn before the next roll. For a valid DFEN with dice assigned and a game still in progress, an empty tree at the start of the roll means a forced pass. Invalid DFENs and positions without dice also return an empty tree; validate the state and assign the roll before interpreting it as a pass.

See the turn lifecycle for the complete controller contract and the JavaScript reference for bot discovery, search and error behavior. Existing integrations upgrading to 0.13.0 should review its release notes: applyMove now preserves remaining dice and refuses moves unsupported by the dice pool.

The public browser client is a working prototype under development. It uses SvelteKit and a Web Worker running the npm engine: the UI presents the board and handles input, while the worker executes local bot search. Its source illustrates an integration; it is not a finished product.

Dice Chess TV uses React Native for Vega for its native screens and remote input, with a pure TypeScript game controller calling @fortemate/dicechess-engine. It follows the engine’s legal turn tree and reads the dice left from applyMove, rather than implementing a second set of rules.

Hotseat play, on-device opponents and mid-turn save/resume show how the library fits an offline application. The TV app owns D-pad navigation, board rendering, sound and saved-game storage. The engine owns legal turns and bot decisions.

The project’s demo was recorded on the Vega Virtual Device. Consult the TV project’s current testing information for physical Fire TV coverage; this integration is not a claim of compatibility with every TV platform or every React Native runtime.

Source: game controller and local bot adapter.

Use Maven Central; no registry token is required. Choose the rules jar for direct Scala rules work, or the engine jar for search and JvmApi. All coordinates in one release share the same version.

libraryDependencies += "com.fortemate" %% "dicechess-engine" % "<release-version>"
// Or, for rules-only Scala code:
// libraryDependencies += "com.fortemate" %% "dicechess-rules" % "<release-version>"

Use a version from the published releases. Java and Kotlin callers use JvmApi for DFEN parsing, dice assignment, legal turns, bot decisions and game-over queries. The rules jar alone does not contain that facade. See Maven setup and the JVM API reference.

Android is a separate integration path: the documented source build selects the shared sources and facade rather than consuming the published JVM jar unchanged.

ONNX-backed searches are JVM-only. Applications using them explicitly add ONNX Runtime and supply a compatible model; the engine does not bundle trained weights.

@fortemate/dicechess-engine-wasm exports the full JavaScript-facing API through a WasmGC build. It needs a runtime with WasmGC support and the package’s JavaScript loader; it is not a standalone C ABI or a universal native binary. There is no Wasm ./rules subpath.

Start with npm integration and compare the builds using the JS/Wasm benchmark guide. Choose based on your actual workload and target runtime, rather than assuming Wasm is faster.

Keep application state and engine state together

Section titled “Keep application state and engine state together”
  • Keep the full DFEN, including remaining dice, while a turn is in progress.
  • Preserve the original turn tree and current branch, or enough action history to reconstruct them, when saving mid-turn. A mid-turn DFEN alone does not retain the original path constraints.
  • Leave the active color unchanged during micro-moves; advance it only at the turn boundary.
  • Keep expensive search off the UI thread where your runtime provides a worker or equivalent.
  • Test the package in the actual application runtime, including bundling and lifecycle behavior.

The engine does not supply a board widget, persistence layer or HTTP server. This separation lets a remote-controlled TV board and a browser game share the same rules while presenting different experiences. See runtime choices for local execution and hosted-service tradeoffs.