Cow Defense System – A Shooter

One of the most classic types of games is a space invader style game. Cow Defense System is just that: aliens are coming down from the top of the screen to kidnap your livestock.

The game uses a lot of components which can be re-used for other games. The engine also allows modifications for different games in the same genre.

cds_screenshot1

Model View Controller

There’s a clear distinction between the visual representation and the data of the game. The Game class is the core of the game logic. This is the place where all models and views are hooked up. The WorldView contains all views of the game mainly in the form of ViewPool instances.

View Pools

This game uses the ViewPool system: all views necessary are created at the start of the game in a hidden state and are obtained when something has to be displayed.

There are a couple of reasons for using view pools. The first is that we try to create as little garbage as possible. The second might be a little less obvious. When running the game on a mobile device the views are actually implemented in native code. When a view is created it is registered in a data structure. This takes some time when it’s done a lot. To make everything run as smoothly as possible the view pool does this once and then keeps re-using the data which was initially created.

There are a number of view pools used and they are structured in layers.

Model Pools

This game also uses model pools. A model pool is a class which contains a list of models. The model pool calls the tick function on the active part of the list. In a shooter type game a lot of items have a short lifetime. For example, bullets or enemies are on screen only a limited amount of time. To prevent a lot of creating and destroying of objects the objects are grouped into pools which allows the objects to be recycled. The code in this library also handles the linking and unlinking of views and models.

The type value

A model pool can contain different types of models. The facilitate this, the ModelPool constructor takes an optional type parameter.

So why use a type when the type is already implicitly provided in the ctor (constructor) parameter?

Let’s create a class which we could put in a model pool:

And another one which we base on the first one:

Ok, we have two models. Let’s subclass the ModelPool. In this subclass the _allocItem function will be called:

Well that looks fine but after running it a couple of times weird stuff is happening. What’s going on? Unfortunately it turns out that using the instanceof keyword to figure out if an item can be used gives us correct values which are wrong…!?

The following code shows how the model pool breaks when using instanceof instead of a type value:

test2 is an instance of Test1 but we only want instances of Test1 object which are not subclassed!

The model pool introduces a public property type to all models in the pool which allows the model to identify which type of model it is.

cds_twins

Optimizations

After making sure the game produces as little garbage as possible – through the use of ViewPool and ModelPool- there is another step taken which makes this game perform very well: the structure of the layers and sprite sheets.

How does the DevKit render stuff?

All visible instances of ImageView are stored in a queue. The only thing which influences the order of the items in the queue is the zIndex.

When the scene is rendered the application executes a number of render calls. To get the best performance the number of render calls should be as few as possible.

How can we reduce the number of render calls? For a series of ImageViews to be grouped into a single render call, these properties have to be the same:

  • Sprite sheet
  • Opacity
  • Filter

If all ImageView instances are siblings and the listed properties are the same then they can be rendered with a single render call.

Events

Whenever a touch event is handled the view tree is traversed to find the actual view in which the coordinates of the touch fall. Usually there are a lot of views which are completely irrelevant for touch events, for example the views in a particle system.

To make sure that the system does not do a lot of redundant checking there’s a distinction made between display views and input views. The display views have the value blockEvents as true passed to the constructor. These views and all their children will not be checked when a touch event occurs.

The Engine

The Cow Defense demo game uses a number of classes which are based on the principles described above. But when you want to build your own game like this it’s not very convenient to start with a completely implemented game.

The shooter library on which this code is based contains a sample Application.js file. This file is a barebones engine demonstrating views dropping, a player which can be moved, projectiles and basic collision detection, all this in less than 250 lines of code!

cds_screenshot2

All classes in the shooter library are documented. The documentation can be found here:

A Generic Menu system

Since pretty much any game needs some kind of menu system this project will feature just that: a generic menu system which you can style as you please.

The code of this menu system can be found here: https://github.com/gameclosure/menus. We’ve made this demo part of the default installation of the DevKit. If you’ve already installed the DevKit then you can just run ./install.sh again to update and get the new application.

All dialogs in this demo use the same images in a consistent way which makes it easy to customize them. There are also settings to select the font family, stroke color and stroke style. Another option which you can change is the way the dialogs appear like sliding and fading in and out.

There’s a single file in this package which controls the default behaviour and style for all views. That file is called menuConstants and has the option to accept a custom configuration through a set method.

This demo provides the most common menus which keep popping up again and again. The first one is a basic menu with a number of items. Usually this type of menu is used as a main menu.

The background of this demo is a blue gradient which is just there to add some contrast when you use these menus. You can choose any background you like or just show the menu on top of the game screen.

Styling

The paths to the resources used by the menu system are defined in the file menus/constants/menuConstants.js. The default location for all graphics is resources/images/ui/. It is recomended that you use the same location. However, if you do want to change the paths you can use the menuConstants.set method to change the configuration of the menus which includes the image locations.

MenuView: A basic item menu

First let’s import the MenuView. Note that the demoMenu resources have been copied into this local demo project.

After importing this class we can create an instance. This is usually done in the initUI function in Application.js.

This MenuView instance has a show function that causes the menu to appear. In this case, it uses the default slide transition.

Calling the show function results in the following screen:
mainMenu

When the first option in the menu is clicked, the onOption function in the Application is called.

When the second option is clicked, the instance emits a Second event which can be used as follows:

One advantage of the event emission approach is that a single event can trigger multiple functions.

TextDialogView: A dialog view

The TextDialogView satisfies another common use case: the alert or confirm dialog. The following example shows how to use the TextDialogView class as an alert dialog.

First let’s import the class:

After importing the class we can create an instance:

One of the constructor parameters is a button array which must contain one or more button definitions. The modal option is used to darken the background behind the dialog.

When the show method on the instance is called the dialog appears which should look like this:

alertModal

DocumentView: A dialog to display simple documents.

To display one or more pages of text you can use the DocumentView. The JSON format allows you to select the color, size and font family of the font. Other options to create nice looking pages are: images, background colors and background images.

A demo game which we are working on will use this window to show information about pickup items:

documentBonus

The style options are basic but sufficient to create great looking dialogs. You can read the api documentation for more information on how to use this dialog.

TutorialView: A tutorial dialog view

You can use the TutorialView to teach users about your game. This is a dialog which contains an animation. Usually this dialog is only shown once for each option in the game. After showing it, simply set a value in localStorage to indicate that it should not be shown again.

To create a tutorial dialog, first import the class:

Then create an instance:

The animation displayed on the dialog is implemented using the SpriteView class.

When show is called the dialog should look like this:

tutorial

Building your own dialogs

The easiest way to build your own dialog is to subclass the TextDialogView and clear the text option. The TextDialogView has a content area which can be used for custom content.

Since the TextDialogView can show buttons these have to be passed to the constructor.

After calling the show method on this menu a dialog like this screenshot should appear:

custom

Ship an awesome, polished Android & iOS game in a few hours using JavaScript

The GC DevKit provides a solid, performant foundation for many different types of games. You can already build cross-platform games of any genre incredibly quickly using DevKit. At Game Closure, we regularly build new games in a day or less.

We wanted to see if we could take it even further: What if we narrowed our constraints a bit and built a framework on top of DevKit, designed for a specific game genre? Could we reduce the cycle from idea to implementation even more, so that developers can not only prototype a game in the span of a few hours, but build a fully-polished, shippable game in an afternoon?

