The San Francisco Pinball Department (SFPD) just started its fourth season last month. I’ve been participating since the first season and it’s my favourite way to participate in competitive pinball. It’s also one of the largest pinball leagues in the US with around 75 active members and a waiting list for new members.
As a result, the administrative work for our league organizer, Per, had become not very fun. I needed a summer project and have made a mobile app for SFPD members to use. I thought other leagues and tournament organizers might be interested in seeing how it works.
How SFPD works
Scoring in SFPD is very simple. People are randomly drawn into groups of four. Each group plays four games and records their final position on each game. Points are awarded at 4.5/3/2/1 for four-person groups and 4.5/2.5/1 for three-person groups. We don’t write down finals scores on each game because there are typically 60-70 people at any given league night and it would slow things down too much.
In the past, results and standings were recorded on paper score sheets and our league organizer would manually type each result into a spreadsheet and then manually publish the scores on our league website. This would literally take hours to do. Not very fun at all.
A plan comes together
I wanted to create a mobile app where each group of players would enter their own scores. That was the baseline. I talked with a handful of people from our league to get idea for how an app would work and sat down with Per to decide which features to implement.
Per felt very strongly about the manual process (and I agree with him). When players arrive, they find their personalized poker chip and put it in a bag. Chips are then drawn from the bag to determine groups of players. This is something that can be handled efficiently by a mobile app. Using an app all groups can be created instantly at the push of a button.
But early on, we decided to leave out two features: online player check-in and app-assisted randomizing of groups.
When a player arrives to put his chip in the bag, someone is present to greet him, and we’re all together when the groups are drawn. Per didn’t want a room of people staring at their phones waiting for a button to be pushed. A league night at SFPD is a social event, and the software should support that goal.
On a practical level, the manual process also ensures a staggered start. If 17 groups started simultaneously, it would be very chaotic.
We also decided to do score keeping on both paper slips and via the mobile app. This ensures a paper trail if something goes wrong. It has already come in handy a handful of times.
Recording results with the mobile app
I built an app that’s really just a mobile website. It will work on any smartphone or tablet without me having to build multiple versions. This is a labor of love, after all.
The flow players go through is pretty simple:
- Receive a printed score sheet with a code
- Enter the code into the app to get to their group (or just scan a QR code on the score sheet)
- Add players to the group. Since we are drawing names out of a bag, the app doesn’t know which players belong in which groups.
- Pick first game
- Enter results for first game
- Repeat for games two through four
At the top of this post you can see a paper score sheet and below you can see screenshots of what it looks like when you’re adding players and entering a result. Not shown is a simple dropdown that’s used to pick a new game.
The app will automatically handle player order for each game, making sure that each player plays each position once and telling the score keeper who should be picking the next game.
As you record results for each game, your points for the night are automatically calculated. You can also see the results from all the other groups as they are entered. The gray background for the overall results indicates who picked that particular machine.
The most recent addition to the app came from one of our players. At the end of the night, he wanted quick access to the latest result for his friends. As a result, I added a basic player profile where you can see the latest results for a player along with a list of machines they’ve chosen in the past.
You can of course view the current standings and results online. On the standings page, you can see which players are rookies and guests (as opposed to league members). This is so existing members can make new players feel welcome, give them pointers on game strategy, etc.
The administration area
Behind the scenes, the league organizer has access to an administration area. This allows him to:
- Register players for a season
- Create rounds/league nights
- Print score sheets
- Maintain a collection of pinball machines and mark them as active/inactive
- View some basic statistics (just most popular machines for now)
- Get an overview of a specific league night (pictured below)
We use this overview to see if all groups have added results in the app (there needs to be four checkmarks). Going forward, we are looking at the timelines on the right to gain insight into how games are playing and how the app is being used. The timeline shows when results for individual games were entered. For example, you can see that group 3 entered all their results at the end of the night and not as they played each game. They had no cellphone coverage in their corner of Free Gold Watch and couldn’t use the app while playing.
I hope to be able to spot more problems of that nature as well as spot exceptionally long-playing games to keep in mind for future planning.
More screenshots: Home screen, Overview of machines, Players list, Players list for season, Most popular machines.
The technical setup
I kept the technical setup simple. I needed to deploy the app to a cheap shared hosting account because I didn’t want it to incur extra costs for the league. This meant PHP was a hard requirement. I went with the Laravel framework to provide the administration area and a JSON REST API for the public frontend to consume.
The data storage is plain old MySQL. Here I really wanted to use Firebase, but their pricing is prohibitive for this kind of project. It would be $50/month just for Firebase. When I have a project that requires fewer simultaneous connections, I definitely want to try out Firebase.
The public frontend is built as a single page app using Angular. This was my main motivation for taking this on as a summer project. I had been wanting to use Angular for a project for some time. Network connectivity can be very spotty at Free Gold Watch and setting up a single page app means that people just have to open the app in their mobile browser to get all assets downloaded. After that point, there are no expensive page reloads and the amount of data going over the network is very limited. The network was worse than I thought, and in hindsight, this was the most important design decision I made.
To make things look pretty, I used default Twitter Bootstrap components because I didn’t have time for anything else.
Highest on my list are the things that needs to work before the current season ends: a way to store post-season results (to show final standings) and a way to autmatically generate the data IFPA needs for submission (because writing that by hand is very time consuming).
Other than that, I have a handful of small tweaks to make the user interface and maybe some more statistics, but in general I don’t want to touch it too much at this point. I am more interested in seeing how the app will perform as the current season moves along.
How is it working?
It’s working great! Administration overhead for scorekeeping is down to almost nothing. Per no longer has to spend all Wednesday night in front of a spreadsheet. League members are really excited that they can instantly see their own position and the results of their friends (for appropriate teasing or bragging before going home for the night).
I was initially concerned that people would complain about the extra work of having to do both paper and electronic scorekeeping, but not one person has complained.
With the app, we have handled 68 games of pinball in 90 minutes during each of the first two league nights of the current season. That’s much better than I hoped for.
If you have any questions or comments, feel free to get in touch.