Thursday, January 30, 2014

Chaos Moves, Time Moves and Leaderboards... Oh My!

Version 0.8 Released:

GumBall Fall v0.8: Web Player | Android | PC | Mac | Google Play BETA | Google+

This past week has seen a whirlwind of development activity with the addition of not only two new game mode variations, but, also linking GumBall Fall to some global leaderboards. The player now has the option to ditch the frantic pace of Time mode and, instead, engage in the more leisurely paced strategic Moves mode where the player has 30 moves to rack up his/her high score.

Also, those scores aren't just local any more! Need some motivation to play? Check out how your scores match up with the rest of the world.

Major Changes in v0.7.1 (Jan 27, 2014):
  • [BUG FIX] (re)Corrected issue where the game might lock up when a round was finished (leaving gumballs uncleaned)
  • Introduced Game Mode Moves. Instead of 60 seconds, you now have 30 moves to rack up gumball chain
  • Revamped bonus scoring system. Instead of bonus points decaying with time, they now decay whenever the player fails to make a chain of size 4+ ( 1 point decay for each move under 4 )
  • Tweaked Score screen layout. The Top 10 list of your last play mode will now be listed first in the scroll view

Major Changes in v0.8 (Jan 29, 2014):
  • [BUG FIX] Fixed some problematic gumball animations
  • Introduced Global Leaderboards. The top ten players from around the world for each game mode are shown
    • NOTE: If you’re not online, your high scores will NOT be uploaded
  • Player Name can be set in the Setting menu (or during the initial tutorials)

The rapid development this week is the direct result of design decisions made early in development or, in the case of Leaderboards, decisions made during Bouncing Bombs! development.

Decoupled Modular Building Blocks:

I enjoy spaghetti... just not mixed in my code. As mentioned in a previous post, GumBall Fall makes liberal use of a messaging system that allows all of the various pieces and parts of the game to broadcast and subscribe to information they're interested in. This keeps my game objects decoupled from each other quite nicely. They don't care who (or how) the information is sent/received. They just care that they sent/received it.

Which now brings us to Time vs Move-based game play. If you think about it, 60 seconds is a heck of a lot like 30 moves. Something counts down and, when it reaches 0, the game's over. The only real difference is one countdown is dictated by nature and the other is dictated by the user.

The game object responsible for determining when a game is over listens for game 'tick' updates. When it receives a 'tick' it decrements its 'tick' counter by an appropriate amount and determines if that lowering is enough to end the game. Thanks to the messaging design decision, this GameOver game object doesn't care how the 'tick' was generated (or when it was generated); it just cares that it received one.

So, to switch the game from Time to Move-based, all one has to do is swap a countdown clock game object for a move count game object. Both broadcast their 'ticks' at appropriate times and the GameOver game object is none the wiser.

The result? An easy to implement game mode to diversify GumBall Fall's game play!

Generic Leaderboard Server Interface:

During Bouncing Bombs! development, I settled on using for my leaderboard backend. It provided a simple/stable/cross-platform RESTful interface to code to and has proven to be a reliable service.

By the time Bouncing Bombs! was released, I had developed a (mosty) generic leaderboard server interface. To interact with the system, a game object simply messaged a request to the leaderboard server game object and registered for a response. Porting this interface to GumBall Fall was a no-brainer.

You might have noticed 'mostly' from the last paragraph. Turns out, my 'generic' server I though I created wasn't quite as generic as I though it was. Small pieces of it were still directly tied to Bouncing Bombs! specific types. But, 98.4279% of the code was good-to-go. After about an hour of tinkering, the leaderboard server interface was transformed into a completely generic standalone piece of software. And, 15-20 minutes after that transformation, it was integrated with GumBall Fall.

As long as remains free and reliable, I'll definitely be reusing this lovely piece of generic code in all of my future game projects!