We wanted to choose a genre that includes a couple interesting technical challenges for game developers. For this first experiment, we decided to build a framework for side-scrolling games. This is a classic genre, filled with greats like the original Mario and Sonic franchises, as well as modern variants like Doodle Jump, Wind Runner, and Tiny Wings. I can’t begin to count the number of hours I spent ignoring my coworkers and responsibilities because I was engrossed in Tiny Wings.

How can we abstract away some of the hard work in building those games? All of them have a few constraints in common:

  • The game scrolls in one direction, always forward.
  • They employ parallax scrolling to provide a sense of depth.
  • The level is potentially infinitely long, computed on the fly.
  • They have a simple physics engine.

Let’s build a framework that makes it easy to build games with those constraints. We’ll build a platform game to test the framework too.

Infinite Levels

To build a game with a never-ending level, we can’t just compute the level at the beginning. We’ll need to generate it as we go.

platform256

For now, assume we have a LevelLayer class of some sort which we expect developers to subclass.

At the very beginning of the level, we need to generate a chunk at least as long as the screen width. But as the level scrolls forward, we don’t want to build new sections of the level at every frame; instead, let’s generate the level in chunks.

Since we’re building a framework, we should think about this problem from the viewpoint of the framework. If we need data about the game, we need to ask the game developer. We could ask the developer to fill out a specific area of the level, perhaps one screen width at a time:

That seems reasonable at first glance, but what happens if we’re building a platform game that has platforms wider than one screen? A fixed-width chunk wouldn’t be flexible enough.

platform512

Instead, let’s just give the game developer the x coordinate where we need to start populating the level, and we’ll keep asking them for more data if they don’t provide enough. We need to know how far ahead they’ve prepopulated the level, so let’s have them return the width of the chunk they populated:

Cool! Now we have a generic way for the developer to specify chunks of the level as we scroll forward. As the screen scrolls forward, we’ll just call their populate() function and prepopulate enough level to ensure the screen is always filled.

But wait, we’re not quite done! As the screen scrolls forward, old level data falls off the left of the screen. If we leave it there, we’ll eventually run out of memory. One of the constraints we chose when selecting this genre was that we only scroll forward, so we know we don’t need the old level data once it leaves the screen. We don’t want the game developer to have to manually remove old level chunks, so let’s make that part of our framework too:

Performance Optimization

While we have avoided running out of memory, we need to address a couple common causes of performance problems in scrolling games.

If we’re going to generate the level on the fly, the populate() function needs to run quickly, otherwise we’ll notice hiccups in our game every time we generate a new chunk of a level. Additionally, when we allocate and destroy new views, they need to be garbage collected by the JavaScript runtime, which can cause noticeable lag spikes at arbitrary times. To write a performant game, we need to avoid allocating new memory whenever possible, so that we can reduce the need for garbage collection.

The GC DevKit provides a ui.ViewPool class, which we use in our games to preallocate a pool of views. When we need a new view, we obtain one from the pool; when we’re done with it, we release it. This pattern comes up often in game development, but it’s especially important in scrolling games where we’re constantly generating new views.

It needs to be drop-dead simple and intuitive for developers to use a ViewPool, and it should be as unobtrusive as possible. In our framework, the only place developers will be creating new views is within the LevelLayer.populate() function. They already create views like so:

Assuming we have a ViewPool in our LevelLayer, let’s create a function on the LevelLayer to make it easy to fetch a pooled view. We have a few requirements, though: we need to be able to instantiate any class for the view pool (like an ImageView or EnemyView), and we may want to be able to generate different types of the same object (like an ImageView representing a coin, and another ImageView representing a heart). A ui.ViewPool can only hold one class of object. In other words, our level may need several different pools, depending on the class and group of the given object.

Putting that all together:

If you’re confused, the ui.ViewPool docs may help.

Now we obtain our views from a pool, but we need to release them. Otherwise we’re right back where we started, running out of memory and all that.

Again, views might disappear for a couple reasons:

  • The developer removed them from the screen
  • The view fell off the left of the screen

Fortunately, the DevKit provides an event that we can handle to detect when a view gets removed from the screen, and we can release the view there:

Now, the developer simply needs to use obtainView(ViewClass) rather than new ViewClass(). Views automatically come from a pool, and they are released back into the pool when the view gets removed from the screen. This avoids excess garbage collection and makes the game perform more smoothly.

Parallax Scrolling

All sorts of games use parallax scrolling to provide a sense of depth. Fortunately, most of the hard work has already been included in our framework through the view recycling code above. A parallax game is really just a bunch of infinitely-scrolling views stacked on top of each other, with each one scrolling proportionally to the others. Layers designed to seem far away will scroll more slowly; layers close to the camera will scroll faster.

At this point, it’s just a bit of math and API design to end up with something like this:

Using that view becomes pretty simple:

And with that, we have a view that supports many layers of an infinitely-scrolling level!

Physics

kiwiAce_blink_0006

The DevKit doesn’t yet ship with a dedicated physics engine, but we’ve created games using JavaScript ports of Box2D. In this case, though, Box2D would be overkill. We just need some simple collision detection and movement. Something simple and flexible. Just enough physics to make game development easy without burdening the developer with the harsh mechanics of physical reality.

kiwiAce_jump_0004

I won’t go into great detail about the implementation of the physics engine I built for this framework (the source is well-commented), but I’ll describe its API. I built this engine in one day, so if you think you can contribute improvements, let’s join forces!

To be intuitive, our physics needs to hook directly into the existing view system. So we should be able to either subclass a Physics component, or add physics to an existing view like a mixin. This framework allows both options, for convenience.

In a nutshell:

DevKit’s ui.View contains a number of useful properties, but as I was developing this framework, I found that resulting game code was clearer with a few helper accessors: .getBottom(), .getRight(), .getCenter(), and the like. In other words, any view that has Physics added automatically becomes enriched with these methods.

Bonus Goodies

There are a couple other pain points I found while developing this test game:

Displaying a Score Efficiently

The DevKit’s TextView isn’t optimal for displaying a high score counter. Internally, it buffers strings of text for display, and a score counter changes constantly, perhaps every frame. Additionally, most score counters display the score in a monospace font for a cleaner look, and most fonts are variable-width.

I’ve included a ScoreView class that we’ve used internally, which takes in a set of bitmaps representing individual digits in a score. At runtime, ScoreView will render a bitmap of each character, a fixed-width apart, and cache each digit individually. This allows the engine to render a new score every frame without degrading performance. Other than performance, a ScoreView is used just like a regular TextView: call .setText(score).

Aspect Ratios

Every day, a new Android phone appears with a different screen resolution. By default, DevKit renders your game in a one-to-one mapping, with your main view sized equal to the screen resolution. In most games, you don’t want that kind of pixel-precision: you want to be able to write your game with a specific size in mind, and have it automatically scale to fit the screen size. Included in the platformer.util module in this framework is a function called scaleRootView(app, width, height); it resizes your main view to fit within the screen, letterboxing it if necessary. Then you can write your game layout logic with a fixed size in mind, without making changes for different screen sizes.

Results & Demo

