Reflection on PokerKit

Given that this is my very first post on this website regarding poker programming (and the whole website in general), I feel obligated to write about PokerKit, my magnum opus, and my evolving relationship with poker.

I would like to start out by saying that if you would like to read a summary of PokerKit’s design, structure, benchmarking, discussion, and comparisons with other computer poker software, you would be best served to read its accompanying publication. Or, if you are simply trying to learn how to use PokerKit, you should be reading the PokerKit documentation, parts of which self-plagiarizes my paper. In this post, I will primarily talk about the backstory behind the creation of this project.

I first learned to play poker at my high school prom after-party (summer of 2019). I don’t really remember what stakes we were playing at (if at all), but I do remember finding the game to be really exciting. But, honestly, I’d never have imagined I would spend so much of my university days writing poker software.

In the very beginning of my first year (September 2019) at the University of Toronto (U of T), my friend Anthony (also a friend in high school) suggested checking out the university’s poker club. The club’s biweekly socials were frequented by the likes of math whizzes, clueless students (like myself), and degenerate gamblers. Despite the club officially forbidding real money games, a table in the corner of the venue always hosted games whose stakes ranged from 50NL to 200NL. We ended up literally going to every single social night to get our “fix”.

To be quite frank, I was a terrible player – without a doubt a slight loser overall – but I had a lot of fun playing poker (both offline and online), and was invited to lots of home games (not being a good player certainly helped). In fact, I ended up having too much fun… In my first-year praxis class, I actually got a mark of 50 (a D-) because I neglected my group meetings and even missed an exam! Schoolwork was clearly not my focus in my junior undergraduate years. It’s honestly a miracle that I ended my first year of the Engineering Science program with a GPA of 3.5/4.0.

Early 2020 was a turbulent time. In the middle of the second semester of my first year, the COVID pandemic caused all of my classes (and some exams) to be canceled and I ended up having a lot of free time. As poker was my primary hobby, I really wanted to do a software project related to it. Incidentally, I also became a co-president (events lead) at the university’s poker club. Given that the club was forbidden from hosting in-person events due to COVID-19, I decided to make an online poker room for U of T poker players. The club needed a play money poker platform where players can buy in for free without third-party payments and keep track of player statistics.

During my survey of the open-source space, I was very surprised to find that there does not exist any poker library that encodes the rules of poker akin to python-chess for chess. Ones that do encode the rules did not support varying stack sizes and only supported a single variant of no-limit Texas hold’em.

As a result, in my Django web application, I ended up having a separate package dedicated to encoding the rules of poker. After working on it furiously over the summer of 2020, I finished my project and hosted the application on https://uoftpokerclub.com/ (the website is no longer available). Other than some hiccups on the first day, the program worked reasonably well. Over the months, I made regular changes to the structure and design of the project. We ran the club completely online for the 2020/21 school year save for the final tournament.

Near the end of web application’s operation, I separated out the poker rule logic part of the project, named PokerFace, and published it on GitHub and PyPI. Obviously, this project was a result of countless iterations of solo software development. While I’m proud to say that PokerFace was a robust library, it only supported variants closely related to no-limit Texas hold’em (e.g., limit hold’em, PLO, draw games, etc.). Near the end of 2022, I came to a realization that it would be very difficult to support poker variants with public player cards (e.g., stud games, etc.) and that the general structure of the programmatic API is flawed. I decided that (re)creating a pure Python library that encodes the rules for every single mainstream poker variant would be a fun challenge to undertake.

I knew from the very beginning – thanks to my experimentations in writing PokerFace – that it absolutely makes sense for rules of different poker variants to share a substantial amount of code as they all feature some form of betting sequences, card dealings, showdowns, and more. I saw that an ideal poker library must have a variant definition system powerful enough to support most variants. Obviously, several major variants should be pre-defined for the convenience of the end-user. I also knew from experience that completely separating the interface for hand combination/evaluation and hand lookup/ranking facilitates easier development.

In contrast to my initial expectations, the development of this new poker library – named PokerKit – proved extremely challenging. I wanted the highest generalization and ultra-fine-grained updates to poker states – down to the movement of chips across the table. I dedicated almost all of my time during the summer of 2023 (after my PEY co-op internship) to writing this library. I was living in South Korea during this time. Since I lost contact with all my Korean childhood friends, I had pretty much nothing to do for the two months I stayed there. In August of 2023, I completed all the features I deemed necessary on PokerKit. This not only included definition and rule implementation of major poker variants but also tens of thousands of lines of unit tests and documentation. I still remember spending two straight days manually annotating all the televised hands that took place in the final table of the 2023 World Series of Poker (WSOP) Event #43: $50,000 Poker Player Championship (PPC).

