John Klingler

Sharp League

Sharp League was an online wagering game that combined elements of fantasy sports and gambling into a tournament that you could play with your friends. It was my hobby project for five years, a source of great pride and fun, and the cause of many long nights spent staring at code with the lights turned low to not wake the sleeping house. [View Repo]

The game was pretty simple. At the beginning of a season (like the NFL), each player would be given $2,000 in fake dollars. He or she would place bets in an online sportsbook all season long and see who won the most money at the end. Most people went bust; some won fantastic sums.

At its height, Sharp League had a couple hundred players. This is not a huge number, but it was significant enough that I had to learn to be a real programmer. Taking an idea and trying to scale it makes you learn all sorts of new things — how to automate manual processes, how to optimize for performace, how to keep a community engaged and coming back.

To all young programmers or those newly interested in computers, my best advice is: just start something. Take an idea and try to get it to work. Make a website from scratch. Code a game or an app that does something someone might find interesting. It doesn't matter what languages or framework you use. The basic concepts are all the same. You'll learn so much by just doing it.

Sharp League never made a single penny and died a quiet death. It is still one of the most rewarding things I have ever done.

tournament listing page

Tournament Listing Page

tournament lobby page

Tournament Lobby

Technical Lessons Learned

Coding and running your own site forces you to learn a bunch quickly:

Object Oriented Programming - After writing a bunch of spaghetti code you start to wonder if there is a better way.

Model-View-Controller - Additionally, Sharp League used FW/1 to seperate concerns and make logic more explicit.

SQL Optimization - I know it is fashionable to use an ORM, but to me it's worth the extra time to write SQL by hand.

Server Management - Not the easiest thing to just keep the damn site up and be aware or potential issues.

PAAS - With a fair amount of traffic, you

Authenication - User accounts and authenication are way more complicated than you realize until you have to do it. Storing passwords properly (with hashing and salting) and then devising a method to reset them is challening.

Security - Speaking of security, any site with a form on it had an attack vector. Dealing with that will keep you up at night.

Timezones - One day I decided the site should show you times in your local timezone. Easy, right? (no.) Go back and save every timestamped thing in UTC time and then run a conversion every time that timestamp is referreneced. Took me a week.

UI/UX Lessons Learned

No one cares how beautiful your code is. Just make things work. Clever solutions make no difference to users. It's better to bang out new features.

Watch your users. Duh, I know. But it's worth repeating that people don't usually do what you expect and you won't anticipate how features will be used or misused. For example, at the beginning, bets were publically viewable by all. This led some people to delay bets until the last minute so others couldn't copy them. Realizing this, we added the option to "hide" a bet and everyone was happy.

Build-Measure-Learn. Not my idea, but true. Try something, see if it works, ditch the failures, build on the successes. Don't spend all your time making things perfect. Make things fast and get feedback.

Make it easy. If you want to encourage an action, make it as easy as possible. For exmaple, we had trouble designing a bulletin board that people would actually use. There were always too many steps. Then we made it like twitter—just an input box and a submit button. Then usage exploded.

collage of profile photos

Some user profile photos

bet-history page

Bet History Page from March Madness

amazing bet ledger page

Somebody got all these bets right on one day

patent diagram 1 patent diagram 2

Diagrams from a patent application that never got past provisional