Working in JavaScript, and with the DevKit, game development is already incredibly quick. I wrote both this framework and the sample game in only a couple days. Now that we’ve taken the time to abstract away some of the core concepts from a platformer-style game, we can all create a game like this even more quickly, with less code.

platformer

This is nothing magic. Looking at the platformer framework, you’ll see that it isn’t a massive, all-encompassing project: It’s pretty simple and easy to follow. But it’s powerful enough that it makes developing platform games incredibly easy. Designing a framework is always a balancing act: If you abstract away too much, you end up with an inflexible monstrosity that’s hard to understand and maintain. But if you abstract away too little, you have a lot of extra code for little gain.

Take a look at this framework, fork it on GitHub, and see if you can improve it.

Multiplayer Word Game

There’s been a lot of talk about building real-time multiplayer games on the DevKit. This makes sense, because everyone knows that multiplayer games are way more fun. Even these kids from the 50s have figured it out:

parlourgames

Multiplayer games have a natural edge over single player games. Would you rather play solitaire or poker? It’s a matter of taste, but your buddies will never ask you to play solitaire with them. All other things being equal, we tend to do what our friends are doing. Thanks to peer pressure, multiplayer games have the potential to spread faster and retain better than single player games.

They’re also a lot of fun to make. Here’s an example of a simple client for a fast-paced real-time multiplayer word game.

The Original

Wordrace is an extremely minimal multiplayer word game I made about five years ago. The backend is a dead-simple Python server written atop dez and rel.

Basically, you’re competing against everyone else who happens to be playing. Everyone shares a pool of seven letters. The point is to use those letters to make words. When someone makes a word, the word’s letters are replaced in the shared letter pool, which is a little jarring. So if you make smaller words, you mix up the shared letter pool more often, thus screwing with your opponents. On the other hand, bigger words get you more points. What a dilemma! Does any of this make sense? Play for a second to get the idea. Here’s what the original browser version looks like:

web

The protocol is a little silly. The server sends down 2-element arrays that look like this: [MESSAGE_TYPE, MESSAGE_DATA]. MESSAGE_TYPE is a string and MESSAGE_DATA varies, depending on MESSAGE_TYPE.

The client sends up frames delimited by :. For example, when a player tries to submit the word dog, the client sends dog: to the server. Besides sending a word, the user can also reset the current letters (if they’re bad) by sending !.

This reminds me of stories I’ve heard about Mexican sports writers interviewing Brazilian soccer players, with one side speaking Spanish and the other side speaking Portuguese, and both sides more or less understanding each other. Or this cat talking to a robot.

That’s pretty much it. There’s a bit more built into the protocol for scoring, but we’re about to implement a client so minimal that it mostly ignores scores, which would take us too far off topic, anyway, unlike cat videos.

So let’s make a mobile version of this game. First let’s slap together some views.

How It Looks

Make a fresh game with basil init and open up your shiny new Application.js. Delete launchUI and empty out initUI. Your imports at the top should look like this:

Now to build our game screen. Here’s your new initUI:

This creates a start button and a game screen with a row of letters at the top, a TextView for displaying game events in the middle, and a row of buttons at the bottom.

What It Does

So now we’ve got a bunch of views bound to nonexistent input handlers. Here are the handlers:

These handlers invoke a couple utility functions, this.log and this.send. They look like this:

The last handler, this.connect, binds several network events to callbacks. Here are those callbacks:

And here are the individual read events triggered by this.onRead:

And it works!

debugger

Woohoo!

The Whole Shebang

That’s the whole game. Done.

game

The project lives at this github repo. If you feel so inclined, install this APK on your phone and play against your friends and others on the site. Trust me, it’s somewhat fun.

The Point

What I’m trying to get across here is that multiplayer games aren’t rocket science. All you have to do is come up with a protocol — even a dumb, asymmetrical protocol — and stick to it. The vast majority of your code doesn’t even have to know about it.

Upstream

No one on the client side has any idea what upstream communication looks like, except for one magical function. Check out this.send:

There it is: this.sock.send(data + “:”);. That’s all it takes to define a colon-delimited upstream protocol. Here’s the matching line in the Python server code:

DELIM is a colon, and self.__parse_input is the input handler. Thus, the server knows that incoming frames are separated by colons. Simple, right?

Downstream

Jumping back to our Application.js, behold this.connect:

Every DevKit socket comes with a reader. It has three read modes:

  • stream: pass all data along to onRead handler (default)
  • json: buffer until you see a JSON object and forward to onRead handler
  • delimiter: read until you see some string and forward to onRead handler

The reader essentially eats a stream of characters and expels frames consistent with the read mode. It sits between the native socket’s read stream and the JavaScript socket’s onRead callback. By default, it forwards every new chunk of data immediately. This is called stream mode.

Here, we want json mode. Thanks to reader.js, a mere this.sock.reader.setMode(‘json’); clearly instructs the client-side socket to deliver you JSON objects as they arrive. All the server needs to do is write stringified JSON.

Final Words

Our socket works great on phones, but not at all in the browser, because browsers and real-deal sockets don’t mix. If this makes you sad, simply use a WebSocket in the browser and a real socket on the phone. You can either write a server that speaks WebSocket and regular stream-speak, or point your browser version at a WebSocket proxy (examples: 1, 2).

socket

If you don’t feel like doing that, build your game using the GC Test App (Android, iOS), which is pretty much just as fast as developing in the browser. Now go forth and craft the finest multiplayer games the world has ever seen!

Add Offline Documentation in 15 Minutes

Your customers want offline documentation. They want to be able to use your product on an airplane and look at the docs. They want to be anywhere and everywhere and they want to take you with them. Too bad it’s unmaintainable, risky, and complicated.

unplug-me-fb-small

Or.. Is it really?

You developed the best application in your space and now you’re looking at how to make it accessible. — That means documentation! If you’re like us, you found pandoc, did your documentation in markdown, and wrote a build script to compile it to static HTML.

Then, like us, you probably sat down and scratched your head for a bit and decided it was too much work to bake your HTML for each release, or decided it’s not worth bloating the download.

We found a great solution for implementing offline docs using HTML5 that is:

  • Easy to do (took us 30 minutes)
  • Makes minimal changes
  • Safe to deploy

The Magic Formula

There are only three easy steps to adding this useful feature to your docs:

  • Create an index-offline.html from your index.html file.
  • Add a cache.manifest file generator to your docs build script.
  • Configure your web server.

Use an HTML5 cache manifest attached to an index-offline.html file. This is like your normal index.html except that your leading <html> tag looks like this: <html manifest="cache.manifest">. Then have your doc build script create a cache manifest. Here’s how we did it in bash:

The resulting cache.manifest looks like this:

The NETWORK tag above is needed so that jquery, Google Analytics, and other off-site resources still work!

And the Revision counter is important to keep the file fresh each time you build.

Configuring nginx (for example)

Add MIME Type: text/cache-manifest

We modified /usr/local/etc/nginx/mime.types to include:

Add Cache-Control: no-cache

We modified /usr/local/etc/nginx/nginx.conf to look like this example:

If you get a 404 from curl testing it’s because you put the location outside of /. It’s important to nest location tags as in the above example.

Test it: curl

The expires -1; tells nginx to add a Cache-Control: no-cache to the response, as shown below. Also note that the Content-Type has been set to text/cache-manifest.

