Saturday, December 22, 2012

Koi Live Wallpaper v1.6

  - New Feature: Shadows on fish and plants!
  - New Feature: Time of day light color
  - New Feature: Daydream support on 4.2+ devices

This updates adds shadows to all the fish, which really brings some depth to the scene in mt opinion.  As it looked odd otherwise, all the plants cast a soft shadow as well.  In addition, you can now enable time of day, and have the light color shift accordingly.

As a bonus, Daydream support is now implemented and working on any 4.2+ device!

Wednesday, December 19, 2012

Holiday Lights Live Wallpaper v2.0

  - New Feature: Simulated scrolling on some devices
  - New Feature: Daydream support on 4.2+ devices
  - Update: 2013 support for 'new york' scene

This brings Holiday Lights forward to our newest framework, and as a result simulated scrolling and Daydream support are now a reality!  In addition, you'll properly get a 2013 display when it comes to it.  :)

Monday, December 17, 2012

Jungle Waterfall Live Wallpaper v2.0

  - Update: Now using OpenGL ES 2.0
  - New Feature: Simulated scrolling on some devices
  - New Feature: Adjust individual time of day colors

This update brings Jungle Waterfall forward to our newest framework, which should give most folks a framerate boost, in addition to adding some nice bonuses like simulated scrolling, better stability and so on.  In addition, you can now individually adjust the colors for the fog based on the time of day!

Enjoy!

Wednesday, December 12, 2012

A Simple 3D Renderer in HTML5, Part 4

For the final installment, we will look at JSLint, accelerometer input on mobile devices, and audio.

(Previous entries: Part 1, Part 2, Part 3)

Code Error Checking, Standards, and Obfuscation

As we continued the project, we realized we needed to have at least some validation for our code so it wouldn't take so long to debug problems that turned out to be simple syntax errors or otherwise mis-typed values.  The best method we found for this was JSLint:

http://www.jslint.com/

Not only would this check our code, but it also introduced a lot of useful standards to keep anyone programming Javascript from getting themselves in trouble accidentally.  For our project's purposes, though, there are a few standard JSLint checks we decided to ignore:

  • Tolerate messy whitespace (white): This puts a lot of strictures on code formatting that don't comply with our own coding styles (most notably spaces around parenthesized expressions and line breaks before opening new curly braces).
  • Tolerate ++ and -- (plusplus): This is meant to keep developers out of trouble if they're expecting to use these operators and their side effects.  But for our purposes, we don't code with the expectation to use said side effects, and using these operators for loops is highly convenient.
  • Tolerate continue (continue): We're not quite sure why this is a standard JSLint check, but some loops are easier to write with the continue statement, so we turned this off.

JSLint has a number of quite useful standards that we revised our code to comply with:

All comparisons are done with the === and !== operators, because they force a type check as well as a value check.  If we just use the == and != operator, Javascript will try to be clever and may convert a string to its equivalent integer value or whatnot, which is likely not intended behavior.

As a nice carryover from standard Java, variables and normal functions are named with initial lowercase letters.  Only functions that are actually classes begin with uppercase letters.

All variables are defined at the beginning of a function, rather as a throwback to C.  In Javascript, variables are scoped within a function, but they are not scoped within a subset of curly braces, unlike most language derivatives of C.  So if you define a variable within a loop or conditional, it will be available for the rest of the function.  Forcing variables to be defined at the beginning of the function serves as a good reminder of this behavior.

With all of code JSLint-checked, the next trick was to be able to optimize and obfuscate the final version of the code for deployment to the web.  For this, the best recommendation was the Google Closure Compiler.

https://developers.google.com/closure/compiler/

This provides a very simple command line to put in your input file or files, and get optimized and obfuscated code out.  Plus, it will do analysis on the code and output errors and warnings.

Accelerometer Input

For this particular game, we needed to use the accelerometer to control the car when it was run on a mobile device.  There are a few different events available to get accelerometer input, but again, their availability varies depending on the device and the software version.  Android version 2.3.3 and below does not seem to support any of the accelerometer events we tried.

window.ondeviceorientation

This provides three rotation angles for the device, labeled alpha, beta, and gamma.  It's supported on all our target devices, and so we ended up using it for our control input.

window.ondevicemotion

This provides actual acceleration vector values, and depending on the device, separated gravity values.  It was not supported on all the Android devices we tested, though, as it's originally an iOS specification.

We also needed to track window.orientation, which gives values (from our tests) of -90, 0, 90, and 180.  This lets us know the screen's orientation, since the actual values returned from the accelerometer events are independent of the screen orientation.

Audio

Audio was the last major piece of the puzzle for this HTML5 experiment.  The HTML5 audio object is limited, especially on mobile devices.  On the surface, most of the usual functionality seems to be there: loading different types of files, playing them, seeking to points in them.  Looping isn't yet a first-class citizen; you have to set a delayed function call (often through setTimeout()) to restart the audio object.  A good discussion of what's available can be found here:

http://24ways.org/2010/the-state-of-html5-audio

iOS, however, throws all of this expected functionality out the window and severely limits what you can do with audio.  Apple explains their stance here:

http://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html

Essentially, they don't want users accidentally overrunning their bandwidth allotments because the particular HTML5 application downloads a bunch of unexpected video and audio data.  So they don't let anything download unless it's called directly from a user click action.  So far, the only solution that got us close to normal behavior on iOS is here:

http://remysharp.com/2010/12/23/audio-sprites/

We group all of our sound effects into a single audio file that's loaded when the user clicks the "Play Game" button.  Then, when we actually want a sound effect to play, we seek the audio file to its time marker and start it playing, then set a delay timer to stop it playing after its time length has run out.  This does limit us to playing a single sound effect at a time, because iOS only allows one audio object in memory at a time.  Also, in order to get maximum performance on iOS devices, we have to encode the audio in Apple's native AIFF wrapper, using the IMA-ADPCM codec within it, since iOS devices decode that natively.  MP3 is also supported, but playback is much slower.

Ultimately, audio is a giant pain to deal with if you want your HTML5 application to run on iOS.  It slows down what is otherwise a very well-optimized implementation of HTML5.

The End

And that wraps up the series about our first foray into HTML5 development.  There are a lot of powerful things here, but also a lot of pitfalls, and a lot more platform-specific issues to work out than one might expect.

Still, there will be plenty of opportunities to use these technologies in future projects.

Saturday, December 8, 2012

Snowfall and Child's Play

One of the things we did back when we first released Snowfall was a charity drive, giving half the sales proceeds to Child's Play.  That worked out pretty awesome, and as it's that time of year again we're looking to do it again!

So, from now until the 14th, any purchases of Snowfall will have 50% of their revenue donated to Child's Play!

Friday, December 7, 2012

A Simple 3D Renderer in HTML5, Part 3

Architecting the Source Code

The next major issue to tackle was a basic architecture for the code.  Javascript is pretty liberal with global values and just running functions in place, as well as not caring whether things exist until the particular piece of code is actually executed.

http://www.wooga.com/2012/06/woogas-html5-adventure/

We spent some time reading through this excellent postmortem, as well as many of the links it provides.  Actually looking at the source code for the game provided some interesting insights for the code architecture.  The big one was to create a single global variable that would behave essentially like a namespace, though in reality is just holds a bunch of function pointers.  An entire class file would be encased in the following code:

( function()
{
    // All class code
} () /* Not only are we defining the function, but we're immediately executing it */
);


So when we actually get down to it, we are able to create individual files for each class in our code.  Each class is encapsulated in a function that's immediately run, so it effectively isolates all the local information about the class.  At the end of the function, the main class function is assigned to an appropriate member of the global namespace variable so it can be accessed anywhere.

For inheritance purposes, we still need to include the class files in a specific order (super classes before those that inherit from them).  When the class's prototype is assigned to a new instance of its superclass, that superclass function is executed immediately.  If it doesn't exist yet, the assignment won't work.

In this first go-around with Javascript classes, we ended up making all class members and functions public.  Javascript classes and inheritance are haphazard at best, and they are only able to represent public and private class members, not protected.  This made the code easier to read in many cases, but it also led to shortcutting some functionality since there was direct access to normally private or protected member variables.

A lot of information about object oriented programming in Javascript can be found here:

http://phrogz.net/js/classes/OOPinJS2.html

Later on, well after the completion of this project, we also stumbled upon this article:

http://msdn.microsoft.com/en-us/magazine/ff852808.aspx

The Game Loop and Performance

Back in the actual game, we looked at ways of creating a proper game loop.  There are a couple standard ways of doing this:

setTimeout()

This simply runs the requested function after the specified number of milliseconds have passed.  So for a game loop, you would write the loop function, and then as the last command, call setTimeout() with the loop function to run again.

setInterval()

This runs the requested function repeatedly, separated by the specified time interval in milliseconds.  This saves the trouble of needing to call the loop function again at the end, as the Javascript engine will do that itself.

We also ran across an updated way to handle the game loop, which we ended up using in the end.

http://paulirish.com/2011/requestanimationframe-for-smart-animating/

This is similar to setTimeout(), but it's more optimized for browsers that support it, especially mobile browsers.  If the browser doesn't support it, it falls back on setTimeout().

One big issue we had to contend with - and that we never fully solved - is that even with the best of intentions and optimizations in our code, we're still at the mercy of the particular Javascript engine for frame updates.  Sending off any of the timing functions allows for a good chance of them running again at the desired time, but not necessarily.  Chrome and iOS Safari run quite nicely, but Firefox tends to hitch periodically, especially if you have lots of other tabs open.  We do our best to limit the maximum frame delta, but this can still cause problems later (check out the upcoming audio post).

We do use one big trick to try to squeeze more performance out of the browsers that support it:

http://developers.facebook.com/html5/blog/post/2012/04/17/making-a-speedy-html5-game/

Specifically, wrap the overall HTML document object hierarchy with a 3D CSS3 transformation that does nothing (like scale3d: 1, 1, 1).  This will request that some browsers (specifically mobile ones) attempt to use their graphics chip to speed up rendering.

Coming up, JSLint, mobile device accelerometer support, and audio.

Aquarium Live Wallpaper v3.1

  - New Feature: Daydream support on 4.2+ devices

Again, primarily a maintenance release.  As promised, Daydream support is included and works well as a nightstand decoration.  :)

(Google Play Link)

Thunderstorm Live Wallpaper v2.15

  -New Feature: Daydream support on 4.2+ devices

This is primarily a maintenance update that also adds Daydream support.  Enjoy!

(Google Play Link)

Thursday, December 6, 2012

Prismatic Live Wallpaper v1.25

  - New Feature: Random theme!

This updates adds a new feature requested by a user -- the ability to have the theme change randomly.  This will select a new theme (at random) once per hour, with the theme changing when the wallpaper becomes active after having been off-screen.

(Google Play Link)

Monday, December 3, 2012

Clock Tower Live Wallpaper v1.15

  - New Feature: Time of day shifting!
  - New Feature: Disable the central axel

Several folks have asked for the ability to disable the central axel piece that turns the hands, and with this update they're free to do just that.  Head to the settings screen and remove the obstruction!

In addition, this update also supports having the light color and intensity shift based on the current time of day.  This looks quite good in my opinion and fits in very well with the overall tone of the scene.  :)

(Google Play Link)

Thursday, November 29, 2012

A Simple 3D Renderer in HTML5, Part 2

Continuing from where we left off last time, we took some time early on to research existing (free) HTML5 3D rendering engines.  After going over that, we'll take a more in-depth look at our own rendering tech.

Researching Existing Engines

We looked at a number of pre-built Javascript frameworks, but none of them quite did what we needed.  There are a number of matrix libraries out there, though they're either slow (Sylvester http://sylvester.jcoglan.com/) or buried within a more generalized scientific math library (Numeric Javascript http://www.numericjs.com/).  Writing our own library proved much faster.

We also spent some time researching existing HTML5 3D renders, which again, did not do everything we needed.

http://sixrevisions.com/web-development/how-to-create-an-html5-3d-engine/

This is nice and fast, but it uses a lot of assumptions, like a fixed camera angle.

http://www.netmagazine.com/tutorials/build-your-own-html5-3d-engine

This was probably one of the most enlightening articles, both for 3D design and general Javascript class design.  Again, the camera is fixed.  It also uses focal length for its rasterization, whereas our engine would prefer to rely on field of view.  It was easier for us not to worry about converting between the two.

Most of the actual HTML5 3D engines are done in WebGL, which is unfortunately not supported in many places, especially Android web browsers.

Rendering Specifics
Screen from the final game

Back in the 3D renderer, as mentioned the previous post, we did our 2D sprites as HTML elements that we moved and scaled around the screen.  This was largely done because attempting to draw the images directly onto the HTML5 canvas was even slower, especially on Android browsers.  That being said, it's still expensive to manipulate DOM objects - both getting and setting properties on them - so we decided to keep track of all the sprites' values in Javascript variables and only modify the actual DOM object if the values changed.  This helped a lot with speed.

Another issue we ran into was handling objects that move and scale beyond the bounds of our screen.  Depending on the particular browser, this could cause the entire screen to shift (especially when trying to accommodate negative values), or to simply have parts of the sprite draw off to the side when it should be clipped.  After running through a number of solutions, including provide a masking HTML element so we could just hide the overflow, we eventually stumbled on the idea (via random Internet forums) of having the sprites be composed of two elements: an enclosing DIV element and the actual IMG element.  We could then move the DIV to the extents of the screen, and if the sprite needed to go further, we could alter the IMG's margins, which would contain its effects inside the DIV and also hide the overflow (with the CSS overflow: hidden property).

For the HTML5 canvas itself that we used for 3D rendering, we confined our actual rendering to flat polygons.  The canvas allows for drawing arbitrary paths along a set of points, and then either rendering just the path itself, or filling in the enclosed region.  This gave us the flexibility to draw a bunch of arbitrary shapes for the road, but limited us in drawing actual 3D objects, because we did not build in any z-sorting.

Coming up next, architecting the source code and dealing with the game loop and performance.

Tuesday, November 27, 2012

A Simple 3D Renderer in HTML5

We mentioned this a couple months back, and now we're finally getting around to it.  Over the next few weeks, we'll be posting parts of a postmortem we wrote for our first HTML5 project.  We've done a couple HTML5 projects since that have allowed us to refine our techniques, but this is still an interesting look back at the research and development process.

HTML5 holds a lot of promise as a "write-once, run-everywhere" standard.  The trick then becomes to get it running decently.  And we tackled one of the harder problems: a real time 3D racing game.  We simplified it a great deal so that it behaves more like Rad Racer from the original NES days, but even still, there were a lot of challenges.  Here's the first one.

Rendering Technologies

Note: The screenshot is an early (thought not the earliest) test of our canvas/sprite rendering.

In order to accomplish the 3D environment, we looked at three methods: HTML5 Canvas, SVG, and CSS3.

SVG seemed like the immediate obvious choice.  It would automatically give us nice vector graphics based on a known standard, so we could design art in Inkscape and import it pretty much verbatim into the game.  After some basic experimentation, we found two major flaws: SVG isn't supported on every browser (Android versions 2.3.3 and below are notable in that regard), and when it is supported, it's often comparatively slow to update.

Our next idea was to go to the HTML5 Canvas.  We could do some relatively cheap math to fake a 3D background, especially since the initial concept of the game had players looking from directly behind the car.  This worked well enough, but Android (at least versions before 4.0) tended to be slow to update/refresh.

We looked at a number of benchmarks for the canvas as well.  This proved a very good article about the state of things:

http://www.codefessions.com/2012/03/what-is-fastest-mobile-browser-html5.html

Microsoft also has a pretty nifty performance test:

http://ie.microsoft.com/testdrive/Performance/FishIETank/

CSS3 seemed to be the best bet.  Its transition animations are all nicely accelerated in browsers, delivering a very good framerate.  The trouble, though, is that all the animations are fire-and-forget.  For things like games where player actions will interrupt movement, we couldn't find a good way to make CSS3 behave properly within the limited time we had to research and pick a technology.

In the end, we ended up with a hybrid of HTML5 Canvas and DOM objects that we mostly manipulate through normal CSS.  We wrote a basic 3D renderer and rasterizer for the HTML5 Canvas that would take care of drawing the road, and we treated all the game objects as 2D sprites, which were actually HTML image objects that we moved around and scaled as needed.  This gave us a reasonable framerate on higher-end Android devices, and of course iOS devices, where HTML5 is well-supported (except for audio, which we'll touch on in an upcoming post).

We pulled most of the guts of the 3D renderer from our OpenGL renderer that we use for Live Wallpapers.  This gave us the flexibility to manipulate the camera without having to worry about faking any math, plus gave us a pipeline to not only do the 3D road on the HTML5 Canvas, but also figure out how to place and scale the 2D sprites.  We did have to write a custom matrix class for Javascript, and we had to write a custom rasterizer to figure out how to actually draw points in the 2D space of the canvas/browser window.

Up next, researching existing HTML5 3D engines.

Monday, November 26, 2012

Prismatic Live Wallpaper v1.2

  - New Feature: Daydream support on Android 4.2+
  - New Feature: Simulated scrolling on some devices

Again, primarily a maintenance update that brings some nice side effects along with it.  We had one report about custom images not working, this build brings with it a framework update that may stabilize that some.

Blue Skies Live Wallpaper v2.1

  - New Feature: Daydream support on 4.2+ devices
  - New Feature: Simulated scrolling on some devices
  - Update: "None" wind speed

Again, this is primarily a maintenance release with the associated improvements.  However, you can now select 'none' as your wind speed, as some folks don't like the lateral motion of the clouds.  Enjoy!

Galactic Core Live Wallpaper v2.3

  - New Feature: Daydream support on 4.2+ devices
  - New Feature: Simulated scrolling on some devices
  - Update: Much better accelerometer behavior

This started out as a maintenance update, but turned out to actually be a pretty nice one.  In addition to getting Daydream support and simulated scrolling by virtue of being ported to our most recent framework, this version drastically improves the behavior of the orientation camera.

Previously we were trying to get away with just using the orientation sensor for this, as it's cheaper, but honestly it never worked all that well.  Starting with this version we're more properly using the accelerometer, and as a result it feels much more correct.

Opaque Daydreams and Live Wallpapers

As Jeremy mentioned, Daydream support for devices running Android 4.2+ is starting to roll out to select Live Wallpapers. We're starting out slowly, but the intent is to eventually have pretty much all of our wallpapers (including the free versions!) work as a Daydream once any initial issues are sorted out.

Speaking of implementation issues, there was a subtle one that we caught internally which I haven't seen discussed elsewhere: if your DreamService uses a full-screen SurfaceView (just about anything OpenGL-based), Android will see its window as transparent. Because of that, the application underneath the Daydream is never paused and the two will compete for resources. That's especially problematic if both are using reasonably complex OpenGL scenes (a Daydream over a view of the desktop/lock screen with a view of a Live Wallpaper, for example).

One way to work around the problem is to launch an Activity from the Daydream service. New Activities, even using a SurfaceView, will generally pause what's underneath them unless using a translucent style. While it did pause the wallpaper below, the transition between the Daydream and the Activity was noticeable and the whole thing felt a bit fragile to use. So that approach was quickly discarded.

After browsing the Android SDK source for a while and comparing application window properties in Hierarchy Viewer, the difference between Daydreams that did properly pause apps (no SurfaceView) and ones that didn't (contained a vanilla SurfaceView) came down to a single private flag that signals a window to report how much (if any) of it is transparent. The flag is set in an unavoidable call to requestTransparentRegion() that is made by a SurfaceView as soon as it's added to the view hierarchy.

After some trial and error, our shipping solution is to create a custom RelativeLayout container for the SurfaceView that overrides requestTransparentRegion(). It's an empty method in our version, which effectively blocks the request to gather the transparent region from making its way up the view hierarchy. The window is now totally opaque to Android, but that opens up a new problem: SurfaceViews are added underneath the current window by default, in case you want to draw standard UI controls above them. In other words, the SurfaceView is totally hidden by the blank DreamService window! To get around that, call SurfaceView.setZOrderOnTop( true ).

The end result is a DreamService window that displays your SurfaceView scene and pauses whatever is below it. Optional support for transparency can be easily added, if ever needed.

A minor downside is that I'm pretty sure the above-mentioned solid blank rectangle is still being drawn every frame below the SurfaceView. I haven't confirmed this yet with dumpsys, but because the contents of the rectangle never changes, it should never invalidate and so hopefully end up in a hardware overlay (fast) rather than drawing into a frame buffer (slower). Either way, it's certainly faster than drawing another complicated OpenGL scene below it, and I haven't noticed an actual real-world hit to performance.

I did try an approach that overrode the container's gatherTransparentRegion() method to always return true (opaque) and a 0x0 transparent region. Despite seeming like the Right Way to do this with public APIs, it outright failed to pause the application below the DreamService. It seems that even if the transparent region is reported to not exist, just the presence of the request flag disqualifies DreamService's window from being opaque to the view hierarchy. In the end, what we came up with gives a nearly-identical end result and has so far been extremely reliable in practice.

Sunday, November 25, 2012

Clock Tower Live Wallpaper v1.1

  - New Feature: Daydream support on 4.2+ devices
  - Update: New clock face: Blue Star

The primary goal of this update is to integrate our new Daydream support, as a clock seemed like a very appropriate use of the feature!  Assuming things go well here we'll be looking to propagate Daydreams out to our other products as well.  :)

In addition, this update includes a new clock face!  This one uses Latin numbers, so as to grant an alternative to the whole roman numerals controversy. :P

Halloween Live Wallpaper v1.55

  - New Feature: Daydream support on 4.2+ devices!
  - Bug Fix: Color picker crash on some devices

I've been putting off a few updates waiting for us to get fully working Daydream support in, and now that it's complete I'll be enabling it on more or less all our products as we issue updates.  Halloween and Clock Tower will be the first, and assuming nothing comes up I'll try to hit a bunch more shortly.

Beyond Daydream support, this update also fixes a crash related to choosing the candle color, which happened only in certain locales.

Thursday, November 15, 2012

Bamboo Forest Live Wallpaper v2.01

  - Update: Light rays now use 'light color' pref
  - Bug Fix: Color picker crash in some locales

This update is primarily to fix a crash -- the same locale-specific one that was affecting Autumn Tree a little while back.  I'd overlooked Bamboo being affected, but it's taken care of now.  In testing it I noticed that the light rays in the background always stay white, so updated them to make use of the current light color.  This makes a touch easier to customize your scene.

Wednesday, November 14, 2012

Aquarium Live Wallpaper v3.05

  - New Feature: Fizzy style bubbler!

Had a user point out a few days ago that their tank has one of those bubblers that produces a ton of little tiny bubbles instead of a small number of big bubbles.  I said we'd look into that, and so here it is!  Screenshot included, though honestly it looks much better in motion than it does here...

Tuesday, November 6, 2012

Java Strings, toLowerCase(), and Locale

I fixed an interesting bug last night, and figured I'd mention it here for anybody who happens to be searching.

Basically, we got a customer service e-mail from a fellow who was having one of our products crash on his Galaxy S2.  I asked him to send over some logs, we went back and forth a few times, and eventually he discovered that if he set his phone to English, the product worked no problem.  That's strange, we don't do anything special for different languages, do we?  As it turns out, we do.

Replicating the bug, I discovered it was in the midst of Mesh.readFromText().  This is a function that reads the text version of our model format -- we have both a working binary and text-based path, since for some problems having a human-readable model format is extremely useful.  Almost everything we use is binary regardless, but in this case we're reading a text formatted model.  The format is simple, and the top of the file looks like so:
TMDL 7
NUMFRAMES 1

TC 4

0:    1.0    1.0
1:    0.0    1.0
2:    0.0    0.0
3:    1.0    0.0

WINDING 2

0:    0    1    3
1:    1    2    3

FRAME 0

VERTEX 4

0:    1.0    1.0    0.0
1:    -1.0    1.0    0.0
2:    -1.0    -1.0    0.0
3:    1.0    -1.0    0.0
Now, what's happening is when it gets to the first set of windings, it tells me I've overrun an array and throws an exception.  After a bunch of experimentation, it turns out that when I have the device set to Turkish, it never recognizes the "winding" key as being hit, so it's still trying to read in texture coordinates.  Except the array is already full of those.  That's weird, why is it missing that key?

The reason why is that I made the file parsing non-case-sensitive, and I did it by sending the current line though toLowerCase() before parsing it.  It's in no way obvious, but toLowerCase() makes decisions based on your current locale, so it's possible for your lower-case version of a string to have accents, hard-spaces instead of soft-spaces or what have you inserted.  I'm still not sure which character does it, but when it was forcing "WINDING" to lower-case, one of those characters ended up different from the ascii "winding".  Thus the key was never recognized.

This was a pretty harsh lesson to learn.  Luckily, it's easy to fix, as you can call toLowerCase with an argument specifying a locale, like so: myString.toLowerCase(Locale.ENGLISH).  That means you can at least count on it being consistent if you're doing something like parsing a file.  This last week or so has had more than one lesson about this.

So, here's the TL;DR take away: If you're using toLowerCase() or a similar operation on a user-visible string, let it default to the current locale.  If you're using it when parsing, tell it which one to use to ensure consistency.

Snowfall Live Wallpaper v2.2

  - New Feature: Influence snow direction by tilting device!
  - Update: Simulated scrolling on some devices

I didn't want to radically change the behavior of the product, as there's a ton of folks using it, but this version adds a fun new feature.  Basically, you can influence the direction that new snowflakes will fall by tilting your device!  This doesn't affect existing flakes currently so it takes a second, though I could look at doing that if folks want it.  :)

Saturday, November 3, 2012

NA Flags v1.81 & EU Flags v1.81

  - Bug Fix:  Issues with custom images

We recently changed out underlying framework to support mipmaps much more generally, and as a result a couple defaults changed.  Unfortunately, we apparently broke custom images, as while they don't support mipmaps properly we still had the texture mode for mipmapping set.  As a result, these were showing up as black on a lot of devices. Sorry about that folks, it's fixed now.

Thursday, November 1, 2012

NA Flags & EU Flags v1.8

  - New Feature: Simulated scrolling on relevent devices

This is primarily a maintenance update that gets a couple of minor fixes in place, and more importantly supports simulated scrolling on Samsung and other devices.

Autumn Tree Live Wallpaper v1.1

  - New Feature: Oak Tree!
  - Bug Fix: Custom color crash in some locales

This should fix an issue some folks were seeing  when trying to customize the light colors -- basically, we updated our pref saving a while back to use String.format when saving color values.  Sounds fine, except that some locales use commas instead of periods to indicate decimal places.  This means when you try to read the values back in, parseFloat can't handle it.  This took a while to realize.

In addition, the oak tree leaves are finally in shippable shape, so you get an additional tree option!

Friday, October 26, 2012

Silhouette Live Wallpaper v2.05

  - New Feature: Windmills silhouette

In response to some user requests, we've got a new silhouette available: Windmills.  This is the more classic style of windmill rather than wind turbines, which are still in there but renamed.  Check out the screenshot!

Monday, October 22, 2012

Clock Tower Live Wallpaper v1.0

(Google Play Link)
(YouTube Link)

This is a project that's been going on, on and off, for months now... and we finally got the light rays looking right!  What we have here is a bit of a Castlevania inspired abstract 3D clock tower, with turning gears and a clock that properly tells time.  You can pick from different types of clock faces and hands, and there's a few other prefs that let you control the intensity of the rays, camera motion, and so on.

The shader that's at work here is actually pretty nice, and it reacts to the silhouette of the foreground geometry quite well.  We're proud of the visuals here, overall, and think other folks will enjoy them as well!

UPDATE: Just uploaded v1.01, which fixes ray occlusion on some devices!

Autumn Tree Live Wallpaper v1.05

  - New Feature: Cherry tree!
  - Bug Fix: Some mismatched leaf colors

The primary addition here is a new tree species, "Cherry" is now available in the list!  Hopefully folks dig it!  In addition, this update takes care of some incorrect leaf colors, so if you pick 'orange' you can be confident you'll get it now!

Wednesday, October 17, 2012

Asteroid Belt Live Wallpaper v2.0

  - Update: Now using OpenGL 2.0
  - Update: Higher poly asteroids
  - Update: Higher res asteroid textures
  - New Feature: Simulated scrolling on some devices

This new version of Asteroid Belt doesn't look dramatically different, but should look better and run faster on more or less every device out there.  In particular the asteroids are much higher poly with sharper textures, and moving the project forward to GL20 has allowed us to render things in a single pass that previously were two passes.  All of that is a visual and performance win.

As a side effect, Asteroid Belt now supports simulated scrolling if you've got a Samsung or other device that doesn't properly send offset messages.  Enjoy!

Saturday, October 13, 2012

Autumn Tree Live Wallpaper v1.0

(Full Google Play Link)
(Free Google Play Link)
(YouTube Link)


Folks have been asking for something fall-themed for quite a while, so over the last couple of months we've been trying to satisfy that.  The result is Autumn Tree, a quite pretty (I think!) attempt at a Macro-style photograph of a tree branches with colorful leaves.

The entire thing is real-time 3D as usual, and as you can see from the images here we're doing a soft-focus style blur on the background layer to get a proper camera feel.  All the leaves are individual and you can swap their colors out, and change the species of tree.  Currently we have Poplar, Maple, and Birch... we'll be adding Cherry and Oak before too long.

We're quite happy with how this one came out overall, there's still a few things to add but it performs well and looks very nice.  Hopefully you folks agree!

Thursday, October 4, 2012

Canabalt HD v1.15

  - Update: Sensor Landscape now supported
  - Update: Exit button on game over screen

This is primarily a small maintenance release, but the addition of Sensor Landscape in particular is pretty nice.  Basically, it'll automatically switch to the appropriate orientation depending on which side you turn your device to.  We hadn't figured out how to enable this in an old-device friendly way before, but ran across the proper solution recently and so wanted to get it in there.

In addition, there's an exit button directly on the game over screen, so you don't need to restart the game to return to the title anymore.

Enjoy!

Monday, October 1, 2012

Bamboo Forest Live Wallpaper v2.0

  - Update: Simulated scrolling on some devices
  - Update: Better performance

This update moves Bamboo Forest forward to OpenGL 2.0, and meaningfully improves framerate in the process.  We adeed visibility culling that noticably speeds things up, particularly in portrait mode.

Everything else should still look and work basically the same, with some stability improvements and such over the old one.

Halloween Live Wallpaper v1.5

  - Update: Simulated scrolling on some devices
  - Update: Higher poly pumpkins and house

The big thing was to get simulated scrolling in place for folks, as we've gotten a lot of questions about that lately.  Beyond that as it's been another year, I went through and rounded out the pumpkins, added more triangles to the house model, and in general smoothed out the visuals to be a bit higher res than before.  Hope folks enjoy!

Wednesday, September 5, 2012

Upcoming...

We've got a few things on deck that haven't quite been vetted yet, but should be showing up before long.  These include stability updates for Asteroid Belt and Bamboo (similar to the City at Night one below), and also a series of posts written as postmortem for an HTML5 based project we did recently.  As soon as that one's officially live we can discuss it.  :)

City at Night Live Wallpaper v1.15

  - Update: Now using OpenGL 2.0
  - New Feature: Simulated scrolling on some devices

This should run a touch faster as well on most devices, as it reduces the number of passes necessary when rendering time of day.  The main reason for this update is simply maintenance however, as we've moved it forward to the current version of our framework, which is generally much more stable than the old one it was using.  Visually, you shouldn't notice much difference, at least that's the intent.  Better stability, better framerate, looks the same.  Sounds good to me!

Wednesday, August 29, 2012

Dynamic Dice v1.05


  - New Feature: Pause/Resume button in app
  - New Feature: "Green Felt" background!
  - Update: More velocity on dice when using 'reroll' button
  - Update: Can now be moved to SD card

This update takes into account a couple feedback items we've received since release, in particular including the ability to pause the simulation.  This means if you need to show somebody your dice roll during a game, you don't have to be careful about tipping them over.  :)

As a bonus, there's a new background that should be right at home in a casino!

Tuesday, August 21, 2012

Dynamic Dice v1.0

(Google Play link)
(Youtube link)

This started out as a discussion, turned into tech development, and eventually became a very pretty and functional application for rolling dice!  Dynamic Dice makes use of Bullet physics to properly simulate up to six simultaneous dice, all of which you can customize and tweak to your heart's content.  It is primarily designed as an application, but it can be run as a live wallpaper as well and add some action to your home screen.

We play D&D regularly, and there's frequently a need to switch up the current set of dice you're using.  The interface is specifically designed to allow quick swapping of dice, so it's easy to get what you need on-hand.  You can simply push a button for a quick re-roll, or take things into your own hands by using your device's accelerometer to control things.  The environmental settings even allow modifying the gravity of the simulation, size of the dice, and more.

There's a few similar products on the market right now, but I'm confident that what we have here is the best looking and quickest to use, and I'm hoping you folks agree.

Friday, August 17, 2012

Thunderstorm Live Wallpaper v2.1

  - New Feature: Simulated scrolling on some devices 
  - Bug Fix: Per-cloud rain freezing when certain prefs change
  - Bug Fix: Cloud flashes use lightning color
  - Update: Better light flashes
 
This update primarily started out as a bug for the the cloud "internal lightning" not using the proper color, then went a little further once I discovered that per-cloud rain broke under some circumstances.  You'll find that the light flash that accompanies a lightning strike generally feels better now, and this update also includes the scrolling fall-back as described below.

