Tuesday, June 25, 2013

Indies: Why Make Contract Games?

On the road from a traditional job in the game industry to full-time independent game development, we have found ourselves in the position of doing contract game development for a period of time. My initial response to the idea of contract development was less than excited. I feared that it was ultimately no more than a change of bosses rather than the life-changing adventure I was looking for. To my surprise contract game development has proven to be closer to independent development than I had expected. Working with the right companies, contract work can offer many of the benefits of independent game development and act as a stepping stone toward full-time work on your own games, while providing some of the benefits of a traditional game development job.

When you order cheese puffs in bulk, you get a developer as a prize.
Why do contract games at all, you might ask. Well, it's simple. Dependable money. The independent game scene is filled with heroic stories of cash-strapped developers mortgaging their houses, maxing out credit cards, subsisting off of cheese puffs and will-power to create their dream game. While these stories make for a great read and sometimes result in an incredible windfall for the developer, they also sound like a terrible way to live and are one-shot solutions to lack of funding. Miss the mark on your first game and all you've got is debt and regret. Our aversion to taking on debt and desire for a 'normal' lifestyle have led us to take a slow and steady approach to making games. Contract games, though they lack the potential windfall of an independent game, offer a source of dependable income like a regular job. Using this we pay ourselves and by keeping our costs down we have been socking away money until we have enough to make a game of our own. With the revenue from each independent game we release we hope to slowly work ourselves off of our dependence on contract work. In this way, contract game development provides us a (relatively) steady income, similar to a traditional game development job, while providing a path toward greater independence.

Sorry Johnny, it wasn't my call.
At the same time that contract development provides revenue it also provides much of the sense of control that I found lacking in a regular game development job. As a mid-level employee at two different game development studios, I often felt like a horse wearing blinders. The extent of my knowledge of the company's direction and my role in it was limited to the task in front of me. With such limited perspective, I've frequently been confused and surprised by company decisions. I've had projects that dragged on far longer than they should have, while others were cancelled before they were given chance. I worked on a game that had its genre changed on a near monthly basis. Reasonable ideas I suggested were rejected for unknown reasons while company heads made bizarre decisions without my input, such as shoving a poorly drawn Jack Sparrow and mini-games into an otherwise coherent mini-golf game. Working in a small studio has greatly clarified the decision process that goes into making a game. With a better understanding of the decision process has come a sense of control and in-turn fulfillment that I never had when working for a large studio. While contract work still has the limitation that parts of the project are dictated by an outside force, having an active voice in the discussion makes it easier to accept even the bizarrest decision. Additionally we've found that different companies and projects offer varying amounts of freedom, and ultimately we always have a choice of whether or not to take a project. 

iPhone Screenshot 1
Entanglement iOS, does no one love you?
Since contract work provides much of the freedom and control that comes with independent development and also provides a secure supply of revenue, it offers an excellent sandbox in which to learn how to build a company. Derek and I started Gopherwood Studios without any previous business experience. This means we've made a LOT of mistakes over the last two years. Mistakes such as promising an expansion to the iOS version of Entanglement that we ultimately couldn't provide, or giving it an art style without reflecting on the target audience for the game (we still get complaints about that). And while we still make mistakes with regularity, we're much better businessmen than we were. At the same time we've had two years to build up a base of technology and knowledge that make each new project easier. While there is something to be said for diving directly into a passion project from the get-go, there is value in taking some time to work the kinks out of a business before taking a significant risk. 

That doesn't mean that you can't take any risks if you take our route, instead contract games provide us with regular chances to take risks within the confines of a project.  Each project provides new challenges and opportunities. We take advantage of each project to try out new ideas and techniques. With each project these experiments helps us to grow as developers and prepare us for future projects.

While my initial concept of being an independent developer didn't include contract game development, I've been pleased to find that it offers many of the benefits and pleasures of independent development while still offering a path toward full independence. If you've got the ability to a more direct route to independent game development, you may find yourself there sooner than us, but for more risk adverse developers contract game development offers a viable route.


I like whitespace.



Friday, January 11, 2013

New Entanglement Maps and Free Trial!

Over the last few months we've been slowly making additions to Entanglement. Some of these have trickled out over time (e.g. saved games), but this week we finally released the flood. These additions include new levels, a free trial so you can check out the new levels before buying them, and a variety of bug fixes and interface improvements.

New Levels

This update adds eight new maps to Entanglement. Putting the total number of maps at twelve! These maps are split between two new expansion sets.