The curl -I command was perfect for testing.

Ship it!

Testing it was pretty easy on Mac with brew. We ran brew install nginx and made the above changes, and tested with curl. Then we deployed it to our website. We deployed with confidence because we had already tested the changes (which are minor), and the changes only affect index-offline.html.

To hook it up, point the webkit view in your app towards http://docs.mysite.com/index-offline.html instead of http://docs.mysite.com/ and you’re all set.

Users that install your app will hit index-offline.html, the attached manifest will have their browser cache the whole documentation site in the background, and then they can unplug and go anywhere with it. Whenever your documentation is rebuilt, the cache.manifest file revision rolls, and their browser will download the changes as normal. Great!

html5

It was eye opening to us that such a wonderful feature like offline documentation can be had for free thanks to HTML5. We have found a bunch of other great ways to exploit HTML5 features to simplify our release process for the Game Closure DevKit and are looking forward to sharing them. As we have time we’ll write up some of the better ones over the next few weeks.

Space Blaster Meets Mobile

I recently discovered a sort of unbelievable game development platform by Scirra called Construct 2. Using this tool you can basically create an entire game without any programming whatsoever. It’s pretty darn neat.

Space Blaster is one of their demo games. You can find it on the Chrome Web Store, as well as Facebook. After playing a few rounds, I wanted to try it out on my Nexus 4. I downloaded Construct 2, opened up Space Blaster (which ships with Construct 2 as an example), and exported an HTML5 app. It looked like this:

I ran:

This is where my troubles began.

Mobile Browsers are for Reading Email

I opened Space Blaster in a browser on my phone and almost immediately started crying. The first thing I noticed was how laggy it was. The frame rate was so low that my bullets were passing right through enemy ships. The second thing I noticed was the absence of sound. Then it crashed.

flip

This bummed me out a little bit because the actual game is super fun. It’s got great sound effects, and the animations are very impressive when they actually play smoothly. Then I got a little mad, because I should know better. Playing a game in a modern mobile browser is like reading the news on a flip phone or sending an email with a beeper.

beep

Any of these can be attempted, but why? The basic reason, I suppose, is that folks insist on doing everything on the go, which means working with the materials at hand, no matter how terrible they are. I find myself in a similar situation, the bearer of an HTML5 canvas game that I yearn to play on my phone. Luckily, I work at a company that makes a native-accelerated OpenGL canvas for running HTML5 games on mobile.

Why Would Anyone Do This?

enemies

Let’s step back for a second and really appreciate what Construct 2 has to offer. It enables someone with zero coding experience to create a complete HTML5 game. Is your mind blown yet? It really should be. Think of all the sweet game ideas that at this very moment are bouncing around in people’s heads, and how many of those people aren’t programmers. Five years ago, these ideas would never see the light of day. Nowadays, thanks to frameworks like Construct 2, they really can become games. That’s truly awesome.

mines

So where does Game Closure fit in? It’s quite simple. Essentially, lots of people (including Construct 2 users) are creating HTML5 games that run awesomely in real browsers and terribly in mobile browsers. We’ve already solved this problem with a custom native implementation of the HTML5 canvas. If we can leverage our technology to help bridge this gap, we can bring these games to a much wider audience. If we can streamline the process, folks will be able to make HTML5 games using any framework out there and deploy them to smart phones with ease. This degree of compatibility, after all, is the point of HTML5 and open standards in general.

Step one is porting Space Blaster.

Getting Something on the Screen

Basic Setup

I made a fresh game with basil in devkit/projects, and pulled in the JavaScript and images I figured we’d need from Space Blaster:

My src folder now contained 3 files: the Application.js generated by basil init; c2runtime.js, where the Space Blaster game lived; and jquery-1.7.1.min.js, which Space Blaster seemed to require (and which I renamed to jq.js for ease of importing). I opened up Application.js and manifest.json and started tinkering.

Step one was to get something running in the browser. First I changed the game’s orientation from landscape to portrait. This simply entailed replacing the string landscape with portrait in the supportedOrientations array in manifest.json. Easy peasy.

Next I turned to Application.js, which looked like this:

Great. I deleted initUI and replaced the TextView import at the top with a couple imports of our own:

At this point it ran with no errors and transitioned from a GC splash to a black screen. What fun! Now we just need the actual game.

Digging, Lying, and Cheating

So how do you start this thing? A quick scan of the index.html generated by Construct 2 reveals the magic line to get the show on the road:

A search for this function in c2runtime.js takes us to this code:

Seems straightforward enough. They’ve got this cr.createRuntime thing, and they attach it to the window object as cr_createRuntime. Fantastic. The only problem is that they expect to pull a canvas out of the DOM using an ID. There’s no DOM on the phone, so this approach won’t work. But wait! There’s that other function, createDCRuntime (attached to window as cr_createDCRuntime), which just takes a width and height. Worth a shot! I added

to my previously-empty launchUI, leaving width and height undefined because the constructor resizes the canvas to the max dimensions available, which is what we want. I ran it again and immediately got an error:

Fair enough. Construct 2 barfed while trying to route input events to their handlers. You guys didn’t expect this to work right off the bat, did you? Anyhow, it seemed that the undefined variable was being set a few lines up, in this code chunk:

So what’s this.runtime.isDirectCanvas? It gets set in the Runtime constructor, like so:

And what’s canvas? That’s just the object that gets passed in by cr_createDCRuntime (see above), and all it has on it are width, height, and dc (which equals true). So since we’re using cr_createDCRuntime, isDirectCanvas is definitely true, which means that elem and elem2 get set to window["Canvas"], which, according to the Chrome debugger, isn’t anything. So let’s make it something, and while we’re at it we can map our input events to Construct 2′s handlers.

Construct 2 will now add its event listeners directly to what it thinks is a “direct canvas” (which we know to be our shim object). Our shim in turn will create input callbacks that modify our input events (Construct 2 expects a “changedTouches” array) and pass them along to Construct 2′s handlers. Simple dimple!

Run it again and we get a different error, which means we’re making progress. This time, AppMobi is not defined, which makes sense because we’re not AppMobi. The error happens here:

Construct 2 is trying to get a canvas from AppMobi. Time to lie:

We’ve given them our canvas instead. The guilt will fade with time.

pinoccio

Refresh for the next error. Now that Space Blaster has successfully gotten its hooks into our Context2D, it expects to find a function called present. Here’s where the game tries to call it:

At this point I’m pretty happy that we’ve made it to the draw function. This just might work! So what’s present? Turns out it’s an AppMobi/DirectCanvas thing that gets called every tick to trigger a render. Our canvas knows how to render without this. Let’s cheat!

Great! Refresh, next error here:

Oh man, this direct canvas is so demanding! Let’s just cheat again:

This is fun.

I Still Can’t See Anything

Ok, now we’re getting an error in ctx.drawImage. This is because we haven’t told Construct 2 where the graphics are hiding. Let’s do it!

As it turns out, the whole game is defined in a JSON object at the bottom of c2runtime.js. In this case, the object is over ten thousand lines long. Anywho, the most recent error indicates that it’s trying to find an image at images/background3-default-000.jpg. The DevKit serves image assets in resources/images, so this is an easy fix. We just have to override cr.getProjectModel, which generates the game definition object. I added this to launchUI:

That jsio line at the top is some black magic for grabbing a local variable out of a JavaScript file. Since we’re importing c2runtime here, we can remove the import from the top of our Application.js. The rest basically remaps Space Blaster’s image sources to their new home in resources/images. When I run it again I get the same error:

This basically means it still can’t find the image it’s looking for. Let’s tell the DevKit not to build spritesheets for these assets, as they’ve already been sprited. Create a new file in resources/images/ called metadata.json, and paste in this:

And it works!

I Still Can’t Hear Anything

Right, the original had sound, and lots of it. Let’s grab the audio assets we need.

Now we just need the game to look in the proper place. We’ll solve this the same way we handled image asset paths, by overwriting the project model.

Refresh, and we’ve got sound!

Wait, What About the Phone?

phone

Remember a million years ago when the whole point of this was to run Space Blaster on a phone? Let’s give it a shot. Plug an android phone into your computer and start typing in a terminal:

Great!

A Few More Fibs

You just installed the game on your phone. If you try to run it, you’ll get a gross jQuery error:

Man, I’ve heard enough out of you, jQuery. You worked fine in the browser, but now you expect a full DOM on the phone, and that’s just not going to happen. What exactly is this game doing with jQuery? I removed the jq import at the top of Application.js to find out.

It turns out that everything runs fine without jQuery, for the most part. The only thing missing is window size detection, which only happens if jQuery is present:

So let’s fake it. Add this to launchUI:

Looks good in the browser. After rebuilding and reinstalling on the phone, you’ll see this:

Yup, there’s no DOM, so there’s no document.getElementById. Time for more lies!

Don’t worry, no one ever has to know. Rebuild, reinstall, and see the next error:

Looks like we’ve got more shimming to do. Update window.AppMobi to look like this:

That’ll do it. Our loadSound doesn’t actually need to do anything, because our AudioManager can load everything we need up front. You’ll see.

But Where’s the Game?

waldo

Rebuild, reinstall, and run. The first and last thing you’ll notice after the GC splash is a black screen. This is because alwaysRepaint defaults to true on the GC engine. When alwaysRepaint is true, the engine draws every tick. Since we’re not doing any of the drawing, this just clears the canvas every tick, obliterating whatever Space Blaster just tried to draw. Let’s turn that off:

Next thing you know you’re looking at the Space Blaster main menu on your phone. Yay! Before you pop the champaign, tap for the next error.

Creating createPattern

The problem:

This example demonstrates the basic usage of createPattern:

It’s basically an image tiler with a funny API. Very doable. Here’s our 2D Context’s implementation of fillRect:

Great, all we need is a createPattern that returns some kind of object, and a this.fillStyle test of some sort in fillRect, and we’re good to go. This createPattern should do the trick:

Now let’s just handle this case in fillRect:

redmissiles

That’s all it takes! Now the DevKit supports createPattern invocations of various kinds: ‘repeat’, ‘repeat-x’, ‘repeat-y’, and the pointless ‘no-repeat’. Here’s a before and after. The createPattern on the left returns the string “red”. The createPattern on the right returns the object discussed above. Just look at all those missiles! Nice work, createPattern.

And now we’ve got a game! Wooo! Unfortunately, our game has the following problems:

  • the screen goes black when you touch it
  • there’s no sound
  • some of the images are having transparency issues

These are hard core dealbreakers. Luckily, they’re easy to fix.

Black Screen on Touch?

This is due to another flag on the GC engine. Remember alwaysRepaint? There’s another engine flag that defaults to true called repaintOnEvent. The idea with this flag is that in cases when you’re not repainting every tick (alwaysRepaint == false), you’ll probably want to repaint when the user taps the screen (which generally results in some visual difference). Since we’re not doing any of the drawing, this behavior will simply result in a black screen whenever the user taps. So let’s turn it off. Add

to launchUI, and you’re in business! Now take a break to play a few rounds. Yes, this is JavaScript, and yes, it actually works. Let that sink in before moving on to the next issue.

Sound?

Ok, so we copied over the Space Blaster audio assets to our new project. They’re running fine in the browser, but we’ll have to roll our own sound support to get a peep out of the phone. Luckily, the DevKit already did this for us.

We’ve got two copies of each sound: an m4a, which is played in the browser; and an ogg, which is played on the phone. We want file names without any spaces or weird punctuation, because this simplifies our AudioManager configuration. So I made a simple Python script that looks like this:

And ran it like this:

Great! Now we can just drop in our AudioManager, which looks like this:

Remember when we shimmed loadSound with a function that didn’t do anything? That’s ok because of the preload: true here, which loads up all the sound effects for us. Also, I flagged the music files (epicarpg and mattoglseby___3) with background: true. This guarantees two things:

  • these songs won’t preload (this would take up memory and time, and is unnecessary, as music files are streamed)
  • these songs won’t play at the same time (playing one stops the other)

Don’t forget to import AudioManager at the top of Application.js:

Cool. Now let’s hook up our AudioManager to the AppMobi shim:

And it’s a game! With sound! Woohoo!

What’s with the Black Boxes?

Here’s a funny one. As it turns out, some of Space Blaster’s graphic assets use regular transparency, and others just have a black background. Silly game developers! Here are two explosion spritesheets from the game:

exlosion1-sheet0.png, exlosion2-sheet0.png:

explosion1-sheet0explosion2-sheet0

See what I mean? The quickest fix here is an ImageMagick batch conversion, a la this script:

It finds all the graphics with names that start with “explosion1″, “explosion3″, and “playerthrust” (the other images use regular transparency), and uses convert (ImageMagick‘s command-line utility) to replace black with transparency. Run it:

Great!

Spit and Polish

What’s left?

Icon

I used the GIMP to steal this image from one of the enemy spritesheets and resize as necessary:

ios144

Setting the icon in manifest.json is easy:

Splash Screen

This game asset seems sufficiently spaceish:

background3-default-000

We can make this the splash screen with a few simple lines in manifest.json:

Retrospective

We did it!

What We Accomplished

Here’s the Application.js we ended up with:

And here’s the APK we ended up with: Space Blaster APK.

The project lives at this github repo. As it stands, you should be able to run any Construct 2 game on a phone by simply:

  • 1) exporting your Construct 2 game as an HTML5 app
  • 2) cloning this github repo
  • 3) replacing src/c2runtime.js with the c2runtime.js generated by Construct 2 for your game
  • 4) replacing everything in resources/images/ with the image assets from your game
  • 5) replacing everything in resources/media/ with the audio assets from your game
    • update the AudioManager in Application.js accordingly
  • 6) running fixAudio.py and/or fixImages.py if necessary
    • if you have to run fixImages.py, replace the target prefix array on line 12 with whatever prefixes correspond to images with a black background that should actually be transparent

I know that’s six whole steps. I want to simplify this process and probably turn this into some sort of plugin. I’ll keep you guys posted.

Why It Matters

To put this in perspective, consider the general case of porting a game from one platform to another. In fact, look at what this guy has to say about it:

You don’t need to be a 1970s stand-up comedian to know that there’s a large lexicon of monosyllabic, four-letter words for describing something you don’t like – but only PC gamers use the word “port” with such a fervent degree of repulsion.

