Preroll Video iAd’s as Reward Incentive

A common Freemium model for mobile games is to offer a reward (currency, bonuses, etc) in exchange for watching a fullscreen video ad. Attempting to recreate this model using video preroll iAds is possible but has some less than ideal complications. I’ll be going over the basic implementation and the things I wish were different. I started with the Game Health Indicator sample and adjusted it so when the health bar is empty you have to watch an ad to refill it.

First add the iAd.framework to your project under project->Target->General tab. Next we’ll notify our app to prepare and download preroll ads.

AppDelegate.m

@import iAd;@implementation AppDelegate

– (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

//Tell app to download a preroll ad from the iAd server so it is prepared to play
[AVPlayerViewController preparePrerollAds];
return YES;

}

This is a necessary class method to call to but also the source of our first complication. I have yet to find a way to query if a preroll Ad has been downloaded or if one is available. As opposed to the AdBanner class that provides the very convenient bannerLoaded read only property. Then we’ll set up our AVViewController inside our viewController presenting the video ad.

GameViewController.m

//AVPlayerViewController and AVPlayer
@import AVFoundation;
@import iAd;

@interface GameViewController()
//preroll iAd properties and controller
@property (nonatomic, strong) AVPlayerViewController *prerollAdPlayer;
@end

– (void)viewDidLoad
{

//set up the ViewController
self.prerollAdPlayer = [[AVPlayerViewController alloc] init];
//self.prerollAdPlayer.showsPlaybackControls = NO;

}

Here is our second complication. Unlike the typical ad which just requires a tap to follow an external link, video preroll iAd’s require the user to tap the i:information button in the bottom left corner of the AVViewController’s playback controls. This is frustrating on several levels; first we can’t hide the playback controls and second the user is in no way required to watch the entire ad. They can simply skip to the end or hit done. We also have no way to know if they watched the entire ad or not. Continuing from here well set up a method to present and dismiss our video ad once it’s finished playing.

GameViewController.m

//method to play our video ad
– (void) playVideoAd{

//present our ad AVViewController

[self presentViewController:self.prerollAdPlayer animated:YES completion:^{

//Play the preroll ad
[self.prerollAdPlayer playPrerollAdWithCompletionHandler:^(NSError *error) {

if (error) {

//most likely error is we just didn’t have an ad to play
NSLog(@”%@”,error);

}
else {

//The ad started to play and didn’t encounter an error so we give them their reward
[self refillReserves];
self.completeAdPlayback = true;

}
//now we just have to dismiss our AVViewController to return to the game error or not.
[self.prerollAdPlayer dismissViewControllerAnimated:YES completion:^{

if (error) {

//if the ad was unable to play we alert the user
[self showAdPlayerErrorAlert];

}

}];

}];

}];

}

Finally for iOS 9 we have to add one more thing to our Info.plist.

Info.plist

App Transport Security Settings

Allow Arbitrary Loads YES

This is the last complication. For iOS 9 apple added a new security feature called App Transport Security (ATS). Which basically restricts your app from talking to any non HTTPS servers. For whatever reason iAd’s preroll test Developer Ad’s don’t come through an HTTPS server. There is a good chance that this isn’t true for live preroll ad’s but at this time I can’t provided a definitive answer about that.

A sample ap can be found at Preroll-iAd.

You can download Fillip’s Feast from the Apple Ap Store.

Don’t forget to follow me on Twitter @Maroonfacelift.

How do you figure episode 3: Using Line of Action to identify Exaggeration Opportunities

Today we’re building off of the concepts in a previous How do You Figure episode (see here) and will talk about using line of action to exaggerate our poses.

I’m working off of a stock photo from Marcus J Ranum, a photographer who provides amazing resources for artists mostly for free, check out his deviantart for great stock photos.

This character is swinging his axe, moving from left to right, I’m going to attempt to enhance the feeling of power in the axe swing.

Line of action

I’ll start by identifying the primary line of action, a curved line that shows the tension of the spine and the direction of the force. In my study drawing we can exaggerate the feeling of these forces by leaning the line further to the right and bending the line in the torso further

LineofAction_2

LineofAction_3

I find it helpful to think of the other limbs as having their own lines of action, often providing counter motion to the primary line of action.

LineofAction_4

The exaggeration opportunity here is often in the squash and stretch, and their relationships with the primary line of action. Adjusting slightly to avoid right angles can make the pose feel more organic.

From there the study is finished off using a few layers of sketching

LineofAction_5

block in

LineofAction_6

clean line

LineofAction_7

tones/painting.

