So here’s something that’s bugged me for a long time. So I have an iOS app (packaged in Adobe AIR) that does three things on startup:
The hardware-launched splash image appears
The app then takes control, and shows a loading screen for my own software pre-loader
The app then “for reals” launches and to make the transition smooth, shows the same loading screen before tweening in the main menu.
To make things look like they are smoothly loading, I’ve actually set all three of those images to be exactly the same image. They are the same dimensions, and in fact are the same file. I don’t do any manipulation within the app itself.
Buut… for some reason my second image, and only my second image, is scaled incorrectly on different iOS devices. The app is fine on Android and desktops.
I pretty quickly found out (by tracing values) that iOS itself (or Adobe AIR as middleware) was mis-reporting the dimensions of the phone on startup. After around a year of slamming my head into a brick wall, I discovered that it only mis-reports for about 150 milliseconds, then it fixes itself. This is the only window of time where things are going wrong.
So any images that are placed or resized in this window of time (that is to say, immediately upon the app opening) are displayed in a bit of a wonky fashion. Most of my apps don’t experience this, as I front-load my apps with texture loads and such, but this particular app put the loading image up before any other processing happened, and that’s what was forcing the error to surface.
I was able to work around this problem by just putting a 150ms delay into the app to wait for iOS to sort itself out. Hopefully this will help someone else running into the same sort of problem.
(Note: The mis-reporting time seems to be random, but 98% of all instances occur below 100ms and above 10ms. I haven’t seen it misreport over 150ms so far, so it’s the figure I’m using in my application.)
Edit: As pointed out in the comments, iOS throws a resize event if it happens early. Here’s a screenshot of my mess of code:
Since iOS7 released, a few apps on my iPad have been asking me for permission to use my microphone. Apps like calculators and other benign things that should have no microphone access. Including my own microphone-free games. This is concerning! People in the comments are asking about their precious privacies!
After googling around I noticed there was no real solutions or reasons posted anywhere within easy eyeshot. (Is that a word? eyeshot?)
Turns out that any app packaged with Adobe AIR with a version of 3.8.x (or earlier) will produce this behaviour. The Adobe AIR runtime hooks the microphone even if you don’t use it, just so it’s available in the API. Versions 3.9+ of the Adobe AIR SDK only hook the microphone if you explicitly use it, so recompiling using v3.9 is an easy and fast solution to the problem.
This past weekend Kim and I attended (as an instructor and a mentor, respectively) a student game jam at the Centre for Digital Media in Vancouver. It was 30 hours long (much shorter than what I’m used to) and was intended as an exercise of scope control, and a demonstration of what was possible under pressure.
In addition to just helping out with the event, I challenged myself to (1) design and produce a game from scratch, (2) have it up and available for sale, and (3) to make money… all before the jam ended. I was hoping it might inspire some of the students or to help them realize their potential; but mostly, it was just a fun challenge for myself.
I had a few false starts; a few bad ideas were sketched on paper. I started thinking of subversive games; maybe I could make a game where collecting points wasn’t done in an obvious fashion? Kim mentioned “burger clicker” at some point, and I was trying to fit an idea into one of the jam themes (food addiction), so I started doodling out a basic concept on paper (shown at right).
The concept was clicking on a hamburger to get points, but have the leaderboards based on an entirely different button buried in the Options menu. There would be a “cash out” system where you could save your points and reset your progress. If you don’t cash out, you risk losing it all.
I read this idea out to Kim and showed her my doodle, and we started excitedly evolving the idea together until it became an in-app-purchase-filled pay-to-win abomination. Riffing off of the “cash out” system (which essentially made the game a giant slot machine), we decided to call the game Burger Dare! You inflate your burger with “beefiness” by madly tapping on the screen, and try to cash out your points before you get greedy and lose it all.
I built most of the game with programmer-art and Kim swooped in and replaced all my assets, for which I’m super thankful. Now my hamburgers look like hamburgers instead of rotten eggs!
We spent a while tweaking the juicy-feel of the game, making sure there was plenty of particle effects and visual rewards for the player. I also chose a sound effect that is psychologically painful sounding for failure, which actually made people physically recoil from my tablet during playtests. Fun! (We also added the ability to “polish” the burger, instead of tapping it, as a hat tip to RetroGamer’s Happy Poo for Two)
Monetizing the game was an experiment for me. I have never done IAP before, and had no idea where to begin with that, but I ended up successfully getting it all in by the deadline. In the end we have several avenues of profit:
The “cash out” (eat) button has an ever-increasing timer, artifically slowing down gameplay. For 99 cents you can reset this timer back to zero (where it will continue to increase again).
For 99 cents you permanently reduce your chance of failure by about 10%.
For $2.99 you permanently gain double the points per tap, but also increase your risk of popping for each tap.
I added a 99-cent-per-month subscription service that allows you to get two hamburgers at a time instead of just one. This also doubles your points-per-tap.
My personal favourite is the not-as-obvious “buy points” button which gets you 100 million points of beefiness for only 99 cents.
Kim and I were essentially trying to make an “evil” game that made a mockery of other IAP games. I haven’t played Ian Bogost’s Cow Clicker, but from what I hear we are headed down the same sort of deconstructive-satire path here.
The biggest evil thing, I think, is the 99 cent subscription for dual burger mode. I gave it a 7 day “trial” period that you can cancel at any time, for no charge – but the subscription will automatically start billing your credit card after 7 days. Uninstalling the application does not affect your subscription, and I personally had to google instructions to figure out how to opt-out of it.
Of course, all the achievements in the game and the structure of the leaderboards encourages people to buy, buy, buy!
I ended up pushing the game to the Google Play store a few hours before the end of the jam, because IAP-enabled games must go through a bit of a content-delay-filter before they are live to the public. This gave me a few hours to really refine our product description page, and I think I did a pretty good job of that.
In the end, we didn’t really expect anyone to buy a single one of the in-game products; I just wanted the game out on the store as sort of a head-shaking, chuckle-inducing commentary on other games.
Of course, a few hours after launch, someone did buy something. 99 cents is now in our pocket.
I hope this person paid because they enjoyed the commentary, the art, the meta-product; I don’t think my brain can handle the possibility that someone might have actually paid to get a high score!
Anyway, the game is out now on Google Play. Check it out, let us know what you think! It’s currently got six 5-star reviews, and not a single one was left by us. :3
The conversion from iOS to Android took exactly one day (plus a few hours of special-case device patches the next day), including launching on a new platform and integration to the new Google Play leaderboards. Total dev time for the game is now 9 days! I really like that the Google Play store allows you to upload-and-publish nearly instantly.
IceBurgers is one of those games that really makes me proud. It’s a solid design, it’s a lot of fun to play, and I keep going back to it even 1.5 years later. It needs to be re-skinned and marketed a bit more seriously, but that’ll be a project for another day. :)
Well, it’s finally happened – I’ve got an intern, working here across from me at his desk (Hi, Rafa!).
It’s strange – for all these years, Radial Games and my own personality have really been one and the same. I could post about corporate news here on my blog, and my own personal twitter account really was the voice of the company. But that’s not really the case anymore; now Radial Games represents something bigger, something a bit more idealized than just my rantings. Radial Games, as its own entity, has to start building a fan base – instead of just focusing on developer-developer relationships, like I have been doing to date.
I’ll still use this blog to post all my developer-friendly stuff. Numbers posts, y-axis porn, angry rantings about Unity… You know, the usual. :)
I guess I never took this step before because I always thought that making an actual game is much more important than “updating my social media strategy for a new core vertical.” But here I am, typing this, and my game is still being made (Hi, Rafa!)! I seem to have eliminated my own excuses from the equation.
Phil Hassey (creator of Galcon!) has been on a few family vacations on Lake Powell (Arizona) — specifically, on epic houseboats. He thought it would be a great idea to do an Indie MiniConference aboard one, but set aside the thought as organizing such a thing was just a bit too complicated.
After seeing Colin Northway’sGDC soapbox talk (fast forward to about 1:04) encouraging indies to “just do it,” Phil put the call out to make the houseboat conference happen – and happen it did! I spent the last week on just such an epic houseboat and it was amazing.
(I’ve taken a bunch of GoPro videos (some in slow motion!) and will try to edit together a highlight reel sometime after PAX.)
Here’s some thoughts on each day of the trip:
Getting from Vancouver, Canada to the small town of Page, Arizona required a bunch of uncomfortable air travel with long delays. Our final flight was on the worst managed, most comical, most unprofessional airline I’ve ever been on (Great Lakes Airline), which I actually found kind of refreshing and fun (but other passengers definitely looked terrified). We arrived at the houseboat in the late evening, after swinging by a grocery store for final supplies.
Though it was dark, the full moon was reflecting off of the ghostly white buttes and giving me a hint of what might be coming in the daylight. I stood on the roof of the houseboat, hands on hips, and said “wow.”
When day broke the next morning, I stood on the roof of the houseboat, put my hands on my hips, and said “wow.” Seeing the sun striking the vertical cliffs surrounding us was amazing, and I’ve never seen such terrain with my own two eyes before. It’s one thing to see it in film, it is entirely another to be dwarfed by the massive, impassable structures.
After a slow start and collecting our auxilliary speedboat (which I will nickname “Titanic”), we travelled about the convoluted lake, weaving in and out of narrow passageways. We took Titanic out to navigate more quickly in the narrower spots, and visited a nice beach we named “The Swamp of Feet Burning.”
In the afternoon we discussed our “secret sauces” to success and I presented a bit of a structured rant on how to tell your personal stories.
We ended the day by making traditional Canadian Inukshuks on the shores of Antelope Island.
In the morning we brought out our water skis and dragged them behind Titanic! I’ve not been on water skis since I was much younger, but I managed to get up on them (albeit briefly). Playing on the water is a lot of fun, and it’s made even more amazing being surrounded by fantastic scenery.
In the afternoon we discussed the importance of introspection and analyzing your own failures; the future of Galcon; cognitive game design (how the brain works!); and music in games, as more than just a background.
After spotting a nice place to camp out for the night in Danger Canyon (the best canyon name ever), I was out speeding around in the Titanic when we spotted a Floating Toilet. I’m not sure why, but the floating toilet was a pretty amazing discovery – it appeared to be brand new, was rather large, and even featured dedicated male and female options. It was enough for me to put my hands on my hips and say “wow.” Excitement!
If I thought the canyons and cliff walls were impressive before, the trip to Rainbow Bridge blew me away:
Even re-watching that video makes me want to put my hands on my hips and say “wow.” After docking in the canyon and hiking a mile, we made it to the dramatic destination where we saw for-reals dinosaur footprints on the ground and this in the air:
In the afternoon we discussed game creation tools; community growth and management; reframing AI; and talked about how culture is shaping around video games.
I piloted the Titanic out of the narrow canyon and, due to a dislodged warning buoy, nicked the propeller on a submerged rock. Excitement! Adventure! The boat still ran fine so no big deal, but it was a bit of a scare. I felt pretty guilty, poor lil’ Titanic didn’t do anything wrong!
As we were trying to find a place to camp for the night, we sent our houseboat down a very narrow canyon. I didn’t get any footage of it, because a storm suddenly blew in and slammed us around for about 30 minutes before we could escape; we were all-hands-on-deck trying to rope the thing down. It was the scariest time on the trip, and it was enough to make me put my hands on my hips and go “aughghhh!!”
Day four was our first all-steam-ahead heading-back-home day. We played in the water, took Titanic out for some more skiing, and stopped at a floating gas station to refuel.
In the afternoon we discussed marketplaces; indie survival (from a more personal perspective); and discussed the environment as a character in a game.
In the evening I proved my worth as Captain by hitting yet another submerged rock and this time completely ruined the propellor of the Titanic, PLUS snapped the drive shaft. After paddling the boat manually to the nearest beach (quite the workout) and trailing a nice oil slick, I surveyed the damage and our situation (without radio, stranded on a beach, no way to contact the mothership). It was enough for me to put my hands on my hips and say “wow.”
Thankfully there was a houseboat parked a short walk away, and a very helpful fella there towed the Titanic back to our houseboat for us. Hooray! No need to launch rescue flares (I don’t think we had any rescue flares….). I still feel pretty bad for ruining our most fun toy, though.
That night a lightning storm surrounded us (but not over us), and the wind blowing through the handrails on the roof of the houseboat made the boat sing. We could hear other houseboats across the lake singing back to us, when the wind shifted direction… It was quite magical.
The entire IndieBoat 2013 crew
Our final day travelling back, we were a bit behind schedule so we didn’t stop to play quite as much. We did a few recap talks and eventually made our way back to the marina, where we saw some other poor souls on the horizon – their houseboat ablaze, thick black smoke pouring into the sky, fire and police boats nearby. Suddenly, I didn’t felt quite so bad about the damage I had done to the Titanic.
We made our way back to the hotel and collapsed; our whole crew was exhausted. While sipping cactus-margaritas at the hotel bar, Kim and I thought up an exciting new idea for a video game, using the talks and lessons learned from the week. It was nice to reflect on things and use them in a game, and not just theorize about.
I was standing there, my hands on my hips, and saying “wow” – wow to the terrain around us, wow to the experience we had just had (both good and bad), wow to new friends, and wow to the game we had just designed.
This fact is completely divorced from the problems a large organization like the IGF faces. They simply have too many submissions each year, and each year they have a relatively smaller and smaller pool of volunteers to help sift through these submissions.
The IGF will break and cease functioning at the current increasing-submissions trajectory. So a solution was put into place: a fee to enter your game into the running. Yes, this is judging and sorting people by how rich or poor they are. Yes, this sucks. I’m not sure what other alternatives there are though:
Banning all people making over $50K /year will make more people upset.
Banning all white people from entering will make more people upset.
Banning people by nationality will open a huge can of worms.
I honestly can’t think of a system that will produce LESS upset people than a small entry fee.
Adding more judges might work, but they’d have to be paid (volunteers aren’t working out as they’d hoped), which would increase the entry fee by quite a bit.
Last year, several indie devs (myself included) offered to put up the money for anyone who couldn’t afford it, via a shared pool, distributed anonymously so there would be no shame. We had no takers. :/ Not sure what to make of that, but I’ll just state it and leave it there.
Is there a better solution, one that results in fewer upset people than the current system? No matter what we do, we have to let someone down, and shut someone out (just because of the sheer volume of submissions).
As our industry grows, though, we’ll start seeing new venues open up, new awards being given, new opportunities to be had. Maybe one day the IGF submissions will require that your game be on Steam first, or that you have been nominated for an award in another venue. All possibilities! But we have an opportunity to change that future for ourselves, here and now, with our voices.
We do that by suggesting what we’d like to see, instead of just complaining about what we have.
Here’s some sales data from Monster Loves You!, the full sales chart, with numbers to-date from-launch.
Let’s look at the individual components here:
In mid-March, the game launched to such a tremendous success that my jaw fell off and it changed my life. The game was 15% off at launch.
Throughout April, let’s-play and review videos kept making sales bumps; throughout the game was regular price, US$9.99.
In May, things calmed down a bit.
In early June, a small bump is visible – this is the launch of Steam Trading Cards.
The HUGE spike in mid June is a 48 hour featured/banner sale. This produced more revenue than the launch spike, even though the game was 33% off.
In July, the Steam Summer Sale had Monster Loves You! at 40% off, but the game was not featured – you had to search for it specifically to see it. Still, a nice bump in traffic though.
As it stands, the Steam Summer Sale’s tiny blip in revenue there is more revenue than the entire month of May. The featured sale in June produced more revenue than May through August.
I wish we didn’t live in a culture where “let’s just wait for the sale” was common. I wish that putting my games on sale didn’t reduce their implicit value. I hate that I’m locked into this system of ever-increasing discounts, where you can probably guess that at Christmas time the game is going to be half-price (just by plotting my sales trajectory). But…
This is the world we live in. Getting your game on Steam in the first place can make or break your studio, but once you’re there? If your game is featured for a sale, that can make-or-break you for a second time. Choosing not to compete in this system just means that you are walking away from these potential profits, and there is no data suggesting that games that never go on sale make more money in the long run.
So I embrace it. I love the sales. It becomes an event, for me here — staring at my dashboard, watching the charts and graphs rise and fall, me waving my hands in the air as if I’m on a roller-coaster. It’s great!
More important than the money, though, is the simple fact that more people are playing my game. Each time there’s a sale, there’s a slight bump in Steam Forum traffic. New people discovering the game, laughing, smiling, and getting all the inside jokes. That’s the important bit right there — validation for work done. It’s not just people buying a game because it’s cheap, it’s me exposing a great game to people that otherwise would have missed it entirely.
I’ve been playing a lot with external files in AS3 (well, Haxe+NME to be more accurate) in my recent projects.
Monster Loves You!, for instance, loads (at runtime!) all of its audio, images, configuration, and story text from external files. If these files aren’t found, then it reverts to the old internal copies it was compiled with. I love this hot-loading system, for four really big reasons:
Iteration cycles are much faster when working with content teams. MLY!s artist didn’t need me to compile his latest assets into the game; the story writer doesn’t need to figure out how my IDE works. You just drop the latest files into the game folder, and presto, it automagically overwrites its internal content.
Potential for future community mods is massive. Right now, with the live Steam version of MLY, community members can drop files into the MLY install directory and get a whole new game out the other end. Of course, I haven’t documented any of it or left examples of filenames to use, but the potential is there.
Developing DLC or feature-parity sequels now means just patching in a few external files and not a complete re-compile; if the entire source code is lost (or tied up in legal matters) the game can still be expanded. Steam automatically handles game patching, so I won’t necessarily need to use this, but it feels nice to have the option.
Streaming patches in dynamically is much easier. A game using this system could be compiled to run in a web browser, and the “local files” it searches for could be pointed to the URL of a server I control. I could then stream different configuration files to different A/B test groups where I tweak the in-game “gravity” constant or some such.
All of this isn’t a from-scratch system that I developed just for Monster Loves You!. This feature set has been slowly building in my Radial Games Utilities Library for years, and as such it is largely a hodge-podge of tech slammed together. No need for crazy optimization here; the entire process is only a second or two on initial boot.
Since MLY is the first game I’ve commercially released as a PC Downloadable, support for the Windows file system was added in six months ago. I added support for the Mac file system last month, and Linux is likely to follow.
Of course, I ran into a massive, head-scratching dev-breaking okay-on-steam-for-some-reason bug this morning, and this system was the culprit. When I discovered the error I had one of these moments:
Edit, July 28th: Found someone! Thanks to all who applied.
Andy’s List of Serious Business Responsibilities(tm) is getting so long that it’s becoming difficult to properly prioritize and focus on things. So I’m officially taking Radial Games to the “next level” and hiring my first local (Vancouver, BC) employee!
Since I am just starting out and don’t have a big pile of government grants, I can’t hire a big team and start working on a big project; I’m just going to start out with an entry-level, junior-ish, intern-like programmer and build upwards from there.
I’ve been in touch with a few local schools and for that I had to write a fluff-piece about myself, which is terribly awkward and uncomfortable. I hate writing about Radial Games in third person, but I had to do it. If you are interested and want to read more about the position, check it out here.
Feel free to pass it around to anyone you know in Vancouver looking for some entry-level awesome-work!