Basically, he hates it, and so does everyone else, because it’s hard and it usually involves a rewrite. Now, we just took a game that only runs in a desktop browser, wrote about 100 lines of JavaScript, and came out the other end with a game that runs smoothly on Android and iOS. Did we rewrite the entire thing in Java and Objective-C? Did we hire a team of developers and set aside months of dev time? No dude, not even close. It took one developer a couple days to figure this one out, and the next Construct 2 port will take a matter of minutes.

The big takeaway here is that when we use open standards, we get to pool resources. I didn’t write Space Blaster, and Scirra didn’t write the DevKit, but they play nice together because we both bought in to the “HTML5″ idea. And so have lots of other game engines. This means that you should continue to develop your HTML5 games using any framework that tickles your fancy, because when the time comes, you can easily deploy to mobile using our native canvas. Isn’t that great? I think so.

Unravelling Nested Callbacks with FF

If you’re a javascript developer, then callback functions are your bread-and-butter. You know all about the so-called “pyramid of doom”, and you know all kinds of ways to defeat it. If you’re a javascript developer, you might regularly use a promise library like Q, or perhaps something more sequential like node async. Maybe you even get excited or angry when someone mentions co-routines. But if you’re a javascript developer, the last thing you ever wanted in life was another asynchronous flow control library. Well, it might be time to take another look.

The Problem

Let’s start with what we all know, callback hell:

The problem with this is twofold. First, unless you have a really wide screen it is hard to read. But more importantly, as the logic grows more and more complex, code like this becomes difficult to reason about. For instance, what do we do when an important method like addFriend returns an error (can we still cache the userData)? What happens if an uncaught exception is thrown inside/outside the callback chain? How do we schedule multiple asynchronous operations at once and wait for them all to complete before continuing?

The Workarounds

There are a variety of ways to deal with the callback problem. One technique is to use a promise library. In a nutshell, promises ditch the callback paradigm in favor of an event based system. Using a method like then, you can register onSuccess and onError (and sometimes onProgress) handlers for your asynchronous operations. What makes this especially useful in terms of the “pyramid of doom” is that promises can be chained together. Let’s rewrite the nested callbacks above using the Q library to see promises in action:

In the above example, we used the Q.nfcall method to turn our asynchronous operations into promises. Then, in the onSuccess handlers, we return new promises representing the next async operation. In this way we are able to “schedule” a series of handlers for our asynchronous operations rather than simply nesting the callback functions. It is also important to note that in order to use userData across these handlers, we must declare the user variable in the enclosing scope, and set it in the authenticate success handler. Even still, the result is noticeably cleaner code than nested callbacks.

Another method for unravelling the pyramid is to use a generalized flow control library like async. Let’s rewrite the above example using this library instead:

Here we used the async.waterfall method to specify an array of functions that we want to run in order, and one at a time. Each function is given a next parameter, which we use to forward the results of the asynchronous operations to the proceeding function. Once again, we have to declare a user variable in the enclosing scope in order to use it throughout the handlers. In any case, a nice feature of async.waterfall is that all errors are forwarded to the final callback so you can deal with them all in one place. And again, the resulting code is much cleaner than using nested callbacks.

While both of these options are great, life-savers even, what happens when I want to intermingle series AND parallel operations? The logic using the aforementioned libraries can again become complex and hard to read.

Luckily, there are other libraries out there that are specifically designed for this situation. Let’s have a look at Step:

Like async.waterfall, we are specifying a list of functions to be executed in serial order. But instead of invoking next to move on the proceeding function, we use the this.parallel method to tell the Step library to wait for the results from the current operations before moving on. When we want to pass data to the next function immediately, we simply return the variable and it will get passed as a parameter to the proceeding function. This way we do not have to declare a user variable in the enclosing scope, we can directly pass it to the following functions.

FF

Unfortunately, there are some drawbacks to the Step library. First, the "this" keyword is reserved by Step, so you cannot bind your functions to any specific context. This makes code hard to read and write when following OOP practices. Second, if you want to forward local data from one function to the next you need to return it, which means you are limited to passing one object at a time. Third, you have to manually handle errors in each function rather then being able to handle errors in one place (like we did with async).

Tim Caswell, the original creator of Step, realized these limitations and created a vision of what Step would be like if he could rewrite it from scratch. The ff library is our extrapolation of this vision. Let’s see the above example rewritten in ff:

You’ll notice that ff does not rely on the this object, so you are free to run your code using any context you want. Also, using the ff.pass method we can forward as many variables as we want to the next function. This is more dynamic and flexible than relying on the return statement. Finally, if there are any errors returned in the callbacks (or even thrown during execution), we can deal with them all in one place by attaching an .onError handler.

Another interesting feature of ff is that it is entirely Promises/A+ compliant. This means if you have an existing framework that relies on the promise api, or if you just love the promise spec itself, you can still write your code that way:

In the above code, we used the then method to specify how we wanted to handle our ff operation when it finished running of all its functions (or produced an error). For more information about promises, check out Nathan Stott‘s excellent HowToNode Article.

In any case, FF was designed to be a poweful, concise, and easy to read way of handling your asynchronous operations. If you’re interested in learning more about how FF works, check out the documentation. Also, be sure to fork us on github, and come find us on twitter.

Happy coding!

A Quick Look at PVRTC

PVRTC is the image compression (like JPEG) that is built into PowerVR chips on iPhone and iPad devices. And, like JPEG, it should not be used for situations where you want lossless quality. It’s lossy.

The current state of PVRTC is not suitable for beautiful, hand-drawn artwork. I decided to investigate the best that you can do in case there was some utility for it.

Let’s keep this simple and just compare some beautiful game art with the PVRTC compression output. I used a part of a spritesheet from one of our games.

The Original Image

original

Gorgeous! Now let’s crush it with PVRTC:

–bits-per-pixel4 –channel-weighting-perceptual

Here’s the best result you can get from the PVRTC compressor:

bitsperpixel4-perceptual

Notice that the color has been distorted lighter, and there are now a bunch of light-grey tick marks spotting the tree, and the spiderwebs look thicker and messier.

Imagine these sorts of obvious image distortions across every one of your textures.

–bits-per-pixel4 –channel-weighting-linear

This one demonstrates something terrible about PVRTC when it comes to graphics stored in spritesheets (texture atlases). Note there are jaggy artifacts at the top that leak between parts of the spritesheet. This would cause awful visible animation glitches.

bitsperpixel4-linear

–bits-per-pixel2

Just out of curiosity I decided to try out the 2 bits per pixel mode to see how much worse it was.

bitsperpixel2

It has the same types of errors in the other PVRTC encoding modes but more exaggerated.

Further Reading

As a result of seeing these problems we decided not to use PVRTC for mobile games. Instead we use PNG graphics in the DevKit, since it provides an alpha channel and reasonable compression.

By the way, to generate these images I used the preview mode of texturetool, invoked as follows:

There is documentation for this tool available in the OpenGL ES Programming Guide for iOS.

Overcoming iOS Game Memory Limits

If you don’t know how to deal with memory properly on iOS, you will have a game with bad retention and poor reviews. Unless you know what to expect up front, memory issues will not come up on your just-unboxed test devices — because available memory varies by what is installed! You will see it first in user reviews. Confused? We got it handled, and you can too!