each of these other steps have their own shortcuts to get to a finished state more efficiently, but that’s for another blog post.

ButtonNode

When we first started developing with SpritKit we quickly felt the need for some higher level abstractions.  One example of this is a button.  As a result we ended up creating a simple ButtonNode class that we could use throughout our game.  This post will present an example of our button node extracted from our Fillip’s Feast game, available in the Apple App Store.

The following features are included in this basic button node implementation.

  • Buttons would use images from textures or named image assets
  • Provide visual feedback when button is selected

The ButtonNode subclassed SKSpriteNode and provides 2 contractor methods.

+(instancetype)buttonWithImageNamed:(NSString*)image forTarget:(id)target andSelector:(SEL)selector;
+(instancetype)buttonWithTexture:(SKTexture*)texture forTarget:(id)target andSelector:(SEL)selector;

The implementation of each of these only varies based on the source of the image to be used for the button.  Here is what we have for the creating the button with a named image.

// Allocates and initializes a new button node from a named image
+(instancetype)buttonWithImageNamed:(NSString*)image forTarget:(id)target andSelector:(SEL)selector {

ButtonNode *button = [[ButtonNode alloc] initWithImageNamed:image forTarget:(id)target andSelector:selector];
return button;

}

// Init button with a named image
-(instancetype)initWithImageNamed:(NSString*)image forTarget:(id)target andSelector:(SEL)selector {

if (self = [super initWithImageNamed:image]) {

self.target = target;
self.selector = selector;
self.userInteractionEnabled = true;
self.color = [SKColor grayColor];

}
return self;

}

With this constructor we can now create our new button node and add it to our scene.  Since this is a subclass of SKSpriteNode you use the normal SKNode position property to set the location of the button within the scene.

-(void)addMyButton {

ButtonNode *myButton = [ButtonNode buttonWithImageNamed:@”myButtonImage” forTarget:self andSelector:@selector(myButtonAction)];
myButton.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:myButton];

}

Notice in the method above we are setting the target to self (our current scene) and the selector (the method that will be called) as myButtonAction.  In the scene you then need to add the myButtonAction method with the appropriate code to be executed when the button has been pressed and released.

So now we have to address what happens when the button is touched.  There are a few different scenarios we have to deal with. First what happens when the button is touched, then what happens when the user touches the button but then drags out of the button area, and then finally what happens if the user is within the button area and lifts their finger off the button.  The final case is what is commonly referred to a “touch up inside event”.  Lets go through the code for each of these.

First what happens when the user touches the button.  In this case we want to give the user a visual indication that they are touching the button.  For this we will respond to the “touches begin” event.  Here we are responding to this event and if the touch happens to be inside our button we will set the button to the selected state.

// When the button is touched blend the button color with the image to give it a selected appearance
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInNode:self.parent];
if (touches.count == 1 && CGRectContainsPoint(self.frame, touchPoint)) {

[self setSelectedState:YES];

}

}

Setting the button to the selected state will simply update the color blend factor so the buttons appearance changes.

// Helper method to set or unset the button selected state
– (void)setSelectedState:(BOOL)selected {

if (selected) {

self.isSelected = YES;
self.colorBlendFactor = 0.7;

} else {

self.isSelected = NO;
self.colorBlendFactor = 0.0;

}

}

So what happens if the user has touched the button but then drags their finger off of the button.  In this case we want to change the state of the button to be not selected.  But, we also need to handle the case of the user then dragging their finger back within the area of the button.  To handle both of these cases we need to handle the touches moved event.

– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInNode:self.parent];
if (CGRectContainsPoint(self.frame, touchPoint)) {

[self setSelectedState:YES];

} else {

[self setSelectedState:NO];

}

}

So when in the touches is moved we are checking to see if the touch is inside or outside of our button and setting the Selected state as appropriate.

Finally we need to handle the case where the user has touched the button and then releases it.  For this we need to respond to the touches ended event. If the button selected state is true we will call the activateButton method,

– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

if (self.isSelected) {

[self setSelectedState:NO];
[self activateButton];

}

}

Then finally we need to respond to the activateButton method.  In this case we are going to simply call the selector on the target that was passed in when the button was created.

// When activated the button will selector on the target to invode the buttons action
– (void)activateButton{

if (self.target != nil && [self.target respondsToSelector:self.selector]){

[self.target performSelectorOnMainThread:(self.selector) withObject:self waitUntilDone:NO];

}

}

In future posts we will expand on the button node class adding additional functionality.

A sample app, ButtonNode , with this ButtonNode class can be found on our github page.

You can find me on twitter @mellowcoder

SpriteKit and iOS9

This is a short post discussing a few issues that we encountered with updating our SpritKit based game, Fillips Feast, to work with iOS 9.

For the most part everything just worked when running Fillip’s Feast on iOS 9.  But, we did encounter a few issues.

One of the first things we noticed was that our intro video was not being shown when running under iOS 9.  The video which played fine under prior OS versions was not visible in iOS 9.  But, it was playing so it was not an issue of the video.  For game loading intro we created a loading scene that is presented when the app first starts.  This includes a splash screen, which is an SKSpritNode that displays the first frame of the video and an SKVideoNode used to play the intro video.  We also add a message to the intro view once all the assets have finished loading to let the user know that they can tap the screen to skip the rest of the video.

After a bit of debugging we determined that the issues was related to the zPosition of the video.  In building the intro scene we had not explicitly set the zPosition for the elements.  Simply adding the video node to the scene after adding the splash screen sprite node had been working fine.  Explicitly setting the zPosition for the video node, now allowed the video to be shown in iOS 9.  But, this had an undesirable side effect in iOS 8 and prior.  Now the video was displaying a black screen that flashed before the video started playing.  The solution to this was to test for the availability of an iOS 9 feature and only set the zPosition on iOS 9.  To do this we simply tested to see that [SKCameraNode class] returned true before setting the zPostion.  We also found a few other places in the app where the zPosition needed to be set.

At this point things were looking good, except on iOS 9 the intro video was not playing smoothly.  It would play about a third of the way though, freeze, then jump forward and play the final third of the video.  This was not an issue on devices that where running an older version of iOS.  This problem was isolated to the SKLabelNode we where adding at the bottom of the page to let the user know that could “tap to continue” and skip the rest of the video.  We had actually had similar performance issue trying to use an SKLableNode to display the score you are awarded when you catch a bug.  The fix for this was to swap out the label node for an SKSpritNode with an image for the text message.  The downside of this is it makes it impractical to internationalize this text.

Fillip’s Feast Intro Video

 

Layers

Layers

The whole idea of layers has crept up on me slowly surfacing in my thoughts at various unexpected times. I am recalling as a child when playing in the mud on a rainy day starting a construction with a base. Using the base adding the different textures of mud by adding the amount of water I wanted to create the mud project I was working on. My brother and I would play together making comics. He was the artist drawing the pictures and I was the author filling in the dialog and commentary. Without any training at all, we worked in layers adding simple outlines first then filling in the details as we narrowed down our story. I’ve also been thinking about how nature is also arranged in layers from its tiniest components to our largest mountains although the arrangement is structured spherical. Now, of course, I am a “why” person. So I asked myself: “Why are you thinking about all these things?”

I had not realized I was actually thinking about the concept of layers until one day in one of our Infinite Cortex Creation meetings we were discussing possibly using a different production program. During our discussions, the boys were using all kinds of illustrations with grids, figures, rotations, pieces of figures, lighting, depth, shading, and angles. They were asking each other specific questions then one would bring up a project he was working on and the discussion would roll forward on the capabilities of the program again. Now, not to toot my own horn, but I am pretty adept at visualizing in 3D (How I passed organic chemistry pretty easily before there was computer modeling.). As we completed our discussion during this part of the meeting I was still “seeing” the elements when I was asked about the back story of one of the characters in Gellini. I shifted my visualizing to “seeing” Gellini without missing a beat. Whoa! Writers create in layers too.

As I saw Gellini moving through her story, she was not in a void. She was moving through a space and time creating a climate. Gellini, too, has a back story or, if you will, a history. Writers, it seems, draw on their ideas, then begin a process of developing the layers to support the story or nonfiction outcomes they have targeted. As with any creationeer process, writers differ on how they go about creating their layers per personality, training, project, process, and a whole host of other variables.

If we take a look at any “How To _____” book on almost any subject, it is broken down into layers. You may argue that a talented person does not need all those layers. I would argue back. Study any known talent’s process and discover the work that you see. There is a rare one who does not work meticulously on specific elements and are often more ruthless on their expectations of themselves than others would be. The talent may not have been able to tell you what they were doing but they were naturally developing their own process of layers. My grandfather was a gifted wood carver and broke down the process to teach other people. When complimented, he would defer and just say, he used the same process as he was teaching, he just came by it more intuitively.

The Three Little Pigs: Font Dev and Style

