Coding Baseball

The purpose of this post is to talk about a coding project I'm working on. Basically allow you to get inside my brain and hopefully help educate and entertain.

If you never want to make money, find a niche market, and then target a niche within that already niche market.

Do you like Pokemon or Magic the Gathering? Well, you obviously love sports too! And not just any sport, but a sport no one under the age of 30 watches… baseball!

That’s MLB Showdown. Here’s the rub, I fucking loved it.

Make a team of your favorite players, play a quick game of baseball, and see how they perform? Sign me up! I only played this game for one summer in 2003. I even went to a regional tournament to play against other niche nerds. I had to carry paper towels with me all the time because of how wet I was making the ladies.

I collected baseball cards as a kid. I obsessed over the stats on the back of the cards.  Seeing a player who hit over 30 home runs or batted over 300, made me stare even longer. I imagined what it would be like if my beloved Cubs had players like this on their team.

MLB Showdown allowed me to create my own baseball team with their strengths and compete against other people’s fantasy teams. Besides pitchers and batters, they also introduced “strategy” cards. These cards are very much Magic the Gathering blue spells. Allowing you to manipulate dice rolls and change the outcome of at-bats. You get to be the owner, manager, and fan as the magic unfolds.

Unfortunately, Wizards of the Coast stopped producing MLB Showdown in 2005. But since my Dad told me about how I should hold onto my cards and not glue them to posterboard or stick them in the spokes of my bike, I still have them all in my basement. When a conversation came up recently with my kids about sports cards, I brought out the box. Within 10 minutes my son had the playmat out and was trying to figure out his best possible lineup.

As a parent, you want what’s best for your kids. You try your best to not push your ideals on them, but I’d be a liar if I told you it wasn’t awesome when I saw my son absorb the game like I used to. All I wanted to do was play that game with him.

The rules of a basic game are simple enough. You form a team of batter and pitcher cards. Each card has a key number, “on-base” for batters and “control” for pitchers. You then roll a twenty-sided die and add that number to pitcher’s “control.” If the result is greater than the batter’s “on-base”, the pitcher wins, otherwise the batter wins.

example MLB Showdown card

The other key data on each card is a table of values with various results. You roll the D20 one more time to determine the outcome of the at-bat. If the batter won, you’re more likely to get on base, and depending on the batter you may be more likely to walk or get a home run.

We played a simple game, picking out teams that stayed under the salary cap, but didn’t use strategy cards. I couldn’t find my D20 so I asked Alexa to roll a twenty-sided die. I then got bold and found out she responded to “roll D20.”

As we played the game I realize that every action we were doing could be replaced by a computer. Without strategy cards, it’s basically Candyland after you’ve set your lineups.

If you’re just playing this basic version of the game, you should be able to run Monte-Carlo simulations and then use sabermetric tools like WAR to figure out who the best players are.

Is it all about “on-base” and “control” or do certain table values that give you the edge? You could theoretically use some machine learning to try to determine which aspects of a player are most valuable and then see which players have the best values for the lowest price.

Studying the Game

Let’s start with a basic hypothetical scenario. Build a fictitious offensive team out of multiple copies of the most expensive card in the game.

27 ASG Barry Bonds | Giants | LF-RF+0 | L
Points: 910 | On-Base: 14 | Speed: 14
SO  GB FB  BB   1B 2B HR
1-2 3  4-5 6-14 15 16 17+

Barry gets on-base 90% of the time and hit’s a home run 20% if he has control.

This stacked team will have to face a team of the best pitcher available.

112 SS Pedro Martinez '97 | Expos | Starter | R
Points: 830 | Control: 6 | IP: 7
PU  SO   GB    FB    BB 1B    HR
1-2 3-11 12-14 15-17 18 19-24 25+

Pedro gets a strikeout 45% and an out 85% if he has control.

I’m setting up a basic version of the game that doesn’t have to worry about strategy cards, player icons, positions, or substitutions. Start small.

So what happens if I played 1000 games of Pedro v. Barry’s?…

Brief Coding Theory Interlude

One step before writing code is figuring out what your “objects” are going to be in your system. “Object Oriented Programming” has become the defacto standard for most companies, but please know that objects have their place and time.

What objects do we have in our simplified version of the game? Let’s look for nouns we’ve used so far… batter, pitcher, at-bat, and game.

A batter faces a pitcher during an at-bat.
There can be multiple at-bats in an inning and multiple innings in a game.
At-bats can have multiple outcomes and we’ll need to keep track of the base runners, the score, and the number of outs in an inning as well.

Another key to writing code is to eliminate duplication and repetition.

For example:
a batter and pitcher are both baseball players, they’re also players, who are professionals, who are citizens, who are humans…

https://imgs.xkcd.com/comics/the_general_problem.png

