Haskell World logo Haskell WorldWrite code, build worlds
Games

How an Online Chess Engine Uses Immutable Game State

Watch an online chess engine think and it looks like magic: in a second it considers millions of positions, picks a move, and never corrupts the board it started from.

A chess position on screen with a branching tree of candidate moves beside it

Watch an online chess engine think and it looks like magic: in a second it considers millions of positions, picks a move, and never corrupts the board it started from. The magic is mostly discipline, and a lot of that discipline is immutability. An engine that mutated a single shared board while searching would be a nightmare of bugs, so the good ones treat each position as a value that is never changed, only transformed into a new position. That one decision, borrowed straight from functional programming, is what lets an engine search deeply, undo instantly, and verify moves with confidence.

A position is a value, not a mutable board

The core idea is that a chess position is a piece of data you can hold, copy, and pass around, not a physical board you reach in and rearrange. Applying a move does not edit the current position, it produces a new position with the move played. The original is still there, untouched, exactly as it was. That is immutable state, and it changes everything downstream. An engine that can hold the current position steady while it explores a hundred alternatives never has to worry that one line of play has secretly scrambled the board another line depends on.

Searching a tree of positions safely

An engine explores a tree: from this position, try every legal move, and from each result try every reply, and so on. If each node shared and mutated one board, backing out of a line would mean carefully undoing every change in exact reverse, and a single missed undo would poison the entire search. With immutable positions there is nothing to undo. Each branch works on its own value, and abandoning a line simply means dropping a reference. The search becomes a pure exploration of values, which is both safer and far easier to reason about when something goes wrong.

Undo for free

Players expect to take back a move, and online engines expect to as well, constantly, as they explore. With a mutable board, undo is a feature you build and debug. With immutable positions, undo is just keeping the previous value and going back to it. The history of a game becomes a list of positions, each derived from the last, and stepping backward is selecting an earlier element. The feature that costs real effort in a mutable design is nearly free in an immutable one, which is a recurring theme once you commit to not changing data in place.

Make-move as a pure function

The heart of an engine is a function that takes a position and a move and returns the resulting position. Kept pure, that function depends only on its two inputs and produces only its output, with no reach into global state. Same position and same move, same result, every time. This purity is what makes an engine testable and parallelisable. You can hand different positions to different cores with no fear they will stomp on each other, because none of them shares mutable state. The engine scales because its central operation refuses to touch anything it was not given.

Verifying a move without trusting the client

An online chess engine cannot trust a move claimed by a player's browser, because a tampered client could send an illegal one. The server recomputes: it takes the known good position, applies the submitted move through the same pure function, and checks that the result is legal. Because the position is immutable, the verification cannot accidentally corrupt the real game state even if the move is garbage. The engine tests the move against a copy that is really a value, confirms or rejects it, and the authoritative position is never at risk during the check.

Comparing positions and spotting repetition

Chess has rules about repeated positions, and an engine needs to recognise when the board has returned to an earlier state. Immutable positions make this a clean equality question: has this value appeared before in the history. With mutable state, comparing positions means snapshotting and diffing, which is fiddly and error prone. When each position is an immutable value, you can hash it, store it, and check membership in a set, turning an awkward rule into a straightforward lookup. The functional representation makes a thorny bit of chess law almost trivial to enforce.

The discipline behind the magic

An online chess engine looks brilliant, and under the hood a great deal of that brilliance is the refusal to mutate. Positions are values, moves are pure transformations, undo is a step backward through history, verification runs against a safe copy, and repetition is an equality check. None of these is exotic, and together they are what let an engine search deeply without drowning in bugs. The lesson reaches well past chess: when state stops changing in place and starts flowing as values, a hard problem turns into a manageable one, which is the whole case for immutability.

Frequently asked questions

Why not just mutate one board for speed? Mutating a shared board seems faster but turns search into a minefield, because every line of play must perfectly undo its own changes or corrupt the others. Immutable positions avoid that entirely by giving each branch its own value, and modern engines use efficient copying and sharing so the cost is modest compared with the bugs it prevents.

How does immutability help an online engine verify moves? The server takes the trusted current position, applies the player's submitted move through the same pure make-move function, and checks the result for legality. Because the position is a value that cannot be changed in place, a malicious or broken move can never corrupt the authoritative game state during the check, which keeps verification safe regardless of what a client sends.

Is detecting a repeated position really easier this way? Much easier. When a position is an immutable value you can hash it and store it in a set, so recognising repetition becomes a simple membership check against the game's history. With a mutable board you would have to snapshot and compare states manually, which is fiddly and prone to subtle errors, especially under the time pressure of a live game.

Values, not boards

An online chess engine earns its apparent genius through a plain commitment to immutable game state. Positions are values, moves are pure transformations, undo is a walk back through history, and verification never endangers the real board. The ideas come straight from functional programming, and they turn the chaos of deep search into something an engine can reason about move after move without ever scrambling the game.

SR
Sonja Reiter

Sonja Reiter contributed to three major open source projects and started writing documentation when she noticed most tooling guides were written by people who had never taught anyone to use them. She covers build tools, package ecosystems, and the invisible quality-of-life differences between development setups.

More posts by Sonja

More in Games

01doorganico 084goad 3hot8 4465456 after5internprogram ahandfulofblessings ahmadpc ahomcybersecurity allodialresources annodex antiquesandperiodcollectibles aotc asianworldkashmir beedlectrics bloggertemplatefree bluefeatheragency bodyweightsolution campaign08blog carfixadvisor catstreetcollective cbstvsports cnfanspurchasing committeeof500yearsofdignityandresistance covertopsdjs cs-kaiyuangame cuestacomunicaciontotal cxoutlet dancebetgame deskgearhub destinyvillastay detectmagazine di33 diamondsteelbuildings donmo dyanadropship emarsysfinance emimattl escapechan eskitarih evautoplay everythingweddings-orlando farmzone feedviewerapp foxstudiosscratch gamevui123 gleasongrade greetingsday hacklabasu iw-kaiyun jagoanproperti jilidskripsi joltbusinessfinance juegodepokergratis juegospucca kaeru-festival latestmehndidesigns lestanzediottaviano litemagazines localcommunityhero lustrsazan mariashebets menswheels newwebstechs1 nikkit ootheday oxigenvpn plurfitness prefetial probudgetcarpetcleaning psychicmrsmartin pyaten qvantor rejoignezlogis rexzbot riselayouts ruchin rwxqsgd5 sakaltime shibiaowang shop-bot skrtips strcoding tetapatrium topselller uneplanteartificielle vipertechcr webtech1223411 wo-kygaming yamaha-mekar yeknava yoybuysheets zenunwa yamaha-mekar jilidskripsi ankertoto ankertoto ankertoto ankertoto