Context is everything, the two comic book fonts I created looked nice in my last post, but they weren’t in word balloons or on a comic book page.  So I dropped them into a page I made to get accustomed to my Cintiq Companion 2, as well as exploring the overall look and style I wanted to achieve.  Already I can see some adjustments need to be made to the fonts, especially for low resolution situations.

style and font

 

Got any critiques or suggestions, let me know in the comments below.

fillip feast health dashboard

Game Health Indicator

This post is going to present a simple solution for building a dynamic health indicator for your game.  This is based on the health indicator we included in our Fillip’s Feast game, available in the Apple App Store.

The following are the features we wanted for our health meter.

  • Follow the overall look of the game
  • Provide level indicator based on size
  • Provide visual color indication of health

Step one was to create a sprite in which to display the health level.  For our game the health indicator shows as a bar within a wooden sign.

Health Status Bar

Next we need to create a sprite that can be scaled to represent the players health level and who’s color can be adjusted to give an additional visual indication of level.  This is done by creating sprite node with a color and size.  The initial color does not matter since we will be setting the color based on the players health level.  The width is set to match the length of the level indicator in our banner.  For our banner this is .875 of the full banner width.


// For the reserve indicator create a white sprite node the same size as the health banner
CGSize reserveSize = healthBanner.size;
reserveSize.width = reserveSize.width * 0.875;
self.reserveIndicator = [SKSpriteNode spriteNodeWithColor:[UIColor whiteColor] size:reserveSize];

// Set the anchor point for the indicator to be the left side for horizontal and center for vertical
self.reserveIndicator.anchorPoint = CGPointMake(0.0,0.5);

// Posistion the indicator so the left side lines up with the indicator area in the banner
self.reserveIndicator.position = CGPointMake(-reserveSize.width/2,0);


The final setup step requires the creation of a SKCropNode and mask so that health indicator fits within the appropriate portion of the banner window.  For this we use another sprite image.

Health Bar Mask


// We will use a crop node to mask out health indicator so it only shows up in the healt bar area of the banner
SKCropNode *reserveCropNode = [[SKCropNode alloc]init];
reserveCropNode.maskNode = [SKSpriteNode spriteNodeWithTexture:[health textureNamed:@”HealthBar_Mask”]];

// Add the health level indicator as a child of the crop node
[reserveCropNode addChild:self.reserveIndicator];


The final piece is to add a method that will be called to update the health meter whenever the players health level changes.  When the player has full heath the meter will be green.  When he is almost out of health it will be red and the length of the indicator will scale accordingly.


– (void)updateReserveDisplay:(NSInteger)reserve {
self.reserveIndicator.color = [SKColor colorWithRed:((100.0-reserve)/100.0) green:(reserve/100.0) blue:0.0 alpha:1.0];
[self.reserveIndicator setXScale:(reserve/100.0)];
}

Here is how the banner looks with about 70% health.

fillip feast health dashboard

A copy of a sample app, health_level_indicator, that puts all of this together can be found on our github page.

You can find me on twitter @mellowcoder

An Isometric Point of View

6d89bcd782b67e3646835d5fb4bc23As I’ve been thinking about future game possibilities for our company, I’ve become enamored with the isometric point of view. This is when basically you design the point of view of your game from a top down angle where the grid for your ground plane forms parallel lines.

You see this point of view in the smallest independent games all the way up through major platform releases like the Diablo series from Blizzard.

As I’m working on the concepts for games, I’m also performing a series of exercises to get my self thinking from this point of view.
IsometricSketching

Everything from doing throw away thumb nail and silhouette sketches to trying to design how architecture can be rendered so it feels dynamic but doesn’t block your point of view.
Here is a look at one of the exercises I’m working on. Staring with a concept sketch.

MercyConcept
After developing the character in a hero pose, if I was developing this character fully there would be a break down of different angles and behaviors, clothing, equipment and variations. But in this exercise I’m predominately concerned with developing an idle pose that works on an isometric grid. Because I’ve made it a flying character that pose can be fairly dynamic with the wings flapping to keep them in the air.

mercy

I’ve also started trying to figure out the detail I can put into the character with out slowing down my animation process or letting the character get so busy that it’s hard to read from far away. In this case, the sketches I’ve started I are too detailed for the end goal. While I like the design, given our workflow, it takes too much time to draw, and the features need to be simplified.

mercyAnimation

As I’m working of this point of view and the challenges and opportunities it presents, I start thinking about some of the art I’ve already done. I wonder for instance how difficult it would be to take a concept like this and translate it into a playable isometric scene.

DugTooDeepGood

Over all it’s an extremely interesting way to be thinking about game design and I know I’m just scratching the surface of possibilities.