But, but, but... what about The Googles and Amazons?!? They offer various services to implement leaderboards and achievements and cloud saves!! While these services exist, they are (1) mutually exclusive (i.e. Google Play Games services don't run on Kindle devices and Amazon Game Circles services only run on Android devices IF they were downloaded via the Amazon App Store) and (2) require the player to actually commit to setting up (or activating) an account with those respective companies. To me, both of these points add a decent amount of friction to the user experience and, thus, were not my primary online targets.

With that said, moving forward, I still have plans to investigate integrating both the Google Play Games and Amazon Game Circles services into GumBall Fall (for use in their respective marketplaces). But, until that day, the generic approach provides me with a global leaderboard solution while requiring the user to provide nothing more than a simple nickname and it'll work across any platform GumBall Fall is running on (PC, Mac, Linux, Web, Android, Kindle). Even if I end up integrating the services, I still plan on keeping the solution around.

Thursday, January 23, 2014

Two For The Price Of One

Version 0.7 Released:

GumBall Fall v0.7: Web Player | Android | Google Play BETA | Google+

Two! Yes two, two, two build milestones in one (blog post). After releasing GumBall Fall v0.5 a few weeks ago, documenting my coding exploits took a bit of a downturn due to a variety of reasons. Since then, two pre-releases of GumBall Fall have been released into the wild.

With each release comes a more polished product. Release v0.6 saw the first push of the game into the Google Play Store BETA program. If you’re interested in joining the public BETA follow these directions and join the fun!

Major Changes in v0.6 (Jan 16, 2014):
  • Graphics:
    • New Desktop & Android Icon 
    • Selected gumballs now highlight their ‘closeness’ radius. If another gumball of the same color falls in this radius, it can be added to the chain 
  • Game Play and Internal Logic: 
    • Gameboard now resets if no valid chains are detected for the player to select 
    • After not finding a valid chain for ‘a bit’ the game will suggest a chain for the user 
  • Brand new Intro Tutorial. Still needs polishing, but, it’s a BIG improvement over what used to be there 
  • Various UI tweaks 
  • First build to be signed and pushed to the Google Play Store in BETA form

Major Changes in v0.7 (Jan 23, 2014):
  • [BUG FIX] Corrected regression in v0.6 where player data wouldn’t save properly when run in WebPlayer (C# Dictionaries don’t serialize in Unity)
  • Gumballs ‘reflection’ now (hopefully) look more realistic 
  • Revamped internal save data layout 
    • New game modes/types should be able to be added without the need to completely reset player stats 
  • Setting screen created 
    • Music and SFX volume control 
    • Gumball color scheme options ( aid in color blindness )

This Period's Highlights:

More than anything, these last two updates focused on providing the player with a better user experience. First and foremost, if you want to keep players, you have to have a fun game… hopefully, I do. And, hopefully, it’ll only get more fun as I continue to add more features.

But, it’s the little details that really make the game. First up…

Refining the Tutorial

If the user doesn’t know how to play your game, (s)he simply won’t play it! The old tutorial was nothing more than a single screen filled with a wall of text giving the user a vague idea of how the game works. Creating it, I knew it was destined to be replaced with something far more robust. Ideally, I’d create an interactive tutorial system that integrated directly into normal gameplay. That didn’t happen (though, perhaps it’ll make its way into a future build). What has happened is the creation of an interactive tutorial when the player first starts the game. The tutorial walks the player through the basic gameplay mechanics and requires the player to complete simply tasks before it’ll let him/her play the game proper.

Removing The Noise

Most people would say your game isn’t complete unless your game has sound. Ironically, though, for mobile apps, one of the first things people do is disable all audio. After all, a silent game can more easily be played in class or meetings.

Well, GumBall Fall has been pumping out music and sound effects for a few releases now. But, up until this point, the player had no way to disable this ‘noise.’ Well, audio control can now be knocked off my TODO list. The player can now independently control music and sound effects volume from the Settings screen

Aiding The (color) Blind

One of the general no-nos in UI design is to rely on color as the only indicator of an object’s purpose. Think of a traffic light: Green means GO, red means STOP, yellow means SPEED UP AND MAKE IT THROUGH THE LIGHT BEFORE IT TURNS RED. But, what happens if you’re color blind? Well, you then have to rely on light positions. Green is always going to be on the bottom or right, red on the top or left, and yellow always in the middle. You might not know what color is actually showing, but, you can still determine the proper action to take.

So, what did I do with GumBall Fall? Ignored all of those color rules and created a game with perfect spheres whose only discernible difference is color… BRILLIANT!

When conceptualizing the game, It’s a problem I knew I’d run into, but, I kept pushing it to the back burner. Ideally, I’d make different shaped gumballs or brand an unique symbol on each gumball type. But, that’ll be for future release considerations. For now, what we have are alternate gumball color schemes available in the Setting screen. Currently there are 3 schemes to choose from. The first scheme is basically what I’ve been using for the past several releases. The second and third schemes were created mostly based off of the website. With just a few drags and clicks of a mouse, you can explore all sorts of color schemes and, best of all, they have options you can enable to simulate what your schemes will look like to folks with various types of color blindness.

Ultimately, creating non-color dependent visual cues for each gumball type will be the ideal solution. But, for now, the alternate color schemes ought to give folks a higher probability to play GumBall Fall successfully.

Welcome to the BETA

Version v0.6 saw the light of day in the Google Play Store. While sideloading an app on an Android device is all well and good, it still requires some non-standard Android skills. Mostly, folks need to know how to enable Android to allow non-Google Play Store apps to be installed.

Pushing the app to the Play Store means that anyone who is interested in testing it out can simply download it just like any other app… well, almost. Since I don’t want to actually publish the game to the world, I’m placing the game in a public BETA. Anyone can download the game, but, first they need to become a tester. Follow these directions to become a BETA tester. What it boils down to is simply joining the GumBall Fall Google+ community and following a couple links.

Besides easy of download, being in the Play Store also eases the burden of asking folks to reinstall newer versions of the game. Now, new versions will simply get pushed to them just like any other app they’ve downloaded from the store.

Oh, and one more thing…

Pushing to the Play Store inspired me to actually create a more legitimate-looking app icon. I’m far from being an artist, but, this is what I came up with. Let me know what you think!

Thursday, January 9, 2014

Wrapping Up 2013

Version 0.5 Released:

GumBall Fall v0.5: Web Player | Android

With the various family and friends commitments of Christmas and New Years and, just for fun, a nasty flu bug knocking me out for almost a week, development continues to be a bit slow... Not that I'm complaining about the holiday gatherings; they were fantastic (not so much the flu bug).  Delays be damned, I feel that I've finally pieced enough together to warrant a new release and blog update.

Just comparing this release with the previous one, I'm amazed at what a difference a bit of polish can make. Here's hoping you guys agree!

Major Changes in v0.5:
  • Stat Tracking:
    • As promised last release, high scores will be reset with this release.  Expect further resets in future releases... don't become attached to them ;-)
  • In-Game Graphic Improvements:
    • New shader/material rendering to give the game more of a cartoony feel
    • When selected, gumballs now animate to identify their selection instead of going partly transparent
    • More 'juiceness' in the form of revamped gumball EXPLOSIONS, bonus announcements and background (say goodbye to the black background!)
  • User Interface Improvements:
    • Complete revamp of the UI look. Hopefully, the game has a bit more personality now!
    • Say hello to Frank, the rabbit. He needs your help picking up these gumballs! 
    •  Dedicated game summary screen created
    • Initial Help / Intro screens added to explain (probably poorly) to the player how to play
    • Further modularization of the interface to make updates even easier
  • Sound Effects:
    • Selection sounds now use a 'major scale' to make it sound a bit happier
    • Each color gumball has its own scale of tones
    • Music now accompanies you as you play the game
    • NOTE: There is currently no way to disable sounds. This will happen in a future release
  • Game Play and Internal Logic:
    • [BUG FIX] Any chain you're in the middle of making when the game ends will be added to your final score
    •  First iteration of rewarding the player for making long chains 
    • Added basic AI to identify valid gumball chains to add future capabilities:
      • Identify if/when no valid moves are possible
      • Suggest to the player valid moves if (s)he is slow in finding them
      • Allows for automated development demo/test debugging
    • Refactored how internal logic determines if gumballs match for more accuracy and efficiency

This Period's Highlights:

Early Feedback Continues to Focus Development:

As always, the latest player feedback continues to be quite useful. Reddit continues to be the most popular source for Feedback. Most feedback comes from posts in /r/unity, /r/unity3d, /r/indiecode or /r/gamedev's Feedback Friday and it's always enlightening.  This go round, most folks were asking for 'cooler effects and explosions.'  Well, it's time to turn gussy up this puppy... at least as much as this non-artist can ;-)

But first...

Getting Learned in C#:

In previous posts, I've mentioned that I'm rather new to C#. As a result, I'm learning about cool new (to me) features all the time. Today's feature: System.Linq.  If you've never heard of it, go do an Internet search for the MSDN entries for it. Then go read this (Unity3D related) blog article. If you can't see the potential awesomeness in the library, then go back and look again. I won't reiterate what can be read elsewhere, but, suffice to say, Linq is like having access to bit of SQL-query goodness in any of your C# collections (arrays, lists, dictionaries, etc.). Creating unions, differences, and many other random queries are rather trivial to code. The tradeoff is, so I've been lead to believe, that, it's not the most efficient of libraries... so, don't go Linq crazy in your update loops!

So, how am I using Linq? Well, there are various pieces of my codebase I'll likely revisit to refactor to take advantage of Linq, but, initially I'm using it in my new 'AI' logic. Ok, AI is probably waaaay overselling what I've done. One of the pieces of feedback I've received was from a person wishing that the game would highlight suggested moves if the player has been stuck for a while. Good idea. Now how to do it? I ultimately decided to take a snapshot of the positions of all the gumballs and reuse the same selection logic that the player uses to determine where every potential chain is. This ultimately amounts to picking a gumball, finding 'close' neighbors, identifying if the neighbors are the same type of gumball, then, if they are, adding them to a list... you then repeat the process with the newly added neighbors. In the end I ended up with several lists that needed to be joined together. A simple List1.Union(List2) logic is all that's needed to get the job done. Could I write my own logic to join arbitrary lists together? Sure. But, why do that? Better to reuse existing libraries, I say!

So, that's you're C# knowledge dump of the moment. I'm sure anyone who's familiar with C# could spout off all sorts of other great benefits of Linq (as well as other libraries I don't even know about). If you have something cool to share with a C# noob, drop me a line in the comments. I'd love to learn!

Bring on the Personality:

Games, as well as people, are typically perceived as 'better' if they have some personality. Ask yourself, what's more fun, a potato or a Mr. Potato Head? (if you answered 'potato,' go build be a potato-powered clock, smart guy!). Potato Head wins. He has a face and some arms and feet. He's a bit more personable than your standard spud.

I learned a bit from Mr. P. Head. GumBall Fall now has its very own personality in the form of Frank, the rabbit and a bit of a (lame) back story as to why the player is collecting gum balls.  Am I happy with what I have? Yes and no. I feel that by just adding the few things I did, the game is 100% more friendly for the player. But, there's definitely a heck of a lot more I can likely do to make great improvements. But, everyone has to start somewhere, right? I'm starting with a bunny named Frank!


Damn You, Draw Call Batching:

So, the majority of refinements I've made for this release aren't really worth writing in detail about. Graphics look prettier, there are a few new screens, etc. Nothing mind blowing. However, I want to take a minute and write about Draw Call Batching and it's relationship to Unity3D. Every object in my game needs to be drawn. The inefficient way to do this is to simply have a draw call for every item in the scene (assuming its on camera). Unity3D will attempt to dynamically batch draw calls. If you have a bunch of objects that share the same material (basically the texture/shader combo used to render the object), Unity3D will draw all those objects in one call as opposed to one call per item. Needless to say, that's much more efficient.

My game ought to be able to take full advantage of this batching. 99% of it is simply 6 different types of gumballs... and, each gumball uses the same material, I simply just change it's color.  So, 48 gumballs ought to be reduced from 48 calls to 1 call, right? Not so much.  When a gumball is created or re-pooled for later use, it was dynamically getting assigned a new color (i.e. a property in its material was being altered). Turns out, altering a material's property creates a unique instance of the material. Thus, when my game initially creates my 48 gumballs, they all are using the exact same material... and one draw call is used. But, the second I change a gumball's color, a new material is created. Thus, 48 changed gumball colors, 48 new materials. 48 draw calls.  Booooo!

I figured the solution was simple. Just create 6 unique materials: One for each gumball type. Each gumball type will now share a single material. 6 materials, 6 draw calls. Not quite the 1 draw call I figured I might be able to get, but certainly a lot less than the 48 calls I was actually making!

So, I made the change and re-ran the game looking for those 6 draw calls... I'm still getting 48!?!? #*&@##@&*$!!!!  Time for more Internet digging!  Turns out, materials are only part of the problem. The other part is that, due to efficiency considerations, Unity3D will only dynamically batch draw calls on objects that contain less than 900 vertices (or fewer depending on what UV, Normal, etc. mapping you're using in your material). The sphere meshes that come with Unity3D contain close to 500 vertexes and I'm using some UV info which, after doing some experimenting meant that my gumballs could only have around 300 vertices . Ugh!  This meant that I needed to create myself some new simple spheres and led me to boot up my copy of Blender (which I know VERY little about) to create a more basic sphere. After stumbling around in Blender for a bit, I finally created a sphere with around 270 vertices.

With the new material system and the new low-vertex spheres, I finally had some gumballs that would batch! My draw calls dropped from 48 to 6... BooYah!

So, who cares? 48 calls really doesn't seem like that many, right? Well, on the PC, no. I never noticed any performance issues. Even when testing on my Galaxy S3, I saw rock solid 60fps frame rates. However, running the game on my 2012 Nexus 7 showed that I was averaging 35fps. That's still  pretty decent. But, my game's really not all that complicated or graphically intensive. Why should I give up 25fps for no good reason? After successfully batching my draw calls, the frames per second on my Nexus 7 shot back up to a rock solid 60fps.

What's the moral of all of this? Keep an eye on those draw calls! In the mobile world, even a few extra can drastically affect your performance. Because, not only was my frame rate dropping, but, the CPU/GPU was working 8x harder per frame for no good reason... that's going to just drain a mobile device's battery faster than it ought to.

There's definitely more to Unity3D's draw call batching than I've discussed here (both dynamic batching and static batching that I didn't even touch on since it's only available in Unity3D Pro). Check out the  Official Documentation for more information.


Tool Shout Out:

Just wanted to take a moment to give some proper recognition to a free tool I've just recently started using. I've mentioned Unity3D and some of the major libraries I've been using, but, one needs pretty visuals and sounds to go with any game. Today's shout out goes to Inkscape.

Are you familiar with Adobe Illustrator? I knew of it in name only. Well, Inkscape is apparently a pretty dang similar free/open source competitor. So, what is it? It's a vector graphics art tool. Frank, the bunny in my game, was made using vector graphics. I can't take credit for his initial creation (that credit goes to some free-to-use vector character art) but, thanks to Inkscape, this non-artist was able to tweak him to look less sinister and more goofy.

Before and after shots of Frank:

That's all for this post. Thanks for reading and (late) HAPPY NEW YEAR!