Aquarium Live Wallpaper v3.0

  - New Feature: Simulated scrolling on some devices
  - Update: Now using OpenGL 2.0
  - Update: Slightly rounder submarine

There are probably some other minor things mixed in here, but the main purpose of this update was to get Aquarium moved to the current version of our framework.  It should gain a lot of stability improvements, along with the simulated scrolling on appropriate devices and some various performance benefits to boot.

No new artwork in this revision I'm afraid, unless you count rounding out the front of the submarine model.  You can see the propeller better now too.

Friday, August 10, 2012

Gallery Live Wallpaper v1.2

  - Update: Better support for extremely browsing large numbers of files
  - Bug Fix: Crash when displaying image options popup

We got a few crash reports regarding using the thumbnail browser with huge numbers of files, and after some investigation we're pretty confident that issue's licked.  So, if you've got a phone with two or three thousand pictures in a single folder, you should be taken care of now.  :)

This update also includes a fix for the 'image options' popup -- generally this would occur if you removed an image from the list, then immediately double-tapped and removed it again.

Silhouette Live Wallpaper v2.01

  - Bug Fix: Black screen when using TOD on some devices

Sorry about this folks.  We accidentally used an RGB framebuffer instead of RGBA.  Only RGBA is universally supported, so a few devices were showing a black screen when they had time of day enabled.  This version should be better behaved.

Thursday, August 9, 2012

Silhouette Live Wallpaper v2.0

  - Update: Now using OpenGL 2.0
  - New Feature: Different visual themes
  - New Feature: Simulated scrolling on some devices

This started out as a maintenance update to bring Silhouette forward to our current framework, then expanded a notch to add some more, well, silhouettes to it.  As a result we've now got a basic framework in place for adding new foreground elements, and have included a field of windmills and a cityscape to begin with.  Hopefully folks dig them!

We also are including the simulated scrolling that we put in place for Koi Pond earlier, since it doesn't appear to have caused any problems. :)

Saturday, August 4, 2012

Koi Live Wallpaper v1.5

  - Update: Two new backgrounds!
  - Update: Simulated scrolling on some devices

This update also should include some minor bug fixes and improvements, but the main things are the two items up above.  The new backgrounds are courtesy of Kim Lathrop, one is an abstract and one is a beautiful backdrop of heartstones on sand.  :)

The simulated scrolling is something we're putting in place as a general case, so should be available in most of our products as they get updated going forward.  Basically, a lot of companies disable wallpaper scrolling on their home screens, and we get a lot of complaints about this.  It's not our fault but that's not how people read it.

So, we think we've worked out a reasonable way to detect this behavior, and are simulating the camera movement based on drag events.  It's not perfect but should mean you get to see the entire backdrop and it generally behaves sensibly in testing.  Hopefully folks consider it an improvement!

Friday, July 27, 2012

Jelly Belly!

This just hit the market a little while ago -- we worked with Jelly Belly to make a fun Jelly Bean themed wallpaper, take a look! 

Friday, July 13, 2012

Gallery Live Wallpaper v1.15

  - New Feature: "Image Options" popup
  - Bug fix: Rare memory crash
  - Update: Two new transitions: Circle in/out
  - Update: Selection border is now white

This update's primary addition is the new "Image Options" popup window.  You can enable this in the prefs, and it allows you to double-tap anywhere on your home screen to activate the feature.  Doing so gives you a simple popup that allows you to visit the image's associated page (Reddit comments thread, or Flickr page).  Alternatively, you can strike that image from the list so you don't have to see it again.

In addition we believe we fixed a (fairly rare) memory crash related to images of a particular size range.  An int was truncating instead of rounding, so it was possible for some images to "thread the needle" and stay too large to load properly.  This should be fixed now.

Finally, a couple cosmetic additions -- two more transition effects are now in the list, and the selection border when editing the "device" available images is now white.  It's classier that way.

Flags Live Wallpaper v1.75 updates

Just pushed a new round of updates that take Flags of Europe, Flags of Oceania, and Flags of South America all up to v1.75.  These are mostly maintenance releases but do fix a couple visible issues as well.

  - Update: Now using Holo UI in settings screen
  - Update: Fixed flagpole color/shading

In addition we fixed the German flag display in portrait and it's inheriting some general optimizations and improvements we've made to the framework over time.

Friday, July 6, 2012

NA Flags Live Wallpaper v1.75

  - Update: Now using Holo UI where available
  - Update: Support for Jelly Bean wallpaper setting

This is primarily a maintenance release to fix a couple minor behavior problems and to enable the better looking settings screen.  In addition, our default "How To" popup (the one that explains how to apply a wallpaper when you push the Market "open" button) now supports Jelly Bean's new ability to directly launch the Wallpaper Preview window.  That should make the general user experience a notch better upon purchase.

Issues with Android 2.2

I'm pushing updates to a couple different products today (Friendly Bugs and Prismatic) to fix an issue with Android 2.2 that appeared in the last update.  Here's what happened.

On June 28th, we switched basically all of our products away from using proguard.cfg, and towards using the newer style of proguard-android.txt that's provided by the SDK.  I spot checked things on a few devices and everything seemed fine.

Well, it wasn't fine.  Basically, the default proguard configuration doesn't preserve any NDK hooks that might be in place.  It's necessary to use the NDK to use OpenGL 2.0 on Android 2.1 or 2.2, which means that on those devices you ended up with a black screen.  At this point almost every device we have has ended up being updated to 2.3.3, so none of the devices I checked at the time were running an Android version that old.  This was neglectful on my part, I should've made a point of checking an NDK-using device.

Thankfully, we noticed this fairly quickly, so really only a couple of products were affected, and a lesson was learned regarding treating Proguard with respect.

Lines Live Wallpaper v1.06

  - Bug Fix: Lines ending too soon on far left (some devices)
  - Update: Now using Holo UI when available

This is primarily a bug-fix release, as we discovered that on very wide devices the scene ended a little too early on the far left side.  That's been fixed, in addition a few other small updates were put into place.

Monday, July 2, 2012

Friendly Bugs Live Wallpaper v2.1

  - Bug Fix: Z-Buffer clipping when butterflies overlap
  - Update: Now using Holo style UI on ICS devices

We've had this one on the list for a while and just now got to it.  It wasn't a grievous problem -- when a butterfly flew above another butterfly, sometimes you'd see part of its wing disappear.  Well, that's taken care of now, sorry for the inconvenience folks!

Thursday, June 28, 2012

Prismatic Live Wallpaper v1.15

  - Update: Now using Holo style UI on ICS devices
  - Update: New Backgrounds: White Dwarf, Neon

This is primarily a maintenance update with a few extras -- folks on ICS devices get the prettier UI skin on the settings screen now, for one thing.  For another there's a couple nice new background images, check the list for White Dwarf and Neon Lines!

Wednesday, June 27, 2012

Gallery Live Wallpaper v1.1

  - New Feature: Categories in image browser
  - New Feature: Select All/None in image browser
  - Update: Now using Holo theme on ICS devices
  - Update: Better Market "open" button handling

This update is primarily driven by customer feedback, as the #1 item was definitely being able to view your images by category/folder, and being able to select all of them easily.  To that end we now determine a list of categories, have you select one (or all) then allow you to individually modify the list or select all/none within that category.  It works well in my testing so I'm hoping everybody's getting what they were looking for.  :)

In addition, we've moved the project forward to SDK 14, so it'll use the Holo style UI on supported devices now.

Also, just put up a YouTube video, if you're interested!

Sunday, June 24, 2012

Lightscape Live Wallpaper v1.1

  - Update: Name change to Lightscape
  - Update: Additional pattern images
  - Update: Now using ICS SDK/Holo theme

The product formerly known as Wavescape has been renamed, due to a trademark collision.  The new title is Lightscape, but aside from that it's still the same shifting patterns of light rays and general coolness.  :)

As a bonus, anybody with an ICS device gets the Holo theme in their settings now!

Thursday, June 21, 2012

Replying to Play Comments

This is pretty awesome.  At long last you can now reply to comments on the Google Play listings!  This doesn't sound like much, but it's not uncommon to see people mention bugs or other issues in the comments, without actually sending you an e-mail.  This makes it effectively impossible to follow up, ask questions, inform them their issues is fixed, etc.  Especially if it's a recently posted product, this is kind of nerve wracking.

No more!  If you log into your Play Publisher account, and head to the comments section on a product listing, you now see a "reply" prompt that does exactly what it says.  The reply is displayed on the listing inside Play, and in addition the user receives a notice that a reply has been posted.

We just tested this, and the user does indeed receive an e-mail.  The text of the reply isn't contained, rather they receive an e-mail from "nobody" (oddly enough) notifying them that one of their comments was replied to by the developer.  A link is provided underneath that.  Clicking the link takes them to their comment and its reply (which worked).  I'm happy to see the message also encourages them to use e-mail for reporting further problems.

Here's a pic of what the user sees:

Tuesday, June 19, 2012

Gallery Live Wallpaper v1.0

(Google Play full version link)
(Google Play free version link)

(YouTube)

Gallery Live Wallpaper allows you to display your favorite images on your home screen!  You can select from any image on your device, and can customize which transitions and camera behavior you get, how fast the images cycle, and plenty more!

If you don't want to take your own pictures, then you can point it at Reddit or Flickr and it'll download images in the background periodically, so you'll always have something new.  You can provide your own subreddit selections or Flickr search terms to customize what kind of results you get, and can set how frequently checks happen and how much storage will be used.

Additionally, unlike the similar products I've seen on the market,  Gallery is fully OpenGL accelerated, so slow pans and zooms don't have any single-pixel jumps going on that mess up the smooth motion.  It also performs very well, like a slideshow should.

I'm really happy with how this project turned out.  The initial idea was to make something that could emulate the Ken Burns Effect, and it went way further than that over time.  :)

Making this one was something of an educational experience, simply because while most of our projects are using pre-made art, this one doesn't.  It's completely reliant on whatever it is the user provides, so we ran into a few different hurdles making sure there were no visible limitations:
  • Modern camera phones take images much bigger than is necessary for the screen, so you have to get their size and reduce it appropriately before you try to do any loading.  Otherwise you'll end up allocating 30 meg to read in a 8 megapixel image, to display on a 1 megapixel screen.
  • Reducing at load time generally means reducing by an integer divisor - half size, quarter size, etc.  You don't get a lot of fine control there.
  • Despite that, careful not to reduce it too far, otherwise the quality on-screen will suffer.
  • Non-power-of-two textures work, but using odd numbers crashes some devices' OpenGL drivers.  Make sure you resize to a even number in both dimensions.  This means you may end up resizing it twice, given the integer resizing issue.
  • Some images have EXIF tags to rotate/mirror them.  This is really annoying to deal with, but otherwise you'll end up with a lot of sideways images.

Saturday, June 9, 2012

Canabalt HD for Playbook

It took a while to get through the process, but Canabalt HD is now available for purchase on Blackberry App World!  This is taking advantage of RIM's Dalvik compatibility, and runs extremely well on the Playbook.  I'm thrilled to finally have this out there.  :)

Friday, June 8, 2012

Obscure Market Errors

We spent most of an afternoon trying to figure out a problem we were having with Android in-app purchases.  We'd try to buy something, it would fail, and in the log output we'd get IAB_PERMISSION_ERROR, something that you'll find almost no hits on if you do a Google search.

After a lot of pounding our heads on the wall, we figured out the source of the problem, at least in our case -- the item we were trying to buy existed but hadn't yet been published.  Sounds obvious I know, but it wasn't our Market account we were testing against so we didn't have any way to double-check it ourselves, and were told everything was good to go.

If you got here because you had this error happen and this is the only link in English, I suggest that you confirm the in-app product has actually been published, not just saved.  We also did some tests trying to access an in-app product from an account that wasn't in the test list, you'll see the same error in that case.

Flags of Europe Live Wallpaper v1.7

  - New Feature: Andorra, Kosovo flags

This isn't a big update, just a content addition of a couple countries that have been requested over time.  Hope folks enjoy!

Sunday, June 3, 2012

Compatibility Testing on Android

I was just reading this TechCrunch article and thought I'd write a quick explanation of the philosophy we've generally tried to take here, which is somewhat different than any of the ones listed.  Our work is almost exclusively in 3D rendering (with minimal UI, even) and has informed the way we've handled things as a result.

Basically, we've taken the tack that there are two directions to check: Hardware and Drivers.  This means we want representatives of all the OS versions, and representatives of all the hardware chipsets.  On the OS side that's 2.1, 2.2, 2.3.3, 3.2, and 4.0.  On the hardware side that's Qualcomm Adreno, nVidia Tegra, PowerVR, and Samsung Mali.

This means minimum we end up with around 20 devices, in order to get each OS version represented with each chipset.  In practice it's not quite so neat and tidy -- there aren't any 2.1 or 2.2 Tegra devices, for example.  When in doubt, we get variations of hardware before variations of OS, as experience thus far is that while the OS may change the drivers appear to stay the same.

Generally, if we're doing a major update of some kind we'll make a point of running it on a variety of these devices and make sure everything behaves correctly.  For minor updates where nothing risky has changed, we'll generally run through it on the devices on the desk of the individual developer.  Generally these represent the hardware axis of the grid, given the aforementioned driver point.

Sunday, May 27, 2012

Friendly Bugs Live Wallpaper v2.05

  - Bug Fix: Problem with "Frosted Glass" on some devices
  - Update: Ladybugs dance when touched!
  - Update: Resting butterflies fly away when touched!

This update fixes an issue with the "Frosted Glass" background -- it wasn't a power of two, and non-power-of-two ETC1 textures don't work on all devices.  Sorry, that slipped through the cracks.  :/

In addition to this fix, we've added in a couple quick features.  Laldybugs and butterflies now both react to touch!  Butterflies at rest will fly away when touched, and ladybugs will do a little dance!  Enjoy!

Tuesday, May 22, 2012

Canabalt HD v1.1

  - New Feature: Options screen with volume, vibration, etc controls
  - New Feature: You can totally set the music as a ringtone!
  - Update:  About button has been moved to the options screen
  - Update:  HD player character now has white socks (by popular demand!)
  - Bug Fix: Collision volume for leg has been tweaked a bit to fit the graphic closer
  - Bug Fix: Rooftop fences draw in order better in SD mode

Good day everyone!  Took a bit longer than originally planned, but as of now Canabalt HD v1.1 is up on Google Play.  This primarily is there to introduce independent sliders for music and sound effects volume, a much requested feature judging by our contact e-mail.

In addition we've added a few fun extras.  Notably, you can set the three music tracks as your ringtone if you'd like!  Plus, since several folks mentioned it, the HD player model now has proper white socks.  Enjoy!

Sunday, May 13, 2012

Friendly Bugs Live Wallpaper v2.0

  - Update: Now using OpenGL 2.0 for rendering
  - Update: Two new backgrounds: Frosted Glass and Dark Wood
  - Update: Higher res backgrounds
  - Update: Thumbnails in settings screen

This is a (primarily) technical update that should give Friendly Bugs better performance on pretty much all devices.  In addition we're also including a couple of new standard backgrounds, and have upped the resolution of some of the existing ones.  You also get a thumbnail swatch of the current background on the settings screen.  :)

Tuesday, May 8, 2012

Flags of Oceania Live Wallpaper v1.7

  - Update: Four new flags!  Philippines, Torres Strait, Tiwi Islands, Norfolk Islands

This update is primarily to get some new flags in place, all user requests over the last few weeks.  In addition, this update enables support for more native platforms - x86, arm7, and MIPS.  Shouldn't actually make much difference in practice, but it does allow Play's filtering to work properly.

Monday, May 7, 2012

Galactic Core Live Wallpaper v2.25

  - Update: Can now disable touch response entirely
  - Update: Better color swatches in settings

This isn't a big update, but fulfills a user request to completely disable the camera's motion based on touch.  In addition, we've improved our color swatches on the settings screen so they should look consistent with all the other stock preferences panels now... which makes the whole thing look a lot better.

Friday, April 13, 2012

Thunderstorm Live Wallpaper v2.0

  - New Feature: Change colors based on time of day
  - Update: Now using OpenGL 2.0

This is a major update from our perspective, but should look more or less the same to you folks.  Basically, we ported Thunderstorm forward to a newer version of our framework, which should make it generally better behaved and give you snapper home screen response besides.  That's not bad to start with, really.

In addition, we've hooked up the ability to have the colors change based on the current time of day, similar to several of our other products.  Like those, we use coarse network location to calculate an accurate sunrise/sunset time.  You can click the "Time of Day Preferences" selection to edit the colors for the available times to make it look however you see fit.

The only oddity about this is if you're using minimalist mode, as you'll probably want to tone the colors down if you've got that enabled.  That's the general case with the light colors though, so hopefully we'll be forgiven for that one.

Along these same lines, we're also working on an update for Friendly Bugs that should give some similar benefits.  Give it a few days and we'll have that one live too.  :)

Wednesday, April 11, 2012

Space Battle Live Wallpaper v1.16

  - Bug Fix: Occasional crash when enemy is destroyed

Nothing big here, just a bit of maintenance to fix a crash bug.  Sorry for the inconvenience folks!

Prismatic Live Wallpaper v1.1

  - New Backgrounds: Tie Died Trees, Camoflage!
  - New Feature: Thumbnail preview on background selection
  - Update: Misc performance and stability improvements

It's been a while since Prismatic got updated, but this one one should give you some noticable speed improvements on the right devices.  In particular, we're selectively clearing the buffer when rendering, which on a Tegra device makes a lot of difference.  This update also inherits a lot of general stability fixes we've made over the last few months, so all told users should have a better experience.

In addition, you'll find a couple new background images in the list, and some other small usability improvements.  Enjoy!

Tuesday, April 10, 2012

Koi Live Wallpaper v1.4

  - New Feature: More backgrounds!  Fountain and Pompeii!
  - New Feature: Thumbnail on background selection pref

This update features two new gorgeous background images, both at super high resolution.  These were painted by Mr. Kim Lathrop specifically for this project, and they turned out fantastic.  In addition, you'll see a preview thumbnail on the settings screen for your currently selected background -- we'll hopefully start getting this into more products over time as we do updates.

Speaking of, look for a Prismatic update tomorrow!

Thursday, April 5, 2012

Canabalt HD v1.07

  - Bug Fix: Error when submitting high scores

This was a pretty bad one to miss, and is bluntly rather embarassing.  Sorry for all the updates folks, we should be settling back to a normal schedule shortly.

Easter Meadows Live Wallpaper v1.1

  - New Feature: Time of day!
  - Update: Misc stability improvements

It's been too long since we updated this one, but this new version has a checkbox that will get you lighting that changes based on your time of day!  In addition, it's using an updated version of our framework that should have a number of performance and stability improvements in place, so hopefully everyone has a smoother experience overall.  :)

Tuesday, April 3, 2012

Space Battle Live Wallpaper v1.15

  - New Weapon: Cluster Bomb!
  - New Feature: Score display when enemies killed!
  - New Feature: Disable camera scroll
  - Update: Improved settings screen appearance

This is a fun update that adds some new items and features.  In particular, there's the basics of a scoring system in place now -- if we go much further here we'll have to make this an actual playable game.  :P

Version 1.15 also adds a new weapon type in the form of the cluster bomb, which fires a single big shot that splits into eight when it reaches the top of the screen.  In addition, as a few folks requested, you can now disable camera scrolling completely.

Monday, April 2, 2012

Canabalt HD v1.06

  - Bug Fix: Missing hallways
  - Bug Fix: Address authentication when using a pre-existing account

This is just a bug fix update, repairing an unfortunate oversight that occurred when we fixed the impossible hallway that showed up sometimes at the fourth building.  Sorry folks!

Thursday, March 29, 2012

Koi Live Wallpaper v1.35

  - New Feature: Fish startle when touched!
  - Update: Improved performance on Tegra devices

This updates gives us a couple goodies, in particular you can now interact with the fish a notch more than previously.  Tapping on one will now startle it and cause it to swim quickly away for a second or so.

In addition, we have some logic in place now that will optionally clear buffers based on whether or not the current device prefers it.  This means some devices got a pretty substantial improvement -- in particular Tegra chipsets should be a notch smoother than before.

Canabalt HD v1.05

  - New Feature: Localization to french, italian, german, spanish
  - Update: Re-using an existing account better supported
  - Bug Fix: Occasional crash during building generation
  - Bug Fix: Difficult window at building 4

The big thing here is getting localization in place for a few major european languages, and fixing some minor crash issues at the same time.  People seem to be really digging the game so far, so look for more updates in the future.  :)

Please let us know if anything goes amiss!  Look for these fixes on Kindle and Nook devices in the next few days.

Sunday, March 25, 2012

Lines Live Wallpaper v1.0

( Google Play link )

This feels like it needs a cleverer name, but I've been at a loss so am going with the simple one for now.  :)

Lines is an abstract live wallpaper with a collection of lines streaking across your screen.  They move in/out of the scene as you slide the camera, and respond to touch with via vibration and color changes.  The nice thing about this one it it's graphically simple enough to be extremely performant, even on fill-rate starved devices like a Galaxy Nexus.


If you're in the mood for something abstract, give it a shot!

Thursday, March 22, 2012

Canabalt HD on Nook

Took a while to show up in the actual store, but as of this morning Canabalt HD is now available on Nook devices as well!  Click here if you've got a Nook Color or Nook Tablet.  :)

Wednesday, March 21, 2012

Android Sound Playback at 60Hz

Sound effect playback was added to Canabalt HD pretty late in the development cycle. True to form for any late-coming feature, it didn't arrive without one or two terrifying complications. Jeremy already covered one the issues we faced in his post about sound file compatibility. It also turned out that playing the sound effects themselves caused pretty significant hitches in the game. That's the other problem we had to tackle and is what this post is about.