Roll back the clock to a year ago ~ We wanted our games to be beautiful, high-quality and engaging. These goals were in direct conflict with memory limits, which constrained how much we can present to the player.

For the iOS platform, we found that there were unique considerations to make the most of the memory space that the operating system allowed us to use.

Memory Limits

Heads up: We are focused mainly on beautiful 2D games, which are ironically more difficult from a memory-management perspective than 3D games. Some discussion of 3D-related memory management found its way in here too!

The Skinny

  • iOS restricts our apps to about 10% of the total memory available on the device. So we use that as a guide for an initial memory limit.

  • iOS provides low memory warnings that we had to write code to immediately handle. If our code failed to release memory fast enough, then iOS killed our app and the Xcode Organizer device log viewer indicated that the app was closed due to memory usage. We saw these “app crashes” without an exception trace log, and the reason was memory usage.

It was time to clean up our act…

The Game Plan

Memory usage for games falls into a number of basic categories:

  • Code (C, C++, Objective-C, Objective-C++)
  • Configuration (JSON, config.plist, NSData blobs, 3D models)
  • Sounds (.MP3 files)
  • Graphics (.PNG(2D), PVRTC(3D))

Reducing Code Size

We found that the following Xcode Compilation Options had a real impact on app size:

  • Linking : Dead Code Stripping = Yes
  • Deployment : Strip Linked Product = Yes
  • Apple LLVM compiler – Code Generation : Generate Debug Symbols = No
  • Apple LLVM compiler – Code Generation : Generate Position-Independent Code = No
Thumb-Mode Compilation

Like Thumb

The iPhone processor is based on the ARM instruction set, which has a compact “Thumb” mode that should reduce compiled code size to about half its original size. In addition this switch often improves performance on newer iPhone devices at the same time! To turn this option on for GCC 4.2 or newer we used the “Compile for Thumb” option:

  • GCC – Code Generation : Compile for Thumb = Yes

For LLVM and support for more platforms, we added a new User-Defined option to do the same thing:

  • User-Defined : GCC_THUMB_SUPPORT = YES
C++ Language Options to Simplify Compilation

Since we were not using C++ RTTI (Run-Time Type Information) nor C++ Exceptions, turning those options off was a win for performance, size, and compile time:

  • Apple LLVM compiler – Language : Enable C++ Exceptions = No
  • Apple LLVM compiler – Language : Enable C++ Runtime Types = No
Optimization Trade-Offs

Telling the compiler to optimize for size may be a good idea, through the space saved will be minimal. We decided to go for full optimization (-O3) though these other options could be useful for someone:

  • Apple LLVM compiler – Code Generation : Optimization Level = Fastest, Smallest [-Os]
  • Apple LLVM compiler – Code Generation : Unroll Loops = No

References:

1 Mac Developer Library: Code Size Performance Guidelines

MP3 Sounds

We switched to compressed MP3-format sounds.

We used ObjectAL as an OpenAL wrapper to play compressed sounds directly to keep memory usage at a minimum. Encoding audio at a lower MP3 bitrate, especially for the music, afforded another few MB of active textures, which made the difference between good performance and bad performance on lower-end phones on some games. Smaller files meant faster loading too, always nice!

Squeezing Graphics

After reducing code, configuration, and sound size as much as we could afford, it was time to move onto the biggest resource: Graphics.

Squeeze Graphics

Choosing a File Format: PNG

For 2D games like ours, the visual quality loss of JPG or PVRTC is too high to ignore. Beautiful pixel-perfect hand-drawn artwork gets crushed by these lossy formats even at the highest possible quality. See our article on PVRTC quality.

Alternative Formats

Alternative formats to consider are BCIF and WebP.

BCIF has Java and C versions, which are faster and better than WebP for lossless compression ratio. WebP supports a slightly lossy+alpha mode suitable for sprites that is an attractive option, though the encoder is only available as C code.

We decided to go with PNG for the first cut, though a modified BCIF looks like an exciting prospect for a home-grown solution. In a few tests it saves about 30% more space than PNG!

PNGCRUSH

PNGCRUSH is free open-source software (FOSS) that allowed us to get more compression ratio out of PNG image files by spending more time brute-forcing all the options. Sure- it takes a while to compress. But we only had to do it once a week for each public release!

In three of our resource-heavy games, the advantages of running PNGCRUSH are clear:

PNGCRUSH Performance

PNG images that “crush” well tend to be user-interface elements with fewer colors and sharp edges (~30% reduction), text (~50% reduction), and spritesheets with empty space.

Somewhat counter-intuitively, a more tightly compressed PNG image will also load faster. The main reason is that read time is shorter and the decompression code has less data to process so it can finish sooner!

Texture Atlases / Spritesheets

Since our game is designed for the high performance of OpenGL, textures must be power-of-two in size. So to use memory efficiently, texture atlases (also called spritesheets) were already a part of our game engine.

This is what a texture atlas looks like:

Whack-that-Mole Atlas

If each graphic in our game had been a separate image file, then they each would be increased in size to be a power-of-two in dimension at runtime, wasting a ton of memory just to satisfy that requirement. Instead– Sprites are combined into a single spritesheet and will use much less memory and will render much faster!

3D Games: PVRTC and Memory-Mapping

Images can be loaded as textures without decompressing into memory if they are stored in PVRTC format. This is a huge win for load times because as soon as the image file is read, the texture is done loading. This is great for 3D games because the quality loss due to the lossy PVRTC format is negligible.

A further exciting benefit of PVRTC is that the image files can be memory-mapped. This allows the operating system to do most of the texture memory management. Meaning that images outside of the active set may be unloaded automatically by the operating system without having to write more code.

For even less overhead it would be best to pack all of the PVRTC files into one large file that is memory-mapped at runtime. This saves memory because each memory-mapped file needs to be mapped at a memory address number that is an even multiple of the disk sector size. Since file sizes are rarely evenly divisible this would waste memory and would require more code and startup time to load each file. Offsets inside the blob for each file can be compiled into the app code with a pre-build script, or they can be read in through a separate configuration file.

3D games can still do some simple texture memory management and react to memory warnings by dynamically reducing the number of textures used in each frame. The OS will automatically unload the unused textures.

References:

1 iOS Developer Library: Using texturetool to Compress Textures

2D Games: Texture Memory Management

Once we started getting serious with iOS game development, very quickly our games started having more textures overall than we could have loaded at one time. Since we use OpenGL for graphics, this means that we needed a texture manager to control which images are in the “working set” of images that are being rendered to the screen, and which images should be unloaded when no longer needed.

A good texture manager makes full use of memory and keeps loaded as many textures as it can in a “cache” — so that the next time a texture is displayed, it is already available and does not need to be reloaded from disk.

Here’s an example ramp-up for game memory on startup:

Instruments Memory

And here’s a reaction to a memory warning:

Instruments Free Memory

Only the most recently-used textures would need to be kept in memory. So if we have some hint as to which images are going to be needed soon (sometimes called preloading), then those textures are “touched” to keep them “alive” in the texture manager cache of textures even though they are not being rendered in the current frame.

It is up to the texture manager to keep the game within its memory limits, since at runtime graphics memory is the only part of the game that can shrink further in reaction to memory warnings from iOS.

