Python Playtesting: Crafting the Perfect Board Game - Alla Barbalat - 2026
Watch on YouTubeVideo summary
Alla Barbalat presents a talk centered on the intersection of board game design and Python programming, specifically focusing on playtesting through simulation rather than traditional human testing alone. Drawing from her background as a former lawyer and current organizer for PyLadies San Francisco, she shares how she transformed an initial idea involving dark satire and cooperative-to-competitive mechanics into a functional prototype using Google Sheets before migrating it to a terminal-based Python application. Her primary goal was not necessarily to create the "perfect" game immediately but to use code as a tool to iteratively refine game logic, balance strategy against luck, and ensure that win conditions were achievable without relying solely on randomness.
To evaluate whether her game design decisions resulted in an enjoyable experience, Alla employed three distinct Python-based simulation methodologies: rudimentary functions focused on maximizing specific metrics like wealth or population using breadth-first search, random action scripts to test baseline viability, and Large Language Model (LLM) bots equipped with varying levels of context. The results were surprisingly revealing; while the game was initially unwinnable through random play, simulations showed it could be won twice out of one hundred attempts purely by chance, a statistic that shifted significantly when strategic algorithms were introduced. These quantitative data points allowed her to identify issues such as games hanging indefinitely due to running out of event cards and helped her adjust the number of rounds from an arbitrary limit to a more satisfying duration based on actual playthroughs.
The process highlighted critical insights into game balance, demonstrating that while simulations could quickly test for winnability and resolution rates, they sometimes lacked the nuanced understanding required to judge "fun" without human intervention. Alla found herself having to step back from purely automated testing to manually play through scenarios in her terminal version of the game, which provided context on how players might perceive impossible hands or trade-offs that a simple maximization function would overlook. Ultimately, she concludes that while the prototype is not yet perfect and lacks fully developed chaotic competitive modes, the project successfully achieved its objective by providing a playable foundation for friends to enjoy without fear of an unbalanced experience, proving that Python can effectively turn abstract creative questions into testable hypotheses.
Read the full video transcript
So, we've had a couple of
pretty heavy serious type talks coming
up immediately before this. Time for a
bit of a bit of a change of pace.
This talk is about
play testing with Python and creating
board games. Please welcome Ala.
>> [applause]
>> Hi everyone. Thank you for that intro.
Very excited to be here today and talk
about Python play testing crafting the
perfect board game with Python. Really
excited to
welcome you all here to my talk today.
Thanks for joining me. Before I get
started, I would love to get a sense of
how many folks here enjoy playing board
games.
Good, that's probably like the majority.
And then I'm curious
about how many of you have either made
or designed a board game?
A good handful of people. Wow, that's
impressive. That's more than I would
have expected. So, that's good to know
that
maybe I could get some good feedback
from folks after this. And I'm also
curious of those folks that have made or
created board games, have you simulated
them or tested them with Python?
All right, just one. So, be a really
wonderful to chat with you after.
Awesome. And with that I'd love to get
started by introducing myself. I am a
former lawyer and I feel like starting
my professional career as a lawyer has
really shaped how I view the world. So,
I included that. I also have a really
crazy shepherd husky mix. So,
she's going to be a little bit in this
presentation too. So, I hope you all are
prepared for that. And then I'm on a
somewhat of a career hiatus at the
moment. And during this hiatus I
restarted the San Francisco chapter of
PyLadies.
>> [applause]
>> Thank you. And I bring that up because
one of my goals as the current lead
organizer for PyLadies San Francisco is
not just it to like of course improve
the Python community and share
information and you know, enjoy each
other's company. But one of the things I
really love doing is creating a platform
for new voices and amplifying voices
that might not get heard otherwise. So,
I really love finding speakers that
maybe have never given a talk before,
maybe are really nervous about giving a
talk or maybe feel like, oh, I have a
personal project, but make that into a
talk? So, something that I've really
been working on is kind of inspiring
those folks and giving them the
confidence to present whether it be at
the PyLadies San Francisco meetup or at
a conference or another space. And I
hope that this talk in some way also
serves as inspiration for that.
Also, I put this in italics.
I guess I'm also a board game creator. I
don't really think of myself as that.
Thank you.
This is the first board game I've ever
created. I think of myself more as
someone who enjoys playing board games.
I really love social games, cooperative
games, and competitive games in the
right environment with the right group
of friends. So,
definitely maybe a little more
interested in social and co-op games.
So, with that I'll walk you through a
brief road map of what I'll be talking
about today. First, we'll discuss
building a board game prototype in
Python for fun to make it fun.
Using simulations to test the game
logic. And then looking at what worked,
what could have been better, and what
comes next. So,
the idea for this game was like very
random. Like I said, not really a board
game designer.
I've had a lot of different hats that
I've worn professionally, but none
in the game space. But one day I was
standing in line at a restaurant waiting
for the bathroom and I was struck with a
moment of inspiration and I thought,
wouldn't it be cool if I created
this board game and it really had two
ideas that really sparked my interest.
The first was to create a game that had
a very dark
satirical
political statement as the basis of the
game. So,
I'll get into that a little bit more,
but not enough to hopefully make people
feel uncomfortable. And then
the other idea was to
have a board game that starts out as
cooperative and then
at some point in the game there's this
chaos mode that's triggered and the game
becomes competitive. And my hope was to
have a variety of different competitive
conditions that could be created. So,
different win loss conditions based on
whatever chaos mode was entered. And
unfortunately with this prototype, I
didn't actually include the chaos modes
yet. Though very excited to work on
those eventually. And
So, as this process was going, I
got inspired. Never really thought I
would take the inspiration to heart, but
somehow managed to put the initial ideas
into a Google spreadsheet which
I don't know if it was my lawyer brain
or something else. I was like, oh, a
spreadsheet. That's like natural place
to put a design for a board game.
So,
started there and then
built out a lot of the game and then
made my partner play some rounds with
me. And
even outside of the fact that obviously
there was no UX UI because we're playing
from a spreadsheet, there were other
things missing and lacking in the game
logic that I saw needed improvement. And
even though it wasn't especially fun, my
partner is still with me. So, that's
good.
>> [gasps]
>> And I was inspired to
take that spreadsheet and then put it
into a Python program with the goal of
then simulating the game a bunch of
times to figure out how could I improve
the game logic?
And
I'll just make a brief note that
unfortunately because I started with the
spreadsheet, I was like, oh, it'd be
really easy just to like get a bunch of
CSVs and import the game data that way
which definitely got me up and running
really fast. But I feel like if I had to
start over from the beginning, I would
not be importing the game information
via CSVs. So, that was a whole weird
process that I went through that now I
might have to change eventually. But I
do have a terminal based version of my
board game. And
as you can see there is a very, let's
say, compared to other board games, kind
of boring
map here. So, the initial idea here was
that there would be different spaces
that the characters can move through.
And I'll just give you kind of a very
brief overview of what the game entails.
So,
basically, like I said, it's very dark
satirical take on
let's say a political system. So, in
this game
>> [laughter]
>> there is this unstable monarchy that is
trying to accumulate wealth and their
actions have consequences and that
affects the townsfolk. And
depending on the consequences, it can
destabilize the kingdom and lead to a
loss condition in the game. And the way
that the game operates is every player
is a character. I have three characters
so far. You can see them on the slides
and every character has its own
character deck and
they play three cards of a five card
hand
for each turn. And then at the end of
everyone's turn at the end of the round,
an event deck card is drawn. So, that's
just like the basic game mechanics of
this game. And
once I put this together, then next step
was to figure out, okay, I have this
terminal based Python program. Now I
have to run these simulations to improve
the game logic to make the game fun. But
what is fun? So,
that was a big question to answer. A
little bit like more of a big
philosophical question than I think I
can answer in this talk. Though
I could try. I feel like I might get
removed from the stage. In any case, so
I needed to pare down this question of
what is fun to specifically focus on
what is fun in terms of
the specific board game that I'm trying
to make. And so, what's great is that
with Python, I was able to
ask this question in a much smaller
scale for very small pieces of the game
so that I could build iteratively in the
game logic to figure out what would be
fun in terms of the game logic for this
specific game. And
while
I was working on that, I
figured this is kind of the
underlying theme for how I'm going to
run my simulations and how I'm going to
figure out if the game is fun. So,
before I did any simulations, I put
together this expected criteria for
evaluation. And
a lot of it had to do with like the
length of the game. Is the game too
long? If it's too long, people get
bored. And what are like the lengths of
the rounds? If the rounds are too long,
then people are going to get bored while
like someone else is playing. And how do
I figure out the movements? That was
definitely an issue in the spreadsheet
version was moving around with felt a
little bit unpurposeful. So, I had to
basically work on that
in the revised version of the game. So,
those are like relatively quantitative.
On the more qualitative side, when it's
to figure out like what are
understandable and achievable goals for
the players in the game.
I also wanted to create a balance of
strategy and luck. So,
if
it's impossible to win the game, then
that's not going to be a lot of fun.
And if you can like randomly do anything
and win the game, that's also not fun.
So, figuring out how much strategy do
you need, how much luck do you need, and
is it possible to win the game? Which is
very important for a cooperative games.
With competitive games, to a certain
extent like the level of difficulty in
the game doesn't matter as much. What
matters is the specific competitors that
are playing the game. So, you can have a
really easy game like tic-tac-toe, and
two people that have very good at are
very good at tic-tac-toe, and they're
still enjoying the game even though it's
very
simple. But, if you have
a really simple cooperative game,
then it's not going to be that fun if
you could just easily win the game. In
the same vein, if it's too hard and you
can never win, you're not going to
invest in the game or want to play. So,
those were kind of the initial ideas. I
also wanted to look for replayability.
That's also a little bit hard to
determine. So, these are like more of
the subjective criteria that I started
out with.
Then, I actually started testing.
So, I used three different
methodologies.
And so, these are all like Python-based
simulations that I ran. The first was a
fairly like rudimentary
series of functions that I ran that were
maximization-focused
with breadth-first search for strategic
movements. So, the strategic movement
was limited only for the specific turn
in question, and it was specifically
only to maximize
the player's wealth or the townsfolk
population. So, there was other things
that you could maximize that
this function did not consider. And
then, there were other trade-offs and
costs that were not considered. So, very
like rudimentary, very basic strategy
for playing the game.
Then, the second methodology I used was
just a random action function. As I
mentioned before, it's really important
to have a game that's
winnable through strategy, especially
for a cooperative game. So, the idea
here is you take this random action
function and then see,
"Well, if I just do random things, can I
win the game? And how quickly would I
win or lose?"
So,
that was a very uh interesting
methodology to use in this particular
game. And then, I also used a series of
LLM-based AI bots with varying amounts
of context on the game to see how they
would perform and get additional
insights.
So,
with that in mind, here's just an
example of some code that I actually
used in my simulation. This is for the
randomness. So, basically you can see
that
you are basically doing like the most
random thing possible, and then you
would just do that over and over again
for every single player's turn
and see what happens. So,
what was interesting is I actually
thought with the random action that
it would never win. So, I was really
surprised to see that with random
action, this game actually was won
twice. And
these specific graphs that I'm showing
are from simulations I ran last night.
So, I ran 100 simulations on random
action and 100 simulations with the very
rudimentary strategy of just maximizing
wealth, maximizing townsfolk, moving
strategically per turn with
breadth-first search, and then not
considering other costs and
uh features of the game. So, the random
action, two of 100 wins. I mean,
obviously that's not a lot, but
previously when I had run the random, I
had never gotten any wins. So, two in
100 still was like extremely surprising
to me.
Then, there were 58 losses. That That
made sense. And then, there were 40 that
never reached a resolution. And so,
uh
I kind of thought that I had just
underdeveloped the game because I only
included 17 event deck cards. So, after
17 rounds, the game ends because there
are no more event deck cards. And I was
like, "Oh, I need to like add more."
But, actually this ended up being a very
good feature for this prototype because
it prevented the game from going on too
long.
Uh especially like later when I talk
about like the LLM-based
bots, like it would have been like if I
had 100 event cards and they just kept
playing, it'd be like way too many API
calls for me. So, this ended up being
perfect. And I do actually think over
like even 17 rounds is too long for this
game. So, it was really good to see that
with the random action, not only are you
like probably going to lose. Like
otherwise, the game also just lingers.
And so, the lack of resolution was also
to me a good sign because the game is
really about trade-offs. And if you're
not using any strategy, you're not
considering the trade-offs that are
built into the game. So, when you take
an action, there's a lot of consequent
actions that happen as a result that
would just never happen if you're
playing randomly. So, with this very
rudimentary function that I mentioned
that basically maximizes wealth,
maximizes townsfolk population, doesn't
maximize anything else, and then
strategically moves through the board
per turn, I was able to increase from
two to 12. And I was actually surprised
by this. I thought there was going to be
a higher win rate here. So,
this was interesting. I mean, it's
probably overall good because there's a
lot more strategy and a lot more
consideration of trade-offs that should
be made in the game. So, uh this was a
good result. And then, obviously
there's also a lot fewer games that
hang. So, this was also a really good
result because that means that
if you're actually using some strategy,
you're more likely to end the game,
which is a good result. You don't want
to play a game that has no resolution.
It's more satisfying to get a resolution
even if you lose than to have no
resolution at all. So, this all was like
looking very good. And then,
I also last night ran 20 simulations
with the LLM-based bot. And this is like
the most sophisticated bot that I had
playing the game.
And they're just making API calls to uh
an LLM, and they won about half the
time. So, I feel like this is pretty
good. Like this seems like reasonable.
If the bot's like running about half the
time, has a lot of context on the game.
So,
I felt pretty
satisfied with that. And so,
after I'd run all these simulations, I
actually Well, not just these
simulations, but I ran like a bunch more
that aren't on the slide. But, during
this whole process of running these
simulations, I ended up using very
different criteria to evaluate the
simulations than I mentioned previously.
So, unfortunately, I didn't really get
all that like time-based data because
the simulations I'm running directly in
Python that aren't based on the LLM run
instantaneously.
And then, the LLM-based ones often times
actually took way longer than expected,
especially the ones that were like
getting a lot of context, but still
wouldn't be in any way like matchable to
a human being. So,
uh before I created my more
sophisticated LLM bots, I was having a
trouble getting like win results at all.
So, I actually weakened the win
condition, and then I was able to
achieve a win with the LLM bots. So,
then I went back, and I was like, "Well,
what's going on here? Like, I need to
actually sit down and just play the
game." So, I took a step back
to some human in the loop, and I played
a three-person cooperative game by
myself in the Python terminal. And took
actually a really long time to play 10
rounds, like surprisingly long.
But, I was able to win the game. I do
know every single card and like have a
sense of like what could happen at any
moment in the game. So, that could have
also helped. But, uh from that, I
figured about like 10 rounds max for
like a three-person game would be good.
And I addressed the criteria that I used
to evaluate the simulations. I also then
went back to the original win condition
and adapted the LLM bot so that I could
get better performance from them.
So,
uh basically, the actual criteria I used
were like the number of rounds.
So,
like looking at the 17 round max, like
did the game end or not? The variance in
game length. So, with the random
function, I was able to gain like uh
lose the game within like three rounds,
which was really interesting. So, kind
of looking at how many rounds were there
total. Looking at end state conditions,
so like the proximity to the win
condition if the game was lost or if the
game was just hanging.
And then, uh I also ended up looking at
these other things that I didn't really
consider as much before. Like handling
impossible hands was really important.
And
also looking at the AI reasoning for the
LLM bot decisions and their asks. So,
and then obviously, as I've already
discussed, the effects of random action
and the effects of rudimentary strategy.
So, with that, did I craft the perfect
board game? I'm sure it's pretty obvious
the answer is no.
But, I feel like I accomplished my goal
because I now have a prototype that I
feel comfortable
playing with my friends without having
to worry that I won't have friends
after. So,
yeah, goal accomplished. So, this was a
really fun project and I feel like I
learned a ton about game design and how
you can use Python to simulate.
And with that, I have a lot of like
possible next steps for myself that I'm
really excited about. Definitely want to
actually play the game with friends.
That would be really cool. Hopefully
with the physical version that it maybe
I'll just have one prototype version
that I create. Uh definitely want to go
back and add the competitive chaos modes
that I mentioned. I want to build out
more features and characters in the
game.
And I really want to look at more
complex logic for the max functions.
Like I said, they don't really look at
trade-offs fully, so that's definitely
something that I could incorporate into
the game.
Also want to look at
potentially doing machine learning
algorithm-based AI bots. So, kind of the
old-school AI and that would work for
both like cooperative and competitive
modes. And then potentially for future
competitive modes, I could do mini max
or game engines. So, like a lot of
future possible simulations that I could
be running, as well as money Carlo
simulations.
And
that So, hopefully
the key takeaways from this talk are to
take a chance on creative projects. And
sometimes when you have this creative
project, you can use Python to
take a creative question and turn it
into a testable one.
I will say, sometimes you have a project
on the back burner or you just don't
feel confident working on it or you're
not sure about your talk proposal. And I
really hope that
this talk inspires you to go on and do
that. Often times, I very begrudgingly
take my dog out into the rain.
And then we get to walk around and see
beautiful rainbows together. So,
uh hope for many rainbows on your Python
path. And happy to answer any questions
or connect on LinkedIn.
>> [applause]