To set the stage, Canabalt is a game that tries to run at sixty updates, or frames, per second (60Hz). That's the fastest rate available on most displays, so it's a common target for driving, shooting, sports, or reflex games like Canabalt. A 60Hz update rate gives us 16.666ms per frame (60 / 1 second = 0.01666s = 16.666ms) to do everything related to running the game: gather input, simulate physics, prepare the scene for rendering, a bunch of other things, and play sounds.

Not long after adding sound effect playback via the SoundPool class, we started to notice the game running kind of rough. The game would visibly stutter on occasion and miss input events, meaning the main character wouldn't jump when you asked him to. Not fun, and certainly not shippable.

The culprit was the call to SoundPool.play(). Seen here in an image from a bare-bones test application that I wrote while diagnosing this problem, the game thread was spending anywhere from 1-9ms(!) just waiting to start playing back a sound. Not pictured are some instances of sounds taking more than 12ms to start (rare, but it happens). That's not only quite volatile, but also way, way over-budget!

To narrow down what was going on, I tried changing every variable that I could think of, one at a time:

* SoundPool is build on top of AudioTrack, which is the lowest-level sound API available to apps written Java. So, the first thing I tried was using AudioTrack directly. Operating in static mode, any combination of AudioTrack calls that would reliably play sound effects properly netted basically the same delay. Streaming mode clocked in at several hundred milliseconds per fill of the streaming buffer, so that too was out.

* The sound files themselves are decoded to PCM by SoundPool when loaded (AudioTrack expects you to supply it with PCM yourself), so as expected there wasn't any performance difference between using OGG and MP3 files. Other things that turned out to not have any discernible impact: sound file sampling rate, sample bit precision, and sound file length.

* Finally, every device we have here (every major manufacturer, most non-major manufacturers, ARM CPUs, Intel CPUs, every Android version from 2.2 - 4.0) turned in similar performance, with one notable exception. The gaming-centric Sony XPERIA Play never blocked the game for longer than 2ms.

Thiago Rosa has found evidence of the sound system shutting down to save power when nothing is playing. Starting a sound would take a long time because everything would need to start back up. Unfortunately, the suggested solution of constantly playing a muted looping sound didn't alter the numbers I was seeing.

Experimenting with AudioTrack is what lead to our shipping implementation. It seems that starting a static AudioTrack is nearly instant. Stopping a static AudioTrack so that you can tell it to refresh and play its contents again (even if the playback was long completed) is what eats up all of the time. My best guess is that all of the time is being spent idling waiting for something between the deeper parts of Android and the hardware to grant access to the AudioTrack.

We ended up moving audio playback onto a different thread from the game logic. Instead of stalling the game while waiting to play a sound, the game simply (and instantly) adds to a buffer the id of a sound effect it wants to play. Each frame, the buffer is handed over to the sound thread where all of the calls to SoundPool.play() happen.

This basically means that the game is free to run whenever the sound thread is stuck waiting.

In the best-case scenario, single-core devices are able to do work during time that was previously spent waiting for the audio system. Multi-core devices may even have the game and sound threads on separate cores, which means the game would be completely isolated from all of sound effect speed bumps.

The worst-case would be if the audio system is actually working hard and not idling while waiting to start a sound. In that case, there is no time to be gained back on a single-core CPU, but we still do have the benefit of not blocking the game thread for extended periods when several sounds start simultaneously.

The downsides to this approach are increased code complexity and an additional game frame (16ms) of latency between the request for a sound to start and when the sound actually starts.

It does bother me a bit that this was ultimately based on an educated guess, but I can say that threading our sound effect playback did restore the missing responsiveness to the game. I would love to have a conversation with someone who really knows the Android audio system to help get to the bottom of it.

I can't say whether our experience would have been any better if we were able to use the NDK. A brief web search indicates that the OpenSL ES implementation there suffers many of the same limitations as AudioTrack/SoundPool in Java, such as 100ms of latency. It would be an interesting point of research to see if starting and stopping sounds there had the same performance penalty.

A future refinement may be to add a priority value to requests in the sound playback queue. This would be so that important sounds (dialog, impact noises, etc.) aren't delayed by a backlog of unimportant ones (ambient sounds) if SoundPool is really running behind. It's not really an issue for Canabalt, but I can see how it would be handy to have.

Monday, March 19, 2012

Generala v1.6

  - Update: Enabled hardware UI acceleration

I reviewed Generala on the Galaxy Nexus and fixed a few minor issues, but all told was pleased to see it's held up just fine even with all the interface changes that have happened.  To that end I updated the SDK version, enabled hardware acceleration, and a few things like that.  this is primarily a maintenence release.

We're part of Humble Android Bundle #2!

Howdy folks, on the fence about Canabalt HD?  Get it as part of the second Humble Android Bundle, and send a portion of the proceeds to charity to boot!

Thursday, March 15, 2012

Canabalt HD

( Android Market link )

We've mentioned working on a game project a couple times here -- the first one we've done in over a year -- and it's finally ready for prime time!  Canabalt HD is an Android-based update to the seminal platform game originally developed by Adam Atomic.  Look for 3D modelled buildings, characters, and backdrops, with the original gameplay left completely intact!


We've stuck faithfully to the color palette and feel of the original game, and hope any fans will be pleased by the graphics update.  If not, you can switch back to the original artwork seamlessly and return to the original old-school sprite look.  Both run well on any Android device running Android 2.2 or above!


As of right now, Canabalt HD is also available for the Kindle Fire, and I'm expecting to have it green-lit on the Nook store shortly.  In addition, it should work and play fine on a GoogleTV device, and we have support for the XPeria Play gamepad to boot.  Everybody wins!




NCAA Jersey Live Wallpaper

( Android Market link )

Adding another one in the NCAA category, looks like our second project there just went live!  This one displays your favorite NCAA team jersey, customized with whatever name and number you'd like!  If you're a fan, check it out!

Wednesday, March 14, 2012

How to Crash a Galaxy S II via the Date Class

We just ran up against this one in a project that's set to launch any day now: a crash that only happened on Samsung Galaxy S II phones, only when set to the Sydney, Australia time zone, and only when using the DD/MM/YYYY date format.

The culprit was eventually tracked down to be the way we were storing time stamps in our text-based save data. This simplified example of what we were doing will crash the above configuration every time:

final Date source = new Date();
final String serialized = source.toString();
final Date dest = new Date( serialized );


The solution was pretty straightforward once we identified the problem. We now store the milliseconds value from the Date object rather than the formatted display text:

final Date source = new Date();
final String serialized = String.valueOf( source.getTime() );
final Date dest = new Date( Long.parseLong(serialized) );


It's a simpler approach and therefore probably what we should have been using since the start, but that's with the benefit of hindsight. The original approach is totally valid according to the Android documentation and survived months of mixed casual and focused testing. It's a pretty good example of one of the weird problems an application can run into out in the wild that are almost impossible to anticipate.

We were extremely lucky to have a someone testing the application in just the right place and with just the right hardware. He snipped a copy of the system log containing the crash from his phone using alogcat. That led us down the path of being able to locally reproduce the problem and ultimately fix it.

Thursday, March 8, 2012

Are you an NCAA Basketball fan? Check this out!

( Android Market link )

We've been working with the folks over a 2Thumbz on a couple of NCAA based projects, and the first one went live last night!  It's an attractive Sports-Center style treatment of the various school logos, with real-time light rays and a selection of different backgrounds.  It's quite good looking in my opinion and well worth a look if you're a fan!

Tuesday, March 6, 2012

Aquarium Live Wallpaper v1.7

  - Update: New background!
  - Update: Two new fish!

This is a content update adding a new background painting, and a couple new fish!  The background is a very cool undersea city painted by Kim Lathrop!

Enjoy!



Saturday, March 3, 2012

Blue Skies Live Wallpaper v2.05

  - New Feature: Set light color (non time of day)
  - Update: Better color swatch pref appearance

A customer pointed out a little while back that while we said in our upsell text you could set the color of the light, in actuality we only let you do that when messing with the time of day.  This is a fair point, and this update adds that feature.

In addition, previously our custom color swatch preference had font sizes that mismatched when you were running Gingerbread -- I've put in a bit of a special case that should help that.  Please let me know if the preference screen looks like gibberish on anyone's device.