Draw a Stickman: EPIC, a MonoGame Adventure
- Backstory -
Back in 2010, Phil Williams, a graphic designer/flash developer at Hitcents started on an idea he called “draw a stickman”. The idea was an interactive story, where you drew a stickman and he came to life. You would then have to draw other items to help your stickman through his adventures.
Phil worked on and off on his idea for about one day a week, and after a year of work http://drawastickman.com was born. Almost immediately the website went viral, and we had over a million page views in 24hrs. The site went on to win numerous awards including 3 Webby Awards.
From all this success, we were ready to move on to a new game, but we weren’t thrilled with the performance we were getting on some devices. We also had the limitation of Android’s web browser not supporting some of the features used in Draw a Stickman. We already had some experience with MonoTouch and Mono for Android, so we quickly made the decision to write a native app and use C# to make that happen.
Moving to C#, we quickly chose XNA and MonoGame as our core frameworks for building the game. We enjoyed the XNA set of APIs, and realized that we could share a very large portion of code across platforms with MonoGame. We built the core of our own cross platform game engine in a month or so and added more and more features to our engine as the new game, Draw a Stickman: EPIC, became a reality.
- Performance –
In building EPIC, we initially developed in standard XNA on Windows and then backported our changes over to iOS, Android, and Windows 8 projects. For the most part, performance was right on par on mobile devices with what we were seeing on Windows, but there are several tips and tricks that can be applied to any game to squeeze out the last couple FPS you need.
Use as few SpriteBatch calls as possible – We use 1 instance of SpriteBatch throughout the entire game, and get by with only 2 calls to Begin and End during the Game class’s Draw step. We have one pass for the sprites in the levels that are modified by a matrix (for your Stickman’s position in the world), and then one more pass for all the in-game menus.
Use sprite sheets – We use a tool called TexturePacker to put all of our textures into large sheets. It supports exporting the locations of all the images in several formats. We had to make a few changes to our engine to support loading and rendering images pulled from these sheets. But the work paid off, as it improved our load times drastically and helped our FPS as well.
Switch from XML or JSON to BinaryReader/Writer – All of our level and enemy data was originally in JSON (we arbitrarily chose over XML), and we used JSON.Net and some sophisticated caching to get our loading times to a bearable level. On a whim, we decided to try out BinaryReader and writing the same values sequentially which eliminated all use of System.Reflection during our loading screen. The results were drastic, on some devices, our load times went from 10 seconds to less than 1.
Don’t render things off screen – We found, particularly on mobile devices, that you can get better FPS with as few calls as possible to SpriteBatch. If lots of objects are off screen, add broad checks to prevent calls to SpriteBatch.Draw if objects are off screen.
Compress your images – We use two major techniques for making our textures a bit smaller for our game. If you have images that don’t require transparency, make them either JPGs or indexed PNGs with fewer colors. We also take advantage of a tool called smusher, that can compress pictures down an average of 10-15% without any loss in image quality.
Run the GC during loading screens – C# being a managed language, the GC has to run occasionally. Manually run it during a loading screen or waiting period to prevent as many FPS drops as possible.
Use profilers – The first issue supporting older devices for us was memory usage. We used tools like Xamarin’s HeapShot tool on iOS to see what objects are in memory. This allowed us to fix a few low hanging fruit as far as memory usage is concerned and get our game running on those older phones and 1st generation iPads.
Simplify your math – Our game has a decent amount of collision logic, as most games do. One trick you can do is to add broad-phase checks, which is basically checking collision against a larger area prior to looping through a list of objects within that area. Also avoid Math.Sqrt where you can, a lot of times you can avoid it and square the values instead to get the same result.
- Monetization and Marketing –
Deciding how to make money with your game is one of the most important decisions you can make about your game. We all wish we could just make games just for fun, but it can get pretty tough to work on games with your electricity turned off.
Have a free version of some kind – A user is more likely to buy your game if they can play it for a little while and decide if they like it or not. On Windows 8 and Windows Phone make sure to use the free trial feature. On other platforms, create two versions of the app: one free one with advertising and maybe the first few levels of the game, with lots of calls to action for upgrading to the full version.
Make an “HD” version – We found that making an HD version of our app and charging a little bit more is a sound practice (notice the big guys like Rovio and Halfbrick do it). The higher price is expected by tablet owners, and we statistically made more money because of having two versions of the game—one at a higher price.
Use in-app purchases – Most every game can benefit from in-app purchases for extra revenue. Keep this in mind before your game is completed, a lot of times it can be difficult to come up with IAPs that make sense for an already completed game. If your game has an in-game currency such as coins, make sure to include IAP packs of coins all the way up to $19.99 (or even $99.99!) to enable those big spenders also known as “whales.”
Have a Facebook Fan Page – At least for EPIC, our users had questions about our game all the time. Keeping up a fan page is a nice way to interact with your users, and find out what you could change about your game to make it better. Getting them involved also gets their friends to potentially find out about your game as well.
Don’t go over the 50MB limit – At least on phones, going over the cellular download limit is a huge hindrance for any iOS app. You are immediately cutting off users that are trying to download your app. Will they remember to download your app when they get home? Who knows? Going over is not as bad with the tablet version of your app, as users are more likely to be on Wi-Fi.
Prompt the user for a review – Make it easy for users to review your app. Some users may find it annoying, but asking for a review once after three startups (or after they complete a few levels) is a good way to gain a lot of 5-star reviews. Users that like your game are more likely to be playing your game on the third startup and are likely to leave a good review. Just make sure to not “pester” the user with this popup over and over.
Support your users – Set up a valid support email address for responding to requests from the app stores. Read your 1-star reviews carefully. Try to fix any glaring issues and push out an update. I was very surprised to see 1-star reviews turn into 5-star when we were able to fix issues in a very short time span on Google Play.
Don’t spend too much money advertising – Advertising is probably not worth it unless you are willing to dump a lot money into it. Ask yourself, am I willing to pay $2-$3 per download on the free version of my app? If that answer is no, then don’t pay for advertising. Likewise, review sites can be inexpensive, but don’t seem to help very much with overall downloads. How often do you go to such sites? Can you name some of these sites off the top of your head right now? So don’t pay for reviews, but try to get as many free ones as possible—coupon codes can be persuasive enough.
- Our Success so Far -
In under 60 days from its release Draw a Stickman: EPIC hit over a million downloads across all platforms. We topped the charts at #1 in UK, Ireland, Australia, and New Zealand for iOS in the free iPad section. We were featured as one of the top 15 apps on Windows 8 by PC World. On Windows 8 we peaked at #1 in the paid Games section, beating out Angry Birds Star Wars at #2. We hit the top 10 new paid on Google Play, and reached the #1 spot in the Amazon marketplace as well. We have also had numerous contacts from device manufacturers for both Android and Windows that will provide new business for our app.
Using MonoGame, we have 95% of our code shared between all platforms. Currently our game is available for iOS, Android, Windows 8, and Amazon Kindle. Right now we are working on ports to Windows Phone and Mac, localizing our game for 12 languages, and adding more content as in-app purchases. We are hoping this will bring our game to more users and increase its longevity.