After I published my project on PyPI, I spent several subsequent days introducing my library in the Two Plus Two Forum and various poker-related Subreddits on Reddit to get more GitHub stars (you can probably still find some of my posts). I was happy to see my project quickly garnering dozens of stars following my posts.

Another thing on my bucket list was to write a short-ish paper introducing this library. I was confident that PokerKit would be of great interest to some academic audiences, but I would have to pick an appropriate venue for the paper. The motivation for writing a paper was not necessarily to advertise my project further (I knew it wouldn’t help much). Instead, I wanted a publication to help me in my graduate school applications I was planning on submitting in late 2024 (a computer science journal publication sole-authored by an undergraduate is completely unheard of). Over the course of two days, I wrote a short 6-page paper introducing PokerKit (with some help of ChatGPT) and submitted the manuscript to the IEEE Transactions on Games on August 4th, 2023.

This paper was the first paper I ever wrote/submitted in my life. I have to admit… I had zero clue on how to write a paper. To learn the process, I consulted ChatGPT extensively to help establish the paper’s formatting, structure, and writing. With that said, pretty much every single word in every sentence in every paragraph was touched up – I meticulously edited everything down to individual characters. Still, despite my best efforts, the paper ended up reading like a company brochure. I submitted the 6-page manuscript anyway, hoping for the best.

After submitting, I continued to maintain and add new features to the library while making small edits to the submitted manuscript. About two months after the initial submission (and days after I sent an inquiry about why the paper status was stuck on “awaiting reviewer selection”) I got the results back: conditional accept with minor revision. The two reviews were very positive, but one of them wanted a benchmark on the poker game simulation. If you recall, I spent two days manually recording hands from the 2023 WSOP Event #43: $50K PPC. I simply used the code I wrote for that for my benchmark. Adding the benchmark process and results in addition to the edits I made since the initial submission, the paper ended up becoming 8-pages long. I sent it over as a new revision.

About a week later, while I was in Darwin, Australia for the 2023 World Solar Challenge, I received an email of acceptance! While I could have published it for free, I decided to pay the open-access fee to ensure that the paper was available to the public (I had some spare money). A few days after that, the paper was available as early-access on IEEE Xplore. I spent around a month or two ping-ponging the edited proofs of the manuscript back and forth. I was told by the editor that the paper would probably be formally published in late 2024.

Starting from early January 2024, I started getting reached out to by people from the poker industry for questions or consulting opportunities involving PokerKit. I didn’t really want to take them so I requested ridiculous compensations (for an undergraduate): $100 USD to $150 USD per hour. Surprisingly, they were willing to pay that much for my services. Obviously, none of them were full-time opportunities. I was able to make some extra cash this way.

I’m quite sure PokerKit is used in many modern poker software systems, but even I am unsure about the full extent of its usage. I know for sure or am reasonably certain (either through my consulting work or email correspondences) that companies like A5 Labs (AceGuardian), Phenom Poker, Buhanka Poker, and GTO Wizard (play mode) use PokerKit in their backend. It seems to also be used in other systems I don’t know about (based on the emails or GitHub issues I get that don’t specify what they are actually working on).

Some people I know have been puzzled by my decision to keep the project free and wondered why I didn’t try to milk money from the online gambling industry. As I have previously mentioned, my big motivating factor was writing a paper to help me get into good graduate schools, and reviewers would have expected a project of my nature to be free and open-source. To add on, I just like open-source, and I didn’t want to deal with the hassle that comes with selling products and interacting with clients.

I’ve dedicated my time since creating PokerKit to fostering an open-source software ecosystem around poker (and writing more poker papers). This included coming up with open-source datasets of poker hand histories (and its standard) and poker hand strengths, implementing a variance reduction tool for poker, a backend for online poker rooms, and exploring the acceleration of poker solving algorithms with GPUs.

My ultimate goal is coming up with a truly superhuman poker artificial intelligence (AI) that does not rely on fake (very human) hand distributions like traditional solvers and is capable of supporting an arbitrary number of players, variants, and chip stacks.

I feel very dubious about the whole concept of “game-theory optimal (GTO)” play in poker. Nobody seems to ask why different poker solvers give different outputs, and what happens when two players follow different solver outputs (I know the answers but does the average poker player?). Even before that, how did anyone come up with the preflop hand distributions? The whole state-of-the-art poker strategy seems like a big lie.

I believe the key to truly superhuman poker AI is to start with a reasonable equilibrium play, and later converge to an exploitative solution based on opponent modeling. PokerKit will serve as the first step in the development of such AI by enabling game simulation and game tree extraction from arbitrary initial conditions.

January 12, 2025