As small-time Windows Phone developers looking to monetize our apps, the free-with-ads model is very attractive. So this week, I buckled down and took a shot at integrating the Microsoft Advertising SDK for Windows Phone into one of our existing games, Follow the Curve.
The SDK itself is quite simple to use. Microsoft provides an extremely detailed tutorial on getting started, as well as a code sample to inspire you. Piece of cake, right? Well, almost. Right off the bat, I had a problem: the sample would run, but no ads would appear.
In Which I Learn to RTFM
When faced with the dreaded blank screen, a developer is generally left with two options:
- Google your problem and if that fails,
- Read every single page of the documentation.
It appears that Microsoft took a fail silently approach when designing the API. All exceptions are caught and then broadcasted to subscribers through use of the DrawableAd.ErrorOccurred
event. This was probably a good choice: there’s plenty that can go wrong when trying to retrieve ads over a network, and ad failure is never going to cause problems for the rest of the app, so in general we can just keep calm and carry on.
Once I noticed that the sample was already logging errors, I was able to determine that my issue was not network-based. In fact, the failure was being caused because the SDK I downloaded was only compatible with Mango, and the sample code was for Windows Phone 7.0. This is the type of error that should have thrown a giant, shiny exception as early as possible, not hidden itself away until I came looking for it.
In Which I Become Rather Confused
The advertisement itself is implemented as a DrawableGameComponent
, meaning that it takes care of updating and drawing itself. The only time you have to care about what the ad is doing is when the user clicks on the ad. There are two things to consider:
- When the user touches the ad, that input should not be passed on to the game.
- When the user clicks the ad and is taken away from the game, the game should be paused.
Most fortunately, the API kindly provides us with events to tell us when we should sit up and pay attention. This is where things get a little confusing, though. These are the events I could find:
public event EventHandler AdGameComponent.InputConsumedChanged; public event EventHandler AdGameComponent.EngagedChanged; public event EventHandler DrawableAd.EngagedChanged;
Wait, what? Well, maybe there’s a reason that there are two copies of EngagedChanged
.
Let’s run a little test. Grab the sample code if you haven’t already, and add some code to record the above events.
// ... bannerAd.AdRefreshed += new EventHandler(bannerAd_AdRefreshed); bannerAd.EngagedChanged += (sender, args) => Debug.WriteLine ( "DrawableAd.EngagedChanged -> " + "DrawableAd.Engaged: {0}, AdGameComponent.Engaged: {1}", bannerAd.Engaged, AdGameComponent.Current.Engaged ); AdGameComponent.Current.EngagedChanged += (sender, args) => Debug.WriteLine ( "AdGameComponent.EngagedChanged -> " + "DrawableAd.Engaged: {0}, AdGameComponent.Engaged: {1}", bannerAd.Engaged, AdGameComponent.Current.Engaged ); AdGameComponent.Current.InputConsumedChanged += (sender, args) => Debug.WriteLine ( "AdGameComponent.InputConsumedChanged -> "+ "AdGameComponent.InputConsumed: {0}", AdGameComponent.Current.InputConsumed );
Here’s what I got when I clicked on the ad:
AdGameComponent.InputConsumedChanged -> AdGameComponent.InputConsumed: True DrawableAd.EngagedChanged -> DrawableAd.Engaged: False, AdGameComponent.Engaged: False DrawableAd.EngagedChanged -> DrawableAd.Engaged: False, AdGameComponent.Engaged: False AdGameComponent.InputConsumedChanged -> AdGameComponent.InputConsumed: False
There are two things to note here:
- Both
Engaged
properties are always false. - The
AdGameComponent.EngagedChanged
event is never called.
Now, it’s quite possible that I’m missing something here. Maybe the behaviour is different on different platforms, or maybe it’ll change in future versions. However, if that’s the case, then it would be nice if the documentation mentioned something to that effect.
In Which I Conclude
Once I decided to simply ignore EngagedChanged
, things progressed smoothly. The InputConsumed
property becomes true whenever a user touches the ad, and changes back to false whenever that touch is released. Relying on the InputConsumedChanged
event is enough to ensure a smooth user experience.
Despite the bit trouble I ran into, I found the Advertising SDK quite easy to deal with. It’s simple to integrate into your code, and setting up an account in the pubCenter is completely painless. Even with the issues I had, the whole thing only took a couple of hours. So get to work and start making some money.
P.S. If anyone knows why EngagedChanged
is always false, be sure to let me know.
Leave a Reply