Chess Crystal
NeuralCrystal was built by Pete DeLaurentis with Shellcaster, an IDE for building complex projects with agents.
This model represents a physical crystal with 80 etched surfaces and 64M parameters that is trained to play chess. There's no search inside the glass: the board goes in as light, the light makes four passes through the block, and lights up locations on a move map corresponding to recommended moves.
Demo
Run this crystal in the optical simulator at NeuralCrystal.com: play a game against it, and see the light travel through the glass.
Input
The board goes in as a 192 × 192 picture on a 4K micromirror array, where every mirror is either on or off. It's always drawn from the point of view of the side to move, so a position with white to move is mirrored first. Besides the pieces (white filled, black as outlines), small markers along the left edge carry what the pieces alone can't show: a turn light for each side, a flag for each castling right that's still open, and a crystal mark on the side the crystal plays. When an en-passant capture is possible, a dot appears below the board under that file. This is the board after white opens with "1. e4" (pawn to e4), with black to move:
Output
After four passes, the light lands on a 64 × 64 move map: 4,096 cells, one for every pair of from-square (row) and to-square (column). The brightest legal cell is the crystal's move. Below, the legal moves are outlined in teal and the crystal's choice, e6, in white.
A piece can't move to its own square, so the map's diagonal is free. The crystal uses three stretches of it to read out the probability of a win, draw or loss for the side to move: the share of light on each stretch. Here it reads 20 % win, 55 % draw, 26 % loss.
Looking ahead
The win/draw/loss readout lets the crystal look ahead, by running additional board images through the crystal:
- Read the board and take the crystal's K brightest moves.
- Play each one, and show the crystal the new board to find the opponent's J brightest replies.
- Play each reply, and show the crystal that board. Its readout scores it: a win counts 1, a draw ½.
- Play the move from the set of K that has the best readout score across the J possible opponent replies, judging each move by its worst reply.
With K = 3 and J = 5, that's 1 + 3 + 15 = 19 runs of the crystal instead of one: the "look ahead 3 × 5" in the results below.
Confidence
The move map also shows how sure the crystal is. Its confidence is the brightest move's share of the light on its K brightest moves (the same K as the look-ahead): close to 1 when one move clearly outshines the rest, and close to 1/K when the top K are about equally bright. The website looks ahead only when the crystal is unsure, with confidence below 0.5 at its lowest playing level. So clear moves cost one run, and close calls get the 19-run look-ahead. Deeper in the look-ahead it does the same thing again: where the crystal is sure of a move, it tries fewer alternatives.
For example, after white opens with "1. e4", the crystal's confidence is 0.41. That's below 0.5, so it looks ahead, and that changes its answer from "e6" to "e5".
Results
Judged by Stockfish 17.1 on 2,002 held-out positions.
Best or near-best move (higher is better)
| Precision | One shot | Look ahead 3 × 5 | Look ahead 5 × 5 |
|---|---|---|---|
| 32-bit | 30.6 % | 33.2 % | 32.3 % |
| 16-bit | 29.5 % | 31.8 % | 31.5 % |
| 8-bit | 30.1 % | 32.0 % | 31.9 % |
Blunders (moves that lose 300+ centipawns; lower is better)
| Precision | One shot | Look ahead 3 × 5 | Look ahead 5 × 5 |
|---|---|---|---|
| 32-bit | 16.1 % | 11.1 % | 11.7 % |
| 16-bit | 16.4 % | 11.7 % | 12.2 % |
| 8-bit | 16.4 % | 12.1 % | 11.8 % |
Look ahead K × J: the crystal's K brightest moves, each tested against the opponent's J brightest replies (see Looking ahead above).
Use it
Install the neuralcrystal Python package, which runs the crystal's light path in PyTorch. Its code and more examples are on GitHub at neuralcrystal/neuralcrystal.
pip install neuralcrystal
import neuralcrystal as nc
from neuralcrystal import chess as ch
crystal = nc.load("chess-crystal.safetensors")
pos = ch.parse("rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1")
# the brightest legal move
pick = ch.best_move(crystal, pos)
# or think two moves ahead: think=(K, J) tries its 3 brightest moves against the opponent's 5 brightest replies to each
pick = ch.best_move(crystal, pos, think=(3, 5))
# or think ahead only when unsure (confidence below 0.5), as the website does
pick = ch.best_move(crystal, pos, think=(3, 5), unsure=0.5)
print(ch.confidence(pick.scores))
# ch.san writes the move in standard algebraic notation (SAN), e.g. e6
print(ch.san(pos, pick.move), pick.wdl)
The crystal's input is a picture of the board. ch.best_move draws it for you from the FEN, but you can make it yourself, save it, edit it, and pass it in:
from PIL import Image
from neuralcrystal import pictures
# the 192 × 192 board picture the crystal sees (0 = dark mirror, 1 = lit)
board = ch.frame(pos)
# save it to look at: drawn in the laser's red, 3× larger
pictures.save(pictures.frame(board, scale=3), "board.png")
# read a saved picture back: any color, any whole-number enlargement
board = ch.frame_from_image(Image.open("board.png"))
# the simulation: the light through all four passes of the crystal (E = the light leaving the glass)
E, _ = crystal.run(board)
# 64 × 64 light: row = from-square, column = to-square
move_map = ch.move_map(crystal, E)[0]
# the brightest legal move (the position tells it which moves are legal)
move, light = ch.move_scores(crystal, E, pos)[0]
# the move in standard algebraic notation (SAN: e6, Nf3, Rxd3 …), and (win, draw, loss)
print(ch.san(pos, move), ch.value(crystal, E)[0])
The picture has to be in the crystal's own drawing style. It won't read a photo or a screenshot of an ordinary chessboard. Use ch.frame_from_image to read a saved picture rather than converting it to grayscale yourself: a red picture turns only half bright in grayscale, and the crystal answers a dimmer board differently (we tried it: wrong moves and a wildly wrong win/draw/loss reading).
Files
| File | Size | What it holds |
|---|---|---|
chess-crystal.safetensors |
336 MB | 80 phase surfaces, fp32 radians |
chess-crystal-16bit.safetensors |
128.5 MB | phase wrapped to one turn, 16 bits a sample |
chess-crystal-8bit.safetensors |
64.2 MB | the same at 8 bits |
The crystal
| Part | Details |
|---|---|
| Light | 617 nm, coherent |
| Glass | fused silica, n = 1.4607; four sections in one block |
| Surfaces | 20 per section, each 1024 × 1024 samples at 1 µm |
| Lit window | 896 µm square |
| Input | the board as 96-pixel piece art doubled to 192 × 192, always from the side to move's view |
| Between passes | the camera's picture exposed from its own mean and spread, plus a quarter of that section's input added back, dithered to 17 levels |
| Output | a 64 × 64 move map and a win/draw/loss readout |
Training
Trained in simulation on chess-positions, in stages:
- Stockfish playing itself: ordinary positions, with Stockfish 17.1's move as the answer (the
teacherset). - The crystal's own games: positions the crystal reached playing against Stockfish and in its own look-ahead, each scored by Stockfish, so it learns to recover from its own mistakes (the
daggerset). - Saving a piece: positions where only one of several threatened pieces can be saved (the
dilemmaset). - Finishing games: exact endgame answers from the Syzygy tablebases, plus won endings scored deep enough to see the mate (the
endgameset). This doubled how often it mates a bare king with a queen.
Credits
The moves the crystal learned from were scored by Stockfish 17.1, by the Stockfish developers, and by the Syzygy endgame tablebases.
License
The crystal is CC BY-NC 4.0: free to use, share and adapt for non-commercial purposes, with credit. For commercial use, contact TextJam, Inc.
The neuralcrystal code is MIT.
© 2026 TextJam, Inc.