The Classic Mode Expansion offers four new maps that follow the classic Entanglement rule set. The maps look pretty simple, but you'll be surprised how the shape of each map changes your strategy.


The Tranquil Garden Expansion includes four new maps that challenge players to score as many points as possible with a limited number of tiles. Passing through sakura trees will earn you more tiles. This game mode was introduced in the Sakura Grove Expansion, but here we've explored it further with some great results!


We've also added a Combo Pack Expansion for users who want to get all twelve maps for the cheapest price possible.

In addition to the new packs, we've renamed the Sakura Grove Expansion to Expansion Sampler. Though it has a new name, it offers the same three maps with both types of gameplay.

Free Trial

For players who enjoy the game, but want to try the new maps  before they buy them, we've added a FREE one-day trial. When you start the trial you'll have access to all the maps in the game for one day.


The trial can be activated from the in-game market, accessible from the main menu under 'More Maps' or from the in-game menu on the 'Get More' tab under 'Get More Maps'. Once you're in the market just log in and select the 'Try It!' button to start your trial!

If any of these additions sound interesting, try them out here!


Friday, January 04, 2013

Saving Your Entanglement Progress

Earlier today we rolled out a new Entanglement build that includes a few new features. We'll announce the bigger additions next week (or just check out the game to see the new content), but I wanted to go ahead and note one simple addition that I think makes the game experience a bit more fluid: we auto-save your game!

I know this is not revolutionary, but, in addition to the end result, I think the implementation is cool. To accomplish this, we use the Local Storage capability of modern HTML5 browsers to store a player's moves as they are made. If the browser window is closed and opened at a later time, the same set of tiles is loaded and the game replays the stored moves to return the player's progress to its earlier state. This is especially useful for mobile devices, where interrupting a browser session is a commonplace event. Now players are able to play a few tiles at a time and still finish their game without losing their progress if they're interrupted.

The cool part? Replays. By storing a particular game's seed, we are able to re-generate the exact tiles that were used the first time the game was played. Then, the game simply swaps, rotates, and places tiles exactly as they were initially played. Once the list of moves has been replayed, the game is sitting in the exact layout it was when the player left.

Using the same logic the game can replay high score games as well... ...but that's not quite ready yet. Essentially, we do not have all the necessary information from earlier games to be able to generate and replay all of them accurately. However, we did run a replay on Fast Shocking Toucan's 5195, and it's... ...beautiful!


Wednesday, December 19, 2012

GopherwoodStudios.com Transformed!


We have a new website! It's bluer and rounder than our old one. As is our wont, we discussed a bazillion awesome designs that were intriguing, engaging, exciting, and would only take several years to develop... ...so we built this one instead. It will never compare with all the impossible ideas we had, but at least it exists. In real life. Cyber real life.

Spin the wheel and check out the awesome quotes about some of our games! Also, play the Cat in the Hat titles and leave some awesome quotables here that I can post... ...since Kotaku and JayIsGames have yet to review those two. Kidding. No, not really. Yes.

Tuesday, September 25, 2012

Cat in the Hat Dives into the Swirly Whirly Ocean

We made a game, yes we did,
It's fun to play, we do not kid
It's fun to play on a ball,
It's fun to play in the hall.

...

...

...alright, I'll stop - sorry about that. Our two most recent games have just been released this past week and we're excited to finally be able to share them with you! As you may have guessed (or maybe not, due to my poor imitation) these games have their roots with Dr. Seuss. Cat in the Hat as a matter of fact. After the second week of development, Todd and I made a mutual agreement to cease our rhyming battles so we could get some actual coding accomplished.
Working with PBS KIDS and a few other very talented folks, we created Do You See My Seahorse? and Deep Sea Follow Me! to bring more fun and educational games to mobile devices. Both of these games use HTML5 which enables them to work across modern web browsers on both desktop and mobile devices.
We had a ton of fun working on these two titles (and my boys had even more fun testing them). Hopefully you (or your children) will enjoy them as well; check them out!

Monday, August 20, 2012

All the King's Men on Goko.com!

We are announcing the (beta) arrival of All the King's Men! We've been working closely with the folks at goko.com to bring this game to life over the past few months. Sign up for the beta, play, and let us know what you think! There may be the occasional hiccup with both the game and the Goko platform being in beta for a bit longer, so if you run into anything that short-circuits the experience for you, please let us know!

We're excited about the Goko platform and the opportunity it provides for HTML5 game developers in making it a little easier to develop multiplayer games for multiple platforms and devices. Check out the video for a short overview of what the folks at Goko are doing:



Also worth mentioning, there are a few other great games available on Goko's site that you might enjoy: Dominion (I would love this fantastic card game a lot more if my wife didn't always beat me so easily), Forbidden City (an elegant game by Reiner Knizia), Catan World (Settler's of Catan with a multiplayer twist), Treasures and Traps, and Race for the Galaxy.

Saturday, July 07, 2012

Enabling HTML5 Audio Playback on iOS Safari

I hate wearing headphones. :-P
Building off of a few things we've learned about audio on mobile devices, here's a convenient function for enabling audio on iOS devices. Essentially, as described in our first foray into audio issues on mobile devices, iOS will not play audio without it being first invoked by the user.

The following function takes a DOM element and assigns it an HTML5 audio tag to play when the DOM element is tapped. This hides the first user-invoked "audio.play()" behind another button so that it can now be invoked by code for the rest of the game without explicit user interaction. For example, in our PBS Kids games, we have a "Play!" button on the opening screen, assign our voice-over soundtrack to this button, and once a child taps "Play!", the game is thereafter able to play voice over clips without the need for additional user interaction.

function enableAudio(element, audio, onEnd){
  var callback = false,
      click    = false;

  click = function(e){
    var forceStop = function () {
          audio.removeEventListener('play', forceStop, false);
          audio.pause();
          element.removeEventListener('touchstart', click, false);
          if(onEnd) onEnd();
        },
        progress  = function () {
          audio.removeEventListener('canplaythrough', progress, false);
          if (callback) callback();
        };

    audio.addEventListener('play', forceStop, false);
    audio.addEventListener('canplaythrough', progress, false);
    try { 
      audio.play();
    } catch (e) {
      callback = function () {
        callback = false;
        audio.play();
      };
    }
  };
  element.addEventListener('touchstart', click, false);
}

To use the above, call the function giving it a clickable DOM element and an audio element to invoke as shown below:

enableAudio(element,audio);

As a bonus, if you want to make sure the audio is indeed ready before performing a next action, you can send a function as the third argument; this function will be called once the audio is ready.

Wednesday, March 28, 2012

HTML5 Audio on Desktop and Mobile

In addition to All the King's Men, we've been spending the past few weeks working on two new games that my boys will love playing. Powered by Ready To Learn, PBS Kids has given us the opportunity to create two math games for children that work across desktop and mobile devices.

This project brings a few new challenges that are unique to this style of game, one of them being a heavy reliance on audio. In our earlier games, audio is a great tool for creating a complimentary ambiance, but in these two games it plays a key role in providing instructions and prompts to maintain game flow.

Since we're targeting desktops and mobile devices, we decided to work our way through the different platforms until we had it functioning appropriately across the board. I'm not an expert on audio file formats, containers, compression, encoding and the like, so the following is simply the series of trials and bits of information I found elsewhere on the web as we worked through the evolving landscape of HTML5 Audio.
This picture has nothing to do with HTML5 Audio.
Except maybe metaphorically.

Ogg and MP3

With our earlier projects I used a two-pronged audio approach that worked well for desktop-based HTML5 games. Using Audacity, I exported all of our audio clips as both MP3 and Ogg files. Ogg covers Firefox and Chrome and the MP3 version is used by the other browsers.

Unfortunately this would not carry over to mobile devices. Testing our games on mobile devices, we found that neither file type would play.

Playing Audio on Mobile Devices

The first issue is that iOS Safari will not play a sound that is not initiated by the user (which also means we cannot preload audio clips :-/) and will only allow one audio clip to be played at a time. We decided to use a single audio clip and employ the "audio sprite" method first heralded by Remy Sharp. He also provides a good solution to getting the audio started by the user. We tied our initial audio play to a simple "Play Game" button at the beginning of the game.

The second issue was the audio format. Ogg is not supported by either browser on Android and iOS, and the MP3 I had created using Audacity fared no better. After searching for a bit, I found that AAC is the format of choice. First I tried exporting via Audacity. This version did not work on any of our test devices. Next I tried exporting from iTunes on my main development computer (a Windows box). This version also did not work. On a whim, I tried exporting from iTunes on a MacBook Pro. For some reason, the mobile devices (both iOS and Android) were able to play this version. I have no idea why exporting using iTunes on Windows produces a different m4a file format than using iTunes on OSX - if you do, please let me know.

I thought using MP4 would release us from MP3, but quickly found that Internet Explorer did not like the mobile-friendly version I created from iTunes, so now we have three audio formats and three different sets of audio files to cover the different browsers: OGG, MP3, and M4A

Playing Audio in Google Chrome

Most browsers handle bouncing around a single audio clip relatively well using the audio sprite method, but Chrome suffered from incredible and inconsistent lag while jumping from one time to another on a single audio clip. This made it essentially unusable when attempting to compose voice-over sentences on the fly: "Can you count" long pause "4" uncomfortably long pause "seahorses?"

Enter "Audia" by Lost Decade Games. I have not had a chance to look into Google Chrome's Web Audio API and wanted a simple drop-in solution to handle the audio analogous to HTML5's audio tag. We already have a lot of code built around the Audio() class, and using Audia allowed us to insert it into our current structure with very little change to our existing code-base. I did throw a try/catch around it so Internet Explorer wouldn't complain about its getters and setters, but the rest was merely checking to see if Audia was supported and replacing "new Audio()" with "new Audia()" if so.

Audio and App Cache

Lastly, loading three different audio streams and storing them locally via the application cache is inefficient and wasteful, considering that the any given browser only has need of a single version of the audio, not all three. Fortunately, handling this client side is not difficult, although admittedly my solution is a bit hacked.
Update (1-21-2013) by Derek Detweiler: The crossed-out method mentioned below worked at one time, but as mentioned above this was a hack. It no longer works in any of the modern browsers we have tested. Our current solution uses a server-side check of the user agent to pass along the correct manifest. An example of this method could look something like this for an .htaccess file: 
AddType text/cache-manifest .manifest

RewriteEngine on

RewriteCond %{HTTP_USER_AGENT} "firefox|opera|chrome" [NC]
RewriteRule ^cache\.manifest$ ogg.manifest [L]

RewriteCond %{HTTP_USER_AGENT} "android|silk|ipod|ipad|iphone" [NC]
RewriteRule ^cache\.manifest$ m4aCombined.manifest [L]

RewriteCond %{HTTP_USER_AGENT} "msie|safari" [NC]
RewriteRule ^cache\.manifest$ mp3.manifest [L]

Since the app cache manifest is not checked until the HTML document is loaded, I inserted the following JavaScript code inline to dynamically assign the appropriate manifest file to the document's html tag. First I assume the browser supports Ogg and the document uses <html manifest="ogg.manifest"> where ogg.manifest lists all the files used, including the appropriate Ogg audio files. The following code replaces "ogg.manifest" with either "mp3.manifest" or "m4a.manifest" depending on what the browser requires:

var myAudio = document.createElement('audio'), isMSIE = /*@cc_on!@*/false;
if ((myAudio.canPlayType) &amp;&amp; !(!!myAudio.canPlayType &amp;&amp; "" != myAudio.canPlayType('audio/ogg; codecs="vorbis"'))){
    if(isMSIE){
        if(document.documentElement.getAttribute("manifest")) document.documentElement.setAttribute("manifest", document.documentElement.getAttribute("manifest").replace('ogg','mp3'));
    } else {
        if(document.documentElement.getAttribute("manifest")) document.documentElement.setAttribute("manifest", document.documentElement.getAttribute("manifest").replace('ogg','m4a'));
    }
}

We're continuing to develop these two titles that my three boys are sure to enjoy, but I hope the above experience proves helpful on your own exploration of HTML5 Audio.

Friday, March 09, 2012

Positioning and Mirroring Images in HTML5... ...and Dragons!

While working on our most recent game, Todd implored me to sharpen some of our sprite rendering. Fuzzy sprites are a result of antialiasing and in our case some images were undergoing this process twice. Rendering pixel to pixel makes a much sharper image, especially if the image has already been anti-aliased once. For All the King's Men, we check the screen size and automatically create all the art at the correct resolution by scaling our sprites from the original size to the appropriate size needed for the current resolution (determined in part by our canvas auto-resizing). Since we pre-render the art at the correct size, and anti-alias it in the process, the last thing we want to do is render it to the visible canvas with a pixel offset, effectively anti-aliasing it twice. Todd accuses me of implementing my awesome "Blurrification Technology" whenever he noticed me doing this. This is how I addressed it (and hopefully stopped him from using made-up words).

At right is a scaled dragon sprite that is still relatively clear, after it's initial anti-aliasing. Also note the sharp color bars I've inserted to highlight the blur. This image is rendered at (0,0), so each pixel on the destination canvas matches a pixel on the source canvas. If our source image was stored in img and the canvas context is ctx, the code might look like this:

x = 0;
y = 0;
ctx.drawImage(img, x, y);

However, in converting from game world coordinates to visual coordinates, rarely are exact integers produced. So, for example, if we offset x by 0.35, the image is anti-aliased for the final rendering, giving the blurred image at right.

x = 0.35;
y = 0;
ctx.drawImage(img, x, y);

Addressing this is simple, since we can simply round to the closest integer coordinate and we once again see our pristine dragon.

x = 0.35;
y = 0;
ctx.drawImage(img, Math.round(x), Math.round(y));

This doesn't hold true when we decide to mirror the image, however. Now we have two items to consider: the original coordinates and where we're flipping the image. Generally, we want to flip the image at it's midpoint, so we could store that in halfImageWidth. Using translate and scale to set things up, we might have:

x = 0.35;
y = 0;
flipAxis = x + halfImageWidth;
ctx.translate(flipAxis, 0);
ctx.scale(-1, 1);
ctx.translate(-flipAxis, 0);
ctx.drawImage(img, Math.round(x), Math.round(y));

Notably, we have once again offset our image to sub-pixels as seen at right. We could round the flipAxis to the closest integer, but images can be flipped between two pixels or in the exact center of a pixel to render a pixel perfect mirror image, so we do this instead:

x = 0.35;
y = 0;
flipAxis = Math.round((x + halfImageWidth) * 2) / 2;
ctx.translate(flipAxis, 0);
ctx.scale(-1, 1);
ctx.translate(-flipAxis, 0);
ctx.drawImage(img, Math.round(x), Math.round(y));

Multiplying the original flip axis (x + halfImageWidth) by two, rounding that number to the closest integer and then dividing by two gives us a flip axis that's between two pixels or directly centered on a pixel. Once again, we have a sharp, pixel-perfect rendering from the source image to the visible canvas.

Thursday, March 08, 2012

Entanglement iOS - What's Going On?

Nothing has changed. :-/
To all of our wonderful Entanglement iOS fans, you may have noticed the promise of a new level "Coming Soon! Free!" that's been on the intro screen for... ...over a year. Well, it's not coming. Not because we don't want to, but because fulfilling that promise is unfortunately out of our control. Entanglement iOS was developed last year by CrateSoft and shortly after its release, the company all but disbanded. It does not appear that we will be able to work out a well-deserved future for Entanglement iOS in spite of the success you have helped make it. It is currently in the state it will remain for the foreseeable future.

If you own the iOS version of Entanglement, we want to make it up to you. We are prepared to give you the online Sakura Grove Expansion Set at no cost to you: simply send a note to us at feedback@gopherwoodstudios.com using the same email address you use to log into http://entanglement.gopherwoodstudios.com, and we will enable the expansion set for your account.

We've learned a few things from this unfortunate turn of events and we are sorry it has affected you this way. Thanks for your understanding and we hope you continue to enjoy Entanglement!

Thursday, February 02, 2012

All the King's Men

Todd and I have been busy working on a new game called "All the King's Men". (Yes, we finally named it if you've been following us on Facebook or Google+) It's not ready to be officially unveiled for play just yet, but here's a short run-through from our initial prototype.

Originally the game was a simple puzzle grid where a player could choose between several pins to push off and collect gems of the same color. The end-goal was a bit vague and players scored by counting how many gems they pushed off. In the prototype photo below, the movement pins are represented by Lego bricks, the gems are Risk pieces, and the game board is the only part I can find of my marble chess set. Playing this version with friends quickly highlighted a problem: game-play felt like a sequence of solitary moves. One player's move didn't really affect the next player's options, so there was no multiplayer strategy or fun to the game.

Prototype comprised of Risk and Lego
These look nicer than Risk pieces
After trying several variations, Todd decided it might be better to have each player play on their own board and their actions could effect the other players. This turned out to be a lot more fun. We had already found that the puzzle grid game-play worked best with three types of gems, so we turned that aspect into three ways to affect your opponents, scaled the puzzle grid from 8x8 to 5x5, and removed all but one movement pin. Since the primary interaction between players happens outside the grid, it served well to simplify that portion of the game.

I love playing Castle Wars with my wife, so I thought a similar theme might work well for an overall goal and the three gems mechanic. We ultimately settled on armies, castles, and flying boulders, with the overall goal being for players to complete their castle or destroy all of their opponent's castles. To complete the setting, the player assumes the role of a medieval king standing at his war-room table, using the puzzle grid to gather his kingdom's resources and imprinting his seal on the resulting commands to send his valiant armies to battle.

Getting ready to unleash Dwayne, the vicious dragon, on the battlefield.
I'm looking forward to completing this game and making it available for play so someone with more skills than I can beat Todd.

Friday, October 14, 2011

Loading HTML5 Game Assets

Before diving into HTML5 game development, I built a few conventional web sites (like this one - nice snapshots of the Blue Ridge). With conventional web design, page assets like images are loaded once the page loads, slowly filling out the blank screen with colorful pictures. This works well for web pages, since you can immediately begin reading the content and hardly notice the small delay as the images are painted in.

However, the wait for in-game assets can be especially long when downloading 10MB worth of images and sounds for a game like Entanglement. With Entanglement, the first issue I came across was that I couldn't draw a beautiful wooden tile to the gameboard canvas if the wooden tile image hadn't been downloaded yet.

My first attempt to solve this problem was to throw a JavaScript try/catch block around the drawImage calls so they wouldn't break the game if the image wasn't available yet. This resulted in the game starting immediately, but the gameboard slowly appeared as the images were downloaded. This is fine behavior for a web page but seemed a bit ugly for a web game.

My second attempt was a bit better: I included all the images in the html document as invisible <img> tags. This ensures that the images are indeed loaded before the game began but had the unfortunate side effect that JavaScript processing didn't start until the entire page was downloaded (including all the referenced images). This caused the long wait at a "Loading..." screen that couldn't be dynamically updated with a progress bar since JavaScript wasn't running yet.
It's doing something but we're not sure what nor how long it's going to take.
Enter the Asset Loader! This tool allows larger assets to be loaded after the page loads and the JavaScript processing begins. We're in the prototype stage of our next game, and I took this opportunity to build a proper asset loader. Seth Ladd wrote a wonderful tutorial on the basic steps to set up a simple asset manager. Using his insight and including a bit more code to handle audio assets, we created an asset loader that loads assets as well as calls two functions we can supply to track progress: what to do when a single asset is finished loading and what to do when all the assets are finished loading.
function loadAssets(assetList, onAssetLoaded, onAllAssetsLoaded){...}
The next piece we want is a nice progress bar. The <progress> HTML5 element has two properties we care about for keeping tabs on our loaded assets: max and value. Using these two properties we can create a very simple progress bar class to hand off to the asset loader that might look something like this:
function progressBar(parent){
 this.element = document.createElement('progress');
 parent.appendChild(this.element);
 
 // initialize the progress bar at zero percent
 this.element.setAttribute('value', 0);
 this.element.setAttribute('max', 1000);
 
 // for this example, progress will be some value [0,1]
 this.update = function (progress) {
  this.element.setAttribute('value', progress * 1000);
 };
};
We can then set up our asset loader to update the progress bar each time an asset is finished loading, by feeding the progressBar's update function the current state of loaded assets. In our asset loader, the "ratio" value shown below is simply the number of assets loaded divided by the total number of assets.
var assetProgress = new progressBar(document.getElementById('loading-screen'));
loadAssets(assetList, function(ratio){assetProgress.update(ratio);}, startGame);

We've already implemented the progress bar in the latest builds of both Thwack!! and Entanglement if you care to see it in action!

Thursday, September 29, 2011

Google In-App Payments: Convenient for buyers and developers

Todd and I are always looking for good ways to monetize our web games so we can continue doing what we love: making more games! With Entanglement, we created extended content that players can purchase if they really enjoy the game, and with our latest creation, Thwack!!, we created a reward system using tokens that can be won by playing the game or purchased for a few cents.

Back in January when we first released our Sakura Grove Expansion for Entanglement, we implemented an email and key system for purchasing: to access the expansion set for the first time, a player would make the purchase, wait for the confirmation email to arrive, and follow the instructions to get back into Entanglement with the key to unlock their purchase. Not only was the process indirect and inconvenient for purchasing a digital good, but it also took us quite a bit of time to develop and debug.

In developing our latest game, Thwack!!, we decided to implement Google In-App Payments. In-app payments are ideal for selling digital goods and the small 5% transaction fee is wonderful for the small transactions common to games.

Once our game's store interface was set up, I was pleasantly surprised to find integrating in-app payments very quick and straight-forward. In fact, I first began reading the documentation early one morning, and by following the very concise step-by-step instructions I had in-app payments implemented in Thwack!! by lunch time!

We were quite pleased with both the appearance and implementation for Thwack!! so converting Entanglement’s purchase process to Google In-App Payments was a natural next step. However, setting up in-app payments for two separate games on one seller account highlighted something I would need to change with my initially simplistic Thwack!! integration, where I had implemented the entire process, including the postback URL, through the web game itself.

Since I was adding a second game on the same seller account, I had to separate the postback process from Thwack!!. After a bit of restructuring, and less than a day’s work, I had In-App Payments running in both Thwack!! and Entanglement with a separate service that tracks orders apart from the games as shown below.

We now have Google In-App Payments running in both games in less than two days’ worth of programming with the additional benefit of a separate central location to track orders.

We found that Google In-App Payments is not only convenient for our game players by allowing them to remain in the game experience while making their purchase, it is also convenient for us as game developers by making the integration process quick and easy to implement.

Tuesday, September 27, 2011

HTML5 AppCache and Keeping Clients Updated

If you've played Entanglement or Thwack!!, you may notice that it takes a while to load the first time. Fortunately, if you've installed Entanglement as a web app, or played Thwack!! more than once, you may have also noticed that subsequent visits require much less time to load. This is thanks to the HTML5 application cache.

The application cache (or "appcache" for short) allows us to store the game and all of its audio and graphics files locally on your computer (here's a nice tutorial on implementing an appcache). Next time you play the game, the application cache loads the files from your computer rather than pull them from the Internet. The beauty of this is two-fold. First, the game can start loading quickly since it doesn't need to check for anything online first. Second, the game can load without a connection to the Internet at all!

One drawback to this is that if someone plays the game and then returns some time later, the next time they play the game their browser loads a version of the game that's potentially weeks or even months old. If there's an updated version, appcache will load the files in the background to prepare for the next time the game is loaded, but the version the player is currently experiencing is the old version until they reload the page. This isn't too much of a problem with Entanglement where changes from one version of Entanglement to another do not negatively effect the experience.

What a player sees if running an old version
However, with the online multiplayer aspect of Thwack!! it's a bit more disruptive. With Thwack!!, each client independently calculates the results of a given turn, and those results have to match up with each other. For instance (not connected to reality... ...okay maybe a little), if Todd decides on a whim to change all of the discs' sizes, weights, and damping, the new version he deploys will calculate a different result for a turn than an older version stored in appcache. This effectively breaks the experience for not only the player whose browser loaded an old version of Thwack!! but also all of the players connected to that particular game.

The fix is fortunately quite simple. When a new version has loaded in the background, we know that we're not running the latest version. We can check this by implementing the following event listener:

var newVersionWaiting = false;
var updateReady = function()
{
    newVersionWaiting = true;
};

window.applicationCache.addEventListener('updateready', updateReady, false);

Now that we're aware of a new version waiting on the sideline, we can notify the player that they're running an outdated version before we let them in on a multiplayer game. Additionally, we attach a page refresh call to the message dialog's "OK" button to make it even easier for them to get the most updated version. Here's a snippet from Thwack!! where "messageBox" creates the dialog you see in the screenshot above. The first parameter is the message and second parameter, a function, is executed by clicking "OK":

if(newVersionWaiting)
{
    messageBox(RELOAD_THWACK, function(){window.location.reload();});
}

Monday, September 19, 2011

Edison Project Win!

A few weeks ago I mentioned we were one of 9 contenders in a local business competition called the Edison Project. We achieved second place! It was a tough competition, but we lauded the virtues of HTML5 and threw in a bunch of games to give us an edge.

Thanks to: Danny Hearn and the Catawba Chamber for putting this competition together; the sponsors: Alex Lee, CenturyLink, CVCC, Catawba County Government, and the Committee of 100 for making it a reality; and Bill Parrish of the SBTDC who worked with us and gave us invaluable feedback as we put together our business plan and presentations!

Todd's response to seeing a check this large for the first time.
We also want to congratulate the first place winner, David Washco, with Price Drive. He doesn't have his product out yet, but he has a very compelling idea that we hope to see come to life soon. The third place winner, Peter Lohr, with Advanced Hydrogen Technologies Corporation, also has a brilliant idea that could fundamentally change car fuel systems.

Until the official news release gets out, hopefully this picture of Todd will suffice to show our excitement in the recognized feasibility of our business plan... ...and winning a check that's taller than my sons.

Update: Hickory Daily Record article


Tuesday, August 30, 2011

Changing an Icon


Today I came across a useful tip for developers submitting applications to the Chrome Web Store.

Recently we created a new vector-based icon for Entanglement and decided to use the new version in the Chrome Web Store. (There are a lot of square icons in the store, and hexagons are so cool.) Doing so updates the icon on everyone's "new tab" home page as well, which in turn sparked renewed interest in Entanglement. Notice a snapshot of our Entanglement web analytics above: a bump of approximately 60% more visitors on Monday (the day we uploaded the new icon) than the days before.

Up to now, we were not sure how to best reach people who have installed one of our apps and let them know that we have rolled out a major update. It seems a very easy, and almost elegant, way to do so is to simply change the app icon!

Monday, August 29, 2011

The Edison Project

Last month we were selected as a finalist in an entrepreneurial competition held by our local chamber of commerce: it's titled "The Edison Project" and is designed to help folks turn their creative business ideas into reality. This has been a great opportunity for Todd and I to take a look at the business side of things and think strategically about how we can make a livable income doing what we love: making games for you! Regardless of who wins, having a chance to create and work through a business plan has been a great learning experience.

Here are the other eight businesses that were selected as finalists:
The competition consists of three parts: our business plan, a presentation to a few local business leaders this week, and finally a presentation to a public audience. If you live in Hickory, NC, or the surrounding area, come and check it out! It's at the SALT Block Auditorium from 4-6pm on September 19th, 2011. There is no charge and you can vote on your favorite presentation. We can chat afterward about HTML5, game design, or why Todd no longer participates in motorized crowd surfing.

Update: We achieved second place!

Thursday, July 21, 2011

Key Frames Are Cool

Open Prize BallWe are planning to give away new discs (that players can collect) when games are won in Thwack!! (You can't get prizes just yet, so don't be too disappointed if you beat the skill shots and receive nothing.)

Todd thought a prize ball would be an exciting way to deliver these prizes. We could use canvas to do this, but today, just for fun, I decided to experiment with CSS key frames and use the DOM instead.

I had read about these on several occasions, but haven't tried them yet. It was much simpler to implement than similar code I could conjure up in JavaScript to do the same thing (example is for webkit browsers):

@-webkit-keyframes ballroll {
  from {left: -25%; -webkit-transform:rotate(-1440deg);}
  50% {left: 125%; -webkit-transform:rotate(0deg);}
  to {left: -25%; -webkit-transform:rotate(-1440deg);}
}

.prize-ball-roll {
  position: absolute;
  height: 75px;
  width: 75px;
  bottom: 0px;
  left: -25%;
  z-index: 20;
  -webkit-animation: ballroll 4s ease-in-out infinite;
}

If you are viewing this post in a browser that supports key frames, you should see a prize ball rolling across the blog. How cool is that!?!

Thursday, July 07, 2011

Thwack!! on html5rocks.com

HTML5Rocks.com has just published a tutorial I put together on resizing games to fit a browser's window size. I fleshed out some of my content from an earlier blog post and put together a few diagrams. Check it out!

We're working on online multiplayer for Thwack!! and are excited about releasing it soon.

Wednesday, June 08, 2011

The Daily Challenge and Going International

The Daily Challenge is finally here! What is the Daily Challenge, you say? The Daily Challenge is the final piece of the Sakura Grove expansion set and the ultimate way to compete versus your friends and family to find out who's the best Entanglement player. How's it work? The Daily Challenge presents all players with the exact same puzzle for one full day. Players can play this puzzle as many times as they like to try to get the highest score possible. Since everyone is playing on the exact same map with the exact same set of tiles, it's easy to determine who's the best and who's just lucky! The player with the highest score so far will have his name and score displayed on the board for all to see. At the end of the day, a new puzzle is created and the fun starts all over again!

How do you access it? To play the Daily Challenge, go to the main menu and select Solitaire. You will see a list of different maps/modes to play. Daily Challenge is at the bottom of the list. If you don't already own the Sakura Grove Expansion you'll be prompted to buy it in order to access the Daily Challenge.

In other news, we've finished translating the game into more than 30 languages! If you live in a non-English speaking country you may have already seen the results of this update since the language changes based on the country settings in your browser. If you notice any errors in the translations, please let us know. We only speak English so we're completely blind to errors in other languages.