Globbert is a interactive stop motion cartoon now available on iPad and iPhone. Once Globbert enters the main stage players can interact with the environment and Globbert by poking and squishing him around his world. Noisy speakers interrupt Globbert’s peaceful world and it’s your job to help Globbert regain his peace and quiet by attacking the noisy things, sometimes with surprising outcomes.
A few people have asked myself and the creative minds (Chris & Marc) behind Globbert what engine Globbert is built on top of. Having only ever previously done apps that interacted with API’s, such as Magic Bean and obviously Buffer, Globbert was something entirely different. I’ve never tried to tackle building what is essentially a “game”, albeit one with the label of an “interaction stop motion cartoon”. This post not only serves as an insight into the tech behind Globbert but as an insight into some of the challenges I faced along the way and I how I overcame them.
First thing’s first, a demo
It was decided a demo would be created before kicking off the project, not only to show that it can be done and performs well but to also prove to myself that I could step out of the world of UITableViews and get the animations displaying on a device and running smoothly in time to sounds.
The demo contained only a few select animations and was obviously crude, excluding nice functionality like squishing and poking. Instead buttons along the right hand side of the screen allowed you to trigger animations without any of the polish seen later in the App Store version.
Even though it was completed within a fortnight, the demo showed Chris, Marc and myself that Globbert was ready to go to the next stage.
Playing out the animations
Each animated sequence contained in the app is a series of images, looped through at 25 frames per second, to create the illusion of motion. Globbert didn’t and still doesn’t use an existing engine, all animation playback is driven by a hand-crafted, bespoke implementation. Each animation is stored as a plist file, containing each frames’ filename and coordinates, ready for display.
Each plist file within the demo was crafted by hand, a painstaking process of copying the filenames for each frame and placing them into the plist one by one, including any additional sound files that needed to play out at specific points. This was time consuming but got the demo functioning as it should very quickly. This wasn’t a solution that was going to scale when it came to building each of the Plist files for X animations however…
For the real thing, Aaron Wardle had mentioned PlistCreator. I managed to use this to take an array of file names and with some other PHP magic it could create the files for me by simply passing it the images for each animation. This was done by grabbing the image files and dragging them to an upload field which then generated the file based on the image filenames, pulling out the required animation reference and coordinates for each frame.
Even though some of the plists required some gentle massaging afterwards, this tool ultimately saved me hours of repetitive work. It just goes to show that every dev should know at least one scripting language to help automate these mundane tasks.
Animations need sound
Sounds for each animation lived in a separate Dropbox, along with a spreadsheet which gave the specific frame number the sound needed to be played for. Most of the animations support multiple sound effects, so the animation doesn’t feel repetitive when you poke and squish Globbert around his little world.
Adding sounds to the app was obviously much simpler than the animations themselves, with only a filename needed in order to trigger the sound through the standard iOS frameworks. However we didn’t want sounds to be repeated multiple times, so the audio system was tweaked slightly in order to ensure a sound is only played once per animation. To get around this various animations have their sounds stored elsewhere in a list, each time a sound is played it is removed from the list. Once the list is completely empty the list is re-populated and the process starts over again.
Adding the ability to hold frames
Some animations within Globbert require a frame to display for more than the usual 0.04 seconds (1/25th of a second), so like sound I had to include an option within the Plist files to hold a frame for a number of given seconds. When the code loops through the Plist and finds a hold it will pause the loop for that length of time. Sounds simple, right?
Sleeping the loop wasn’t enough as in that time the state of the app could change. Globbert could be squished during the sleep or splatted across the screen. This meant that the sleep could potentially be invalidated at any time so another animation could be started. Another loop was used for this which after each frame it had been held for checked that the state was still the same before continuing with the sleep. If the state changed it checked the state and either continued or canceled the current animation and moved on.
Follow on animations
Some animations have multiple endings and only look completed when another animation is played. For instance an animation of Globbert flying back on screen doesn’t show him land, the animation Plist file contains a list of animations that can follow and one is selected at random. Another way to ensure that the experience doesn’t feel repetitive.
Many animations at once
From the outset Globbert required multiple animations to be happening at once all interlinked with one another.
For example, a speaker would include an animation and sound, but at the same time Globbert would need to show a reaction to the speakers. Each animation has it’s own duration, sounds and loops that need to be managed. This required slightly different handling for a few different aspects, so animations were grouped by type.
- Globbert Animations
- Speaker Animations
- Idle Animations
- Exit Sign Animations
- Instruction Animations
Each group of animations has slightly different play out logic, for example Speaker animations play and loop a set of frames in while sound files are playing. Once completed the speaker animation progressed passed the set of frames used during play to retract off screen.
Each frame of animation within Globbert is comprised of the element moving and the background from the set, this meant that frames could sometimes clash and overlap. Extra logic within the play out allowed certain animations to speed up to avoid overlapping frames within certain states. For example, a speaker would be playing a noise to annoy Globbert and would be squished to try and atatck the speaker which would retract quicker than normal to avoid overlaps with bounce-fly animations which see Globbert bounce around all corners of the set.
Part of the magic behind Globbert is when the story happens off screen; when you squish Globbert and he flies out of the viewport, a set of different audio clips is played. You’ll hear Globbert interacting with things not visible on screen. Things that you can imagine him doing in your head.
While he is off screen the world would have been completely still, so various idle animations play out during off screen audio clips to keep the world alive, such as dripping pipes or eyes peeking out.
Queuing animations didn’t seem to work well.
When Globbert is squished he flies off the screen, the animations that are performed for this are comprised of a list of separate animations which show Globbert bouncing around the screen in different directions. These all vary in length and initially were built using a Plist which detailed the separate animation references. When one of these bounce-fly animations needed to play out it would have to grab the reference from the queue before fetching the Plist for that animation before progressing onto the next one in the list. This method worked fine in the simulator and on newer iPads but when it came to the 1st generation iPad it just couldn’t handle it.
The queues were eventually removed and each of the bounce-fly animation Plists were manually created to remove the need for the animation queue files. This improved the performance on the 1st generation iPad.
Make Globbert come alive
To give Globbert the impression of being a living, breathing character subtle effects such as blinking and reacting to the players actions had to be introduced, otherwise you end up with a rather stilted character no-one would believe in. The first step to make Globbert come alive was to add blinks and double blinks throughout the animations, while still allowing squishes and interactions to flow correctly.
After we had breathed some life into the animations, Globbert felt much more natural. With a moving, chaotic world the player never quite knows what to expect when they squish him.
Globbert for iPhone
While we wrapped up development on Globbert for iPad we started to think about iPhone. The iPhone app would be a scaled down version of the iPad app with a few entries removed due to the smaller window into Globbert’s world.
After a few hours sat with a calculator, the maths to work out how much everything needed to be scaled down by was done and all of the assets and playout code was tweaked ready for the smaller viewport.
iPhone 5, another screen resolution…
While Globbert for iPad was being developed Apple announced the iPhone 5. The iPhone 5 came with a taller screen so we had to figure out a way of making the world work within the new resolution. We decided rather than zoom into the world and affect more of the gameplay within Globbert, we would add a border to the top and bottom which sat within the world.
Not all of the challenges have been technical ones; working at Buffer has meant I’ve been traveling around various parts of the world while trying to keep things ticking over with the app. Globbert has well and truly become a transcontinental project, with development ranging from the beach front in Tel Aviv, to coffee shops in San Francisco and even back home in Birmingham.
This has proved challenging providing builds of the app for testing, requiring a rather decent Wifi connection wherever I am to submit TestFlight builds. Fortunately Globbert sits just under the maximum limit for TestFlight builds and has proven invaluable in getting Globbert developed and tested while I have been traveling.
- 16,000 files in the Xcode Project (contains both iPhone & iPad targets).
- 400+ Plists for both versions.
- 550+ audio files for both versions.
- 6300+ images, for the iPad version alone
Go grab Globbert now!
Drop me a comment below if you’d like to know anything else about how Globbert was developed, I tried to cover as much as I could that I thought might be interesting so no doubt I’ve missed something.