The texture manager for the Game Closure DevKit is in the native-core texture_manager.c code.

Reacting to Memory Warnings

We react to memory warnings by implementing the applicationDidReceiveMemoryWarning method in our Objective-C Application Delegate:

These warnings have four levels of severity {0..3}. The private API function OSMemoryNotificationCurrentLevel() can provide the severity level. The reported severity level will increase at each warning until your app is killed. However, failing to respond to any of these will cause your app to die.

Whenever a memory warning is received, we treat it as severe.

Our texture memory manager constantly analyzes how much memory is being used actively by the game. When a memory warning occurs it subtracts off about 10 MB from the used memory (a somewhat heuristic value that works in our experience) to come up with a new texture memory limit.

2D Games: Half-Sizing

On lower-end cellphones, the screens are smaller and can display less detail than higher-end cellphones that have much more memory. Since the same app must work on both classes of cellphones, it is a good idea to support texture half-sizing. This is an efficient operation that can be done during loading, and adds very little additional time to loading.

Johnny Mnemonic Doubler

Why half-size and not quarter-size or 60% size? Half-sizing is efficient to implement in C code by averaging blocks of 4 pixels into one. Efficiency is essential for lower-end iPhone 3GS devices where this is applied. Half-sizing reduces the memory footprint of images by a factor of four so will be good enough to fix memory problems, and quality does not need to suffer any more than this to be effective.

We do half-sizing on the iPhone 3GS, but it can also happen if our engine detects extreme memory limitations: It will smash that half-size button in an emergency attempt to stay under the limit.

A fully unrolled implementation of half-sizing decompressed and resizing to power-of-two (for OpenGL) may be found in the Game Closure Dev Kit texture_2d.c code; see the texture_2d_load_texture_raw function.

Appendix: Fast PNG Loading

Demonstrably faster load times and less memory usage can be achieved by using memory-mapped files on iOS. Normal file loading first allocates a buffer in memory to receive the file contents, and then reads the file from disk into the buffer. Memory-mapped files, on the other hand, make the file contents immediately available without the read step. This leads to about 30% better load times for PNG images in our testing.

MMap Virtual Memory

Files placed in the resources section in Xcode for your app will be available on the device. Verify that the files are present in the Build Phases tab of your target under Copy Bundle Resources if you have problems loading them on the device.

The first step to loading a resource is to get its path. This short code snippet demonstrates how to do that:

To quickly load this URL into a UIImage in Objective C:

Now, our improved memory-mapped file loader as C code:

The data would be passed to OpenGL’s glTexImage2D.

Note that F_NOCACHE and F_RDAHEAD are toggled to further streamline the loading.

F_NOCACHE prevents the OS from caching data during file reads, which would waste time since the data will not be requested twice.

And F_RDAHEAD gives a hint to the OS that each page of file data request will soon be followed by another request for the next page, so it should go ahead and start paging in the next page ahead of time.

These options are respected on iOS and measureably help to reduce load times.

Appendix: More Words on Sprite Packing

Sprite packing can pack game graphics into images up to 1024×1024 pixels that can be loaded by OpenGL at runtime. Note that 1024×1024 is a limit on some cellphones.

Bin-packing

Sprite packing is an interesting NP-complete problem also known as bin-packing. There has been a lot of work done on this problem in a lot of different domains including game sprites and several commercial solutions exist.

Spending a lot of extra processing time to pack tighter typically gains only about 3% better packing that is often lost anyway due to the power-of-two limitation on OpenGL textures.

In general, sprite packing algorithms should be optimized for performance once you have a reasonable approach.

It is also a good idea to store consecutive images in animations on the same spritesheet if possible. This gives better in-game performance since switching between textures can be minimized up front during spriting. Images that are going to be used together should be sprited together for the same reason.

Appendix: Initial Memory Limits

The initial memory limit of 10% total memory is straight-forward to calculate in C code:

Victory!

With all of these techniques brought to bear on the iOS memory problem, our general-purpose game engine now successfully navigates the entire iPhone and iPad landscape, from low-end phones to high-end tablets.

Kiwirun Active

Thanks to the techniques we developed, we can deliver pixel-perfect image clarity with short load times.

Game Closure “DevKit” for Mobile HTML5 Games is Open Source!

We founded Game Closure around the idea that HTML5 is the right technology choice for building successful iOS and Android games, and for the past two years we’ve been working to make that a reality. Today I’m proud to announce our public release of Game Closure “DevKit”, for mobile game development with Javascript. It is 100% Free and Open Source, and we intend for it to stay that way.

This is a technology that already powers dozens of games, and has been battle tested against literally hundreds of mobile devices by millions of players around the world. This is not a science project, or “pretty good for an HTML5 game engine” — the GC DevKit is a damn good mobile game engine that you can compare alongside the best of them. It is the only truly production-ready mobile game engine with such strong roots in JavaScript.



If you’re ready to dive right in, please check out the github repository, and the documentation!

Also, check out Kiwi Run, an early GC DevKit launch title. You can go ahead and play the game directly on the web, or just download it on your iOS (iTunes store) or Android device (Play Store). Kiwi Run is a fantastic game with nearly a million players since release two months ago, and I hope it will make the potential and possibilities of DevKit real to you!

Ethos

  1. GC DevKit is the best 2D mobile game engine in the world. If we find a weakness or this turns out not to be true, we’ll fix it.
  2. Web Technology is Great. We want to piggyback off of the fantastic technology created every day at Apple, Google, Facebook, Adobe, Joyent, Microsoft, and other innovative companies in the Javascript and Web space. We don’t want to re-invent our own debugger, profiler, editor, version control, art software/pipeline, so we didn’t.
  3. GC DevKit is always production ready. It is incredibly stable; check out Kiwi Run’s rating, it’s a 4.7 across many thousands of reviews. We made sure that the core engine is fast, 8000-sprites-on-the-screen fast. We created a UI system that can handle every aspect ratio, size, and type of device, and tooling to go with it. We made the process of distributing games on the App Store and Play store easy.

Licensing

We chose a dual-licensing strategy with the GPLv3 and the Game Closure Free License (GCFL) (you can read more about both on our licensing page). We tried very hard to make the core of the GCFL fit on a single page; it does, and it’s incredibly easy to read and understand. The idea here is to make sure that everyone who is benefiting from our ecosystem is also contributing back their modifications and improvements to DevKit. But we also want to allow studios and developers to create proprietary, closed-source, and for-profit games, completely free of charge.

Contributors

Our primary goal here is to get this technology in the hands of many, many developers, and along the way we’d also like to build a strong community of collaboration and participation. We have a guide for Contributors that outlines our Contributor License Agreement (CLA) which is very similar to the agreements you see in most open source projects, like nodejs, dojo, and Apache. The goal is for us to retain ownership of the code base so that we can protect users under both the GPL and the GCFL. The CLA and the licensing is designed so that users under either license will need to contribute code back for the good of the entire community.

Other than our required CLA, we intend to run the github project similarly to other Open Source github projects out there, complete with branches, pull requests, a mailing list… the works.

Join us!

Game Closure is hiring javascript hackers and (mobile) engineers. If you are interested in working here, either full-time or as an internship, please check out our jobs page. Thanks!