It’s always a struggle between making code re-usable and abstraction for abstraction. Take some time to think about what your app may look like and use in the future, but don’t try to create some library that anyone can use for anything.

Every at-bat should have the same rules that are followed. The code for that at-bat should be very re-usable. It also needs to handle all situations. For instance in this game, if you ground out and there is a runner on first you may hit into a double play. We could make this simpler and not allow double plays in our game, but I think it’s an important piece to handle.

I will now attempt my best at breaking down what happens in an at-bat that we can easily transition to code…

  1. A batter and a pitcher are needed for an at-bat.
  2. A 20-sided die is rolled.
  3. The number rolled is added to the pitcher’s control. This result is used to determine who “won” the at-bat.
  4. A 20-sided die is rolled.
  5. The number rolled is looked up in the table of winning player (batter or pitcher).
  6. The outcome of the at-bat is the value we looked up in the table.
  7. This outcome can be one of the following:
    1. PU (Pop-Up)
    2. SO (Strikeout)
    3. GB (Groundball out)
    4. FB (Flyball out)
    5. 1B (one-base hit (single))
    6. 1B+ (one-base hit that could turn into a two-base hit)
    7. 2B (two-base hit (double))
    8. 3B (three-base hit (triple))
    9. HR (four base hit (home run))

A piece that is tempting here for many seasoned developers is to start abstracting out an at-bat. You want to make your code as flexible as possible, but you also don’t want to partake in premature optimization. For instance, you probably don’t want to hardcode the fact that it’s a twenty-sided die (although this is fairly common in tabletop games). Because maybe you want to change the player’s tables and on-base/control to be more precise. Changing those numbers don’t really change an “at-bat.” But I would advise against making the order of an at-bat more flexible or dynamic. You should make the code easy to read, but you don’t need to create some abstract object to handle “at-bat event ordering.”

Naming is Hard

Before we can write our at-bat function, we need to define our batters and pitchers objects. The first major question to answer is if we want to merge these objects into a single player object.

I vote yes. I win.

The hardest problem in software development is trying to name things. “player” seems straightforward, but you have to remember that there are going to be people playing our game that we may refer to as “player(s)” Therefore I’ll reserve “player” and go with…. fuck… I don’t know.

I could say “athlete,” but esports players can now be considered athletes and athlete is generally not a common way to describe a baseball player. We could go with “baseball player” or “MLB player”, but since we know the game is already about baseball, it’s redundant. I probably want to stay away from MLB too for now in case we turn this game into more of a fantasy game and have made up players… which usually ends poorly.

What if we go with “player” and then just call our game players “users”? They are using the game, but really they are playing against each other. Maybe they are the “owners” of a team?

Now we’re getting deep into the weeds… but putting the user of your software first is important. If this becomes an actual app/game/site that makes money, how would we manage our customers? I hate ads, so it would have to be a subscription model. Or a model where you can buy packs or earn certain cards. Someone could set up an account with us and buy multiple cards and create multiple teams. These teams would also be able to participate in tournaments or seasons. This is a long way of saying that I think that for each game, there are two “owners”, who each have a “team” that has “players.”

A week or month or year from now these names could change, but they generally don’t. You look at code from three years ago and you say, why the hell did they call this “user” instead of “account.” The answer is simple, either they didn’t put enough time into thinking about all their objects and the long-term version of the application, or they did the best they could with what they had.

The Code

I’m assuming you’re starting from scratch in coding and that’s hard. I’m sure I will miss some basic things and I’ll also spend too much time on things you already know. We will start with some basic code to get us going. Let’s create a webpage that rolls a twenty-sided dice and shows the result.

But before we can write the code, we need a place to store the code so you can view it. I’m going to use the widespread standard of github.com. You can create a user there if you want, but it won’t be necessary to just view the code. If you have questions or would like to try writing code yourself, then set up an account. I have created a repository that you can just think of as a folder for where my code will go. Github uses Git to create a history of code changes and allows for code to be easily changed by any contributor. Here is a guide to help you get started with Github.

Again, naming is hard, but I decided to go with “stratomagic”.

https://github.com/unrealities/stratomagic

This is a play on strat-o-matic, the first baseball tabletop game and Magic the Gathering, the original trading card game made by the same company, Wizards of the Coast, that made MLB Showdown.

Since we’re starting with the assumption that you have never programmed before, I will give a brief background in what I will actually be developing. When you visit a website your computer is accessing information from another computer (server). The information may actually come from many different computers (servers) and the content may be static or dynamic. Static content is most of what this page is made of, words and links and stylings of text. That’s HTML and CSS.

Javascript allows a webpage to be dynamic. You can now receive real-time stock alerts on the website or get your favorite advertisement sent to you. It can also allow the user to press a button that would roll a die for a game.

I will start with a very basic/ugly/boring webpage that will hopefully turn into something that any fan of strategy games would be willing to play.

To Be Continued…

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *