This is a new major release.
See the Introducing OpenSpiel 2.0 blog post for an overview of new features and demo of the OpenSpiel MCP Server.
Several of the OpenSpiel games are now being used in Kaggle environments as part of the Kaggle Game Arena, which measures the frontier of model capabilities through dynamic game environments. Much of the functionality added between 1.6 and 2.0 was to support games for the game arena.
Major Changes and Improvements
- Core API: State, observation and action structs
- Core API: Action struct only games for large / open-ended action spaces (see e.g. Crossword)
- Core API: Standard trajectories
- Add optional starting states to OpenSpiel states (
State::StartingStateandState::StartingStateStr); generally supported by serialization - Add language model fine-tuning and QLoRA examples (Gemma 3 via Kauldron, and other models via huggingface, including Gemma 4)
- Add MCP Server example (see demo in blog post linked above)
Support and Process changes
- Support Windows installation on PyPI
- Add Linux arm64 wheels to CI build
- Update to C++20 as standard
- Update version of Abseil
- Add
nlohmann::jsonandpybind_jsonas dependencies (required for structs) - Add
pokerkitas an optional dep (for python pokerkit wrapper game) - Remove OR-Tools from CI testing
- Exclude 4P Quoridor from CI tests (nondeterministic failure)
- Add support for Python 3.14
- Drop support for Python 3.9 and 3.10
- Remove Julia, Go, and Rust API from CI tests and mark them as unmaintained
- Remove
cluas an optional extra dep - Remove TF1-based examples
- Optional python dep: remove cvxopt, add cvxpy
Games
- Ant Foraging (python)
- Antichess
- Banqi (Chinese Dark Chess)
- Capture the Flag
- Crazyhouse
- Garnet (mean-field game)
- Gomoku
- Go Fish
- Hangman (python)
- Latent Tic-Tac-Toe
- Lines of Action
- Poker game via pokerkit wrapper (python)
- Repeated Leduc Poker
- Repeated Poker
- Shogi
- Snake
- Social deduction
- Xiangqi (Chinese Chess)
- Yacht
Algorithms
- Elo rating system (batch version, based on MM algorithm of Hunter '04)
- ESCHER algorithm (python)
- Minimax solver for small two-player zero-sum perfect info games
Improvements and other additions
- Backgammon: remove unnecessary id from ActionToString
- Backgammon: remove filtering of duplicate actions
- Backgammon: restrict nuber of turns per game, reporting a draw if reached
- Backgammon: change chance node so that it's uniform random
- Bridge: Allows specifying the dealer in bridge. Previously it was always North
- Bridge: Change observations strings to be easier to tokenize and more standard
- Fine-tuning on Gemma and other language model example and colab
- IS-MCTS: change tree policy PUCT -> UCT
- MCTS rollout evaluator: add max length
- Make Leduc's string representation clearer
- Add game exclude lists to python
games_sim_test.py univeral_poker: fix game strings- Tests: add Fenchel-Young test to VasE SCO test
- Libtorch AlphaZero: improve performance of tensor creation
- PlayerId as a strongly typed enum with Python IntEnume bindings
- Add Monte Carlo odds estimation to
universal_poker - Add hand ranking and best 5-card functionality to
universal_poker - Amazons: support generalized board sizes
- Add option to Connect Four for egocentric observations
- Update checkers observation tensor to be standard (not egocentric, but allow egocentric through a game parameter)
- Add Elo as a voting method so it can be used in the same way as other VasE methods
- Hex: add swap rule
- Cleaned and refactor Deep CFR versions for torch and jax
- Refactor JAX NFSP and DQN
- Add DQN, NFSP, and Boltzmann DQN colabs
- Add support for multigame strings and multigame string loader
- Add option to store all world states in an info state tree
- Add python bindings for InfoStateTree
- Add custom errors and better error handling to
rl_environment.py - Update old Docker scripts
- Add support for basic general way to define heuristic evaluation functions
- Add general .sgf game format reader (covers a subset of the entire spec)
- Euchre: add ResampleFromInfoState and ObservationStateString
- Hex add option for plain observation
- Expose to python bindings:
SampleActionand Go game properties - Release GIL in MCTS and ISMCTS step methods
- Optimize SpanTensor memory views using Pybind11 Buffer Protocol
- Implement ObservationString and InformationStateString for cribbage
- Implement InformationStateString for Kriegspiel
- Add Wall-clock time controls for MCTS and IS-MCTS
Fixes
absl::MutexLock: use new way now from new abseil version- Chess960: fix serialization
- Crazy Eights: bug fix, initial open card should be regarded as played
- Battleship: fix variant and use
std::variant file_testfix nondeterministic bug due to collisions- IS-MCTS bug fix when allow_inconsistent_action_sets=True (node prior could be out of date and need to be repopulated)
- Python crowd_avoidance: fix the data type of the forbidden states
- Tic-Tac-Toe: fix player string for special players
- Ultimate TTT: fix terminal condition and game length
- Universal poker: fix ToString at chance nodes
- Change
absl::optionaltostd::optionalalmost everywhere - Sliding window accumulator fix when zero data points
- Fix incorrect policy indexing in PSRO update_agents
- Fix Deep CFR convergence on Kuhn poker
- Fix Connect Four observation tensor
- Fixed NeuRD and its test for pytorch
- Fix outstanding issues with Reconnaissance Blind Chess (RBC)
- Fix incorrect logging call in JPSRO algorithm
- Fix bare assert and runtime checks in poker and alpharank
- Fix Deep CFR pytorch advantage network learning
- Fix bargaining obs and infostate tensors (always a 1 bit in the agreement)
- Fix deterministic shuffle in Gin Rummy ResampleFromInfostate
- Fix Colored Trails ResampleFromInfoState
- Fix void-inconsistency in
OhHellState::ResampleFromInfostate - Fix ObservationString for Kriegspiel
- Fix boundary checking in Nine Men's Morris
Several other small fixes (Crazy Eights, Gin Rummy)
Documentation
- Update Windows MSVC instructions
- Add doc strings to MCTS example
- Add minimal docs for mean-field games
- API reference: document 37 undocumented common state and game methods
- Add reference to spielviz in the visualization section
Acknowledgments
Thanks to Google DeepMind for continued support of development and maintenance of OpenSpiel.
Special thanks to the Kaggle Game Arena team for their contributions and support. Several new features for this release were inspired by use cases involving LLMs that came up in collaboration with the development of game arena.
Special thanks to:
- @jhtschultz, @dhennes, @rezunli96 for contributions, discussions, and help organizing and planning the release
- @alexunderch for the AlphaZero JAX port as well as many fixes, refactors, and general support
- @visheshrwl for Windows pip/PyPI support
- @gmweinberg for many excellent game contributions
- @Drazcmd for many poker fixes, new poker variants, and help supporting game arena
- @fuyuan-li and @bbrianxiao for extending the fine-tuning examples to Hugging Face and Gemma 4
- @parvxh and @harmanagrawal for initial implementation of AlphaZero JAX
Thanks to all of our contributors: