Nov 042013
 

I put together this little teaser video back in September showing off/announcing what Depth Charge was going to be:

Alas, we did not make it to MineCon.  Next time!

WhiteBoard

Development Whiteboard

I was intentionally light on the details and didn’t show off a whole bunch because the game was pretty heavily under development back then… The video actually showcased the original Flash prototype, and not the current version of the game.  Radial Games‘ new intern Rafa has been cranking away at it since then, and the game has really come along quite nicely.

The game is now working in Unity and exporting to iPads, we’ve got a dozen ship types, solid goals for missions, and we’ve even laid out all the niceties — tutorials, menu structure, all that stuff.  We’re aiming to ship before Christmas, and I think we can manage it!

We still have quite a few big questions to answer – we aren’t yet sure how to monetize the game, and I’m not sure that the mobile marketplace will guarantee us any revenue.  I’ve got a few tricks up my sleeve though… We’ll see if I can pull them off before launch!

We use a tool called Pivotal Tracker to help us organize our tasks and plan out when our launch date might hit.  I’ve decided to make this tool public — anyone can pop by and see what our progress is looking like.

Because this project is largely in Rafa’s hands now (and not my own personal thing), we’re mostly talking about it on the Radial Games Twitter Feed and Facebook Page.  Check us out there!

Oct 282013
 

A week or two back I posted about a bad experience I had with the Haxe community.  Judging from the reaction I got to that post on Facebook, Google Plus, and even just comments on that article, I think some clarification is in order.

First order of business: I was being unfair to a very helpful group.  I was angry at the time (as much as one can be at a minor code problem), and I went through the whole thing with a big chip on my shoulder.

431595_10151375880425374_839210373_23290711_1354205970_nOf course, a blog post is forever, and now my anger is a permanent fixture on the internet – a rusty iron statue forever casting a furrowed brow out upon the community.  Meanwhile, in real life, I was over it within the hour and have been a grinning and happy person ever since.

The #Haxe IRC channel (on Freenode) has been pretty much indispensable to me (I wouldn’t be able to get ANYTHING done without them), and often times when I ask about a bug in #OpenFL it gets fixed over lunch which is pretty much the best customer service ever.  My worst experience as a community member was someone explaining the issue to me, immediately, and giving me a work-around that would take a minor amount of effort on my part.

Of course, my reaction to that was “WHAT?! I HAVE TO DO MORE WORK?!?!” and immediately flipped the table over.  I mean, as an entitled middle class white male, how dare someone put an extra bit of work on my plate?!.  In short, I was a total dick!

I still stand by what I said as a valid “heat of the moment” kind of response, though I probably shouldn’t have immortalized it with a blog post.  If I were to do it over again, I would make a (calmer) broad statement about the stereotype of the “linux hacker” where a perfectly engineered solution is better than a human-readable one; the whole “RTFM” culture that pervades all technical communities. I did bump into that here, but it’s to be expected these days I guess.

And just how I rail against the “RTFM”-culture and dismissive behaviour in communities, I am also contributing in my own special way by bitching and moaning about it here in my blog, thus contributing to the negative stereotypes. Sorry about that.

#Haxe and #OpenFL are the most friendly, most responsive, most helpful technical community I’ve ever been a part of.  I’m trying to contribute back to the community, and once I elevate above newb status perhaps I can contribute something a bit more than this Vimeo tutorial did over the weekend.

Sure, the IRC channel can behave in ways that are slightly negative at times; I think we’d all behave differently if we were sharing a table at the pub. I think we can all strive to do better. But right now, I’d rather hang out in #Haxe than on reddit or (*disgusted face*) youtube comments.

A library you can use: IRL

 Code  Comments Off
Oct 162013
 

[Checkout IRL on GitHub]

There are plenty of libraries and frameworks out there to help you make your next big game, but many of them don’t work for me. They lack a critical feature, or they are bloated and contain too many unused features, or they require the instantiation of a meta “game” object that then gives you access to the juicy bits.  I don’t want these things! I just want that feature I need, and I want it in a cheap/simple package!

The closest I found to what I needed was FlashPunk, but it didn’t quite fit my workflow.  So I started writing my own library – just a folder full of helper utilities that I use in just about every single game I’ve ever made – from prototypes to jam games to full on commercial products.  In this folder I dumped code borrowed from other developers and other software projects, and the occasional optimized function from a random StackOverflow thread.

Over the years this folder expanded and contracted like an accordion, trying to find that perfect balance between generic usability without being so specific as to tie into a particular project.  I ported this folder of utilities to four different languages, the most recent of which is Haxe.

I’ve been developing in Haxe and OpenFL for over a year now, and I think sharing this folder of utilities might be a way to share my experience with other Haxe developers that are just starting out… So here it is.  A library you can actually use IRL (It’s called “IRL” because I’m clever and it’s a totally good name for reals).

It’s nothing spectacular, there’s no amazing super long functions hyper optimized for blitting on 4D devices in here. But have you ever wanted a really simple GreyBox to help you prototype? Done.  Or how about a simple-to-use save-game class? Or a wrapper for google analytics? I’ve got you covered. I’ve even got a handy little function in there that just makes buttons “bubble up” when you put your mouse over them.

I’ve also got a few dozen other utilities I’m going to pop in there over the coming months, but they’ll take quite a bit more work to become public. Things like my Adobe AIR integrator for SteamWorks; that’ll be fun.

Of course, I’m a self-trained programmer without a good head on my shoulders when it comes to design patterns or advanced features like macros. I usually lean towards solutions that just get things done rather than doing it right, but I’m hoping that – via forks or pull requests – we can work together as a community to make Haxe and OpenFL a bit more fun to code games in, and give us a little bit less to worry about.  Maybe I’ll even learn a thing or two from you guys and end up a better programmer because of this.

Cheers!

Oct 152013
 

I recently started writing Word Wings in Haxe and bumped into a little “gotcha” that I wanted to report on, in case others bump into the same thing.

Haxe defaults Float values to NaN in Flash targets, but defaults to in native targets.

I’ve been developing in Haxe for over a year now, and felt like I had a pretty good handle on it.  Monster Loves you was written entirely in it, largely headache-free, but I did stick with the Flash target for that particular game — and using NME (now OpenFL) prepped me to expect NaN in many cases. Large reams of my code look for NaN as a signal to initialize (or re-initialize things).

Imagine my surprise, then, when I compiled to a native target for the first time and started seeing weird errors cropping up. My tweens don’t execute properly. My screenshake algorithm instantly terminates. Nothing that crashes my game; just little behavioural differences that come out of Floats being initialized as as a default.  Because there was no error message, it took me quite a while to track this down.

“No problem,” I thought. “I’ll just declare all these variables as NaN! Problem solved!”

var myFloat:Float = Math.NaN;

“HAHAHAHA,” says Haxe. “NICE TRY!!! You can’t initialize Floats as NaN up there in the declaration, like you would a number value! You have to start writing your own initialization functions!! HAhahaha you’re such a chump!”

Fuck you, haxe! Fuck you!

To be fair, this behaviour is documented, and is one of the few examples of Haxe actually documenting something well (here’s a counterpoint).  Of course, knowing this behaviour would take place requires that you read the documentation otherwise you’d not be able to figure it out.  It’s not like I saw my tweens not firing and thought “oh man I should google Haxe’s float initialization documentation,” and I definitely don’t sit down and read an entire API before I start coding.  Even if I did read the documentation, I probably would have skimmed the section on “what is a Float” and “what is an Int” as I think I know everything. (It turns out I do not.)

Of course, when I was trying to figure out a solution to this problem in the #haxe IRC channel I was told I was simply “doing it wrong” and that it was all my fault for not RTFM. Gotta love the super friendly support network Haxe has.  (I was asking about ways to override Float’s default value, and instead of saying if it was possible or not, they wanted to know why I would do such a thing.  Then I was chastised for not already having my own initialization functions.)

Still, it’s frustrating that a language that touts itself as “write once, deploy everywhere” would do this.  It feels more like “write once, but only correctly and in this special way, deploy everywhere.”  I understand the reasons they describe in the documentation for this behaviour, and sure I can agree with it too.  It might in fact be the best way to do things.  But it is still a gotcha, it’s still buried in the documentation, and it’s not expected behaviour for a noob like me; it leads to a bad user experience, and should probably change from a human point of view.

From an engineering point of view, where everyone is an expert and reads the manual, and initializes all their variables every time? Perfect.

(I still am in love with Haxe, despite the flaws. I just want to make sure I document this for future explorers.)

EDIT: And it turns out Neko targets initialize floats to null and not NaN, hooray! Three different targets!

EDIT2: I probably laid some unfair bashing on the #Haxe community in this article, and this edit just got way too long so I turned it into it’s own post.

Oct 022013
 

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.

Ghoost Caat

(Ghoost Caat is my mascot of things 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:

Capture

Oct 012013
 

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.

As of this writing, 3.9 is in pre-release and available through the Adobe Labs website.

Apr 082013
 

I’m trying to test the viability of Monster Loves You! on the new iPad, and I’m running into a bit of a gotcha. Any advice would be appreciated.

(I’m use Haxe+NME and Adobe AIR)

The high resolution of the new iPad means that the background art takes a half second to load for each image (and there are about 40 or 50 of them). This puts a very visible “chunk” into the gameplay, which I work around by pre-loading all the backdrops at load time. Which takes quite a while and takes up a horde of memory, but it works. Still, fetching the image from memory makes a (now smaller) but still noticeable delay.

Worse, pre-loading all the images requires more memory than the iPad 2 has, and it crashes on load right at the start. So I’m stuck with the individual-loading delay no matter what here.

I’m terrified of even glancing sideways at the original iPad.

Is there an easy way to get large (2048×1536) images from the Haxe Asset Library to display onscreen super quickly that I’m overlooking?

Dec 282012
 

This is a meta-post about this blog and game development. Bear with me for a few minutes. It’s in disguise:

===

Sometimes life is a constant stream of discoveries and surprises; revelations brought on by the self are some of my most cherished.  To me, living is about exploration.

That may explain why I insist on making all of my own mistakes and re-inventing the wheel over and over again. It can be a flaw!  It may even produce some stubborn opinions about things, but as long as I’m having fun, I don’t mind.

But sometimes (well, okay, frequently,) I lack the expertise to even start questioning myself, to know if I’ve made a mistake. I lack the ability to make a decision for myself, or draw a conclusion. The internet can be a good resource, but sometimes data is sorely lacking. Here’s some examples I thought of in the shower this morning, questions I cannot answer (and suspect I may never be able to convince myself of, in my lifetime):

  • When doing the “Plank” exercise, why is it always carried out on the elbow and not on the extended arm? If it’s about hip-distance-from-floor, can I use an extended arm and just put a cardboard box under me? If it’s about angle on the ankles, can I just put the ankles up on the cardboard box?
  • Ever since I received (as a teenager) my very own Gillette Mach 3 razor – I’ve never cut myself shaving. Is this a property of the razor? Or is it that my skill reached a certain point and the razor type is incidental?
  • Do the three blades of the Mach3 actually matter? I used to swear by it, but I don’t actually remember what I used before that. The other day I bought a 50-cent double-blade disposable from a corner store and it seemed to cut just as good as my Mach3 back home. What’s up with that?
  • When going for weight loss, people often recommend eating a full 3 meals a day (or, preferably, 5 smaller meals throughout the day). How much of that is game theory? How much of that is people trying to bake healthy-eating stuff in but is otherwise ineffectual to weight loss itself? For example: If I skip breakfast every day for the next 5 years, that is sample A. If I eat breakfast every day for the next 5 years, that is sample B. If nothing else changes (theoretical, big if), will “B” actually lose more weight?! I find this unbelievable, yet experts say it is true. Are they counting on increased energy levels and activity levels that result from breakfast? If so, why don’t they just say so?!
  • Who says 5 is the best number of meals for a day? What if I have 6 slightly smaller meals throughout the day? 7 slightly smaller than that? Someone, somewhere, probably made a call on how many meals was “too annoying to bother with.” What was their math based on? What is the actual underlying formula? Is best case actually to eat a single pea from a pod every other minute in the day?
  • How many glasses of water per day should I have for my current (sedentary, high-humidity) lifestyle? I mean, aside from the stuff I get from food (like a bowl of soup shouldn’t count towards a glass of water).

I don’t think I’ll ever be able to answer these myself because they are benign, low-interest, and generic enough that not many people really care. Most of it is about body and diet, and scouring the library, the internet, or even “professionals” (like the trainers at the gym I go to) will just respond with rote responses they learned, without understanding the underlying reasons. Arguing about razors and how much they cut is like asking a room full of people about opinions. Where are my facts?!?!

I just want to find out the truth behind these, so I can start asking follow-up questions and living a more fulfilling life. For that, I need an expert.

I need someone that knows their stuff. Someone that can answer all the hows and whys of those questions. Someone that can unveil the (often boring) reasons behind all those decision. Someone that has the balls to say to my face that, yes, the 5-glasses-of-water-per-day number was a completely made up statistic with no backing to it, but it can’t be bad for you, so I should just do it anyway. Someone that can say, with confidence, accuracy, and supporting articles, that it’s bullshit.

Or maybe it isn’t bullshit?

I can’t know. And it’ll drive me crazy!

===

And this is why I post so many intimate details here on my blog.  Why I post my contract terms, my Y-axis, my personal life and how I deal with it (and how that correlates with game dev), and all sorts of other information: I may not be an expert, but some of the things I’ve posted to this here blog are unique on the internet: for those categories, I’m the best you will (publicly) get.

By posting my data, I get comments, private emails, and lots of feedback. Sometimes my assumptions are corrected, sometimes my statements are backed up. I learn new things. People more talented than myself flock to my blog to point out my mistakes (THANK YOU!!), and those less talented flock to my blog to learn from my mistakes (I LOVE YOU!!!!). People on equal footing are just sharing in this awesome experience of life (YOU ARE AMAZING!!!). This is why my target audience here is other game developers, not the fans of my games.

This blog is my opportunity to help other people out, and learn myself. I’m frustrated that some questions can’t be answered directly by any professional, and questions asked on how to code certain things properly in forums are usually responded to with a shovel full of opinions.

When I find the answers, in this one tiny niche that I call my field of expertise, I post it publicly. So that everybody else can know the answer too. Some may say this is silly (if I keep my secrets, I can be hired as an expert!).  I disagree; speaking my mind about silly bugs and flaws and holes in various languages has landed me more job offers than any resume I’ve ever written, and more than my stupid LinkedIn profile. Never mind all the new friends I’ve found here! (*waves to followers happily*)

So I hope you enjoy it, getting some details you might not see elsewhere. I hope you learn something, or help me to learn something. I hope you love this blog as much as I like writing it.

Now I just have to find an expert on the human body that is willing to swap notes with me…

Dec 032012
 

Ugh.

I’ve been banging my head against the wall for 4 days now, trying to get SteamWorks integration into Monster Loves You. Long story short, the SteamWorks API is only available in C++; someone made an unofficial SWC/ANE in AS3 that helps link it up; I’m trying to import that into Haxe; it only runs wrapped in an Adobe AIR runtime.

I feel like some kind of evil wizard, trying to smash together Haxe, AS3, a C++ Library, and AIR. Noxious fumes arise from my boiling cauldron.

I’ve almost got it all working now, and thanks to some help in IRC and such, but now I’m stuck. Maybe someone out there can help?

Here’s the library I’m trying to use.

I’ve unzipped the .SWF from the .SWC file and have it code-completing in FlashDevelop, and compiling without error. Code is executing.

In one of the .SWF classes, there is an Adobe AIR function call; the app no longer works unless I wrap it in Adobe AIR (ADL.exe works great for this). Haxe/NME doesn’t include AIR references, but I worked around that by using Jan Flanders “Air3″ haxelib. That hurdle overcome.

Line 24 of this class, though, throws a null error.

Line 23 is the AIR call to instantiate the extension. This function returns null if it’s unable to find the reference to the extension in the AIR XML. “Oh,” I think. “I know this one! If I add:


[extensionID]com.amanitadesign.steam.FRESteamWorks[/extensionID]

to my application.xml, it should work!” (brackets changed for HTML sanity) So add it I did. But this is where my problem lies: upon execution AIR attempts to import all the listed extensions and include them in the binary. This is an unnecessary step, since Haxe already compiled the library into the .SWF. If I don’t list the extension, I get the null error listed above. If I include the extension, I get this error when ADL tries to run:

Error: The extension com.amanitadesign.steam.FRESteamWorks has either a namespac
e version or library.swf with a version that is incompatible with the applicatio
ns namespace or root SWF.

So my question then is: Is it possible to get AIR to register an extensionID that is already included, and not attempt to include it itself?

- or –

Is it possible for Haxe to externally include the .SWF (not internally) so AIR can grab it and do it’s thing?

- or –

Am I making some grievous error that is making this more complicated than it should be?

I’ll owe you a beer if you can help.

Sep 072012
 

For some background on one of my latest games, D.U.C.K., I’ll have to tell a personal story. And it’s going to sound a bit like bragging, but bear with me.

THE JOB OFFER

Last November, a “dream job” caught my attention.  A new (only 1 published game) casual game company in California was looking for someone to rapidly prototype quick gameplay mechanics – hopefully a new one per day, on average – and just keep cranking them out. Basically do a game-jam every day, with just grey-boxes and no presentation or polish necessary.

It was the company’s intention to get a nice catalogue of gameplay mechanics, pick out the best ones, and hand them to another team to brush up and insert as mini-games into their larger casual titles (for both launch and game updates down the road).

Wow. For a guy like me, that was perfect. I dislike working with content-reliant games; I tend to focus on pure mechanics and quick 5-minute gameplay experiences.  I think of polish and art as necessary chores for success; and none of that was required here.  I think one of my greatest strengths is my rapid delivery style; the drawbacks for such (unusable code, for example) don’t count against a job posting like this (where the mechanic will just be rewritten anyway).

Imagine that: Spend a few hours hammering out a quick silly fun game… and hang up your hat, call it a day, and move on. I could make a game a day for an entire year (minus weekends and holidays) and not have to worry about paying rent?! Fantastic!

THE INTERVIEW

I seriously considered giving everything up for this job.  Moving to California, halting Radial Games, cancelling any outstanding projects… It was very promising.  I was flown in on two occasions for interviews, and the salary offered was triple any amount I’ve ever made before (not that indie development is a rockstar job). They even picked me up from the airport in a limo. A limo with free wi-fi on board.

Part of the interview process was a test. You know, one designed to show off your chops, both for game design fundamentals, technical proficiency, source code legibility, and speed of development.  To make things [arguably] a bit easier, they provided a theme of “classic video game with a new spin,” and a time limit of 1 day of development (and up to 6 days of preparation).  The game being fun, marketable, or casual were not requirements at all;  just the ability to execute.

I hung up the phone at 5PM, with an expectation to deliver the game the same time next week.

Sounds like a challenge.

THE GAME

I started off with Duck Hunt as a theme, and thought back to those old typing-tutor games I used to like so much. Why not smash the two together? The idea flew off the top of my head pretty danged quickly.

I figured if I was working at this company, I’d need to execute on ideas in a day. I know the standard of “8 hour shifts” include copious amounts of goofing off and cat videos, but I know personally that I can get three or four solid, uninterrupted work hours in a day. So I set that as my personal goal: finish this game in 3 hours. I started a log file.

5:45PM: Thinking
5:50PM: Began setting up environment, generating API keys for stat tracking, etc.
6:00PM: Began Art Asset generation, OFFICIAL START TIME
6:25PM: Finished all intended art. Begin Code!
6:40PM: Basic mechanic implemented (not fun yet)
7:11PM: First fun playable build (#47). Taking a break to fix weird preloader error in the IE8 + Flash 10.0
7:48PM: That particular combination doesn’t like classic programatic debug-mode detection. Developed workaround.
8:10PM: Caught edge cases, changed scoring and added score threats. Not just fun, but a challenge now. (#61)
8:17PM: Added countdown timer.
8:25PM: Added end state and fixed keyboard focus issues.
8:32PM: High scores implemented; sending game out for playtesting (#73)
9:09PM: Added some basic bird animations and waving grass.
9:20PM: Build 108 final build created, incorporates minor fixes and edge cases.
9:30PM: Official Deadline (not counting 30 minute preloader error)

Blammo. I had created D.U.C.K. You can play it by clicking here. Shoot each wave of ducks down by typing the letter card they are holding. Bonus points for juggling a single duck multiple times; big penalties for mis-typing! Perfection is the only way to win!

PLAY HERESOURCE HERE

It’s a basic idea of a mechanic that can be fleshed out into it’s own full-blown game, if there were any interest in that. It’s fun-enough and polished-enough to the point where it’s easy to see where it can possibly go, and where it’s potential failings are.  This game is worth a whole lot more than a design document for a similar game, and was probably executed faster than that design doc could have been written.

But it’s not just a grey-boxed mechanic. Take a look at that development log again. It includes asset creation, play-testing (yay twitter!), bug fixing and multi-browser compliancy tests, in-game metric linkages (highscores are recorded on the back-end; not publicly displayed yet), and even some bonus parallax grass waving in the foreground, just for some visual flair. And all of this in just 3 hours work.

THE GREATEST RESUME

People often ask me how to “break into” the games industry.  My standard response is to make your games your resume. Not many companies actually care about your education (I have no academic degrees!) or your years of experience; the most important thing is what you’ve created so far.

In this situation, I had created a game that said I could do exactly what the job required of me, and then some. I could go above and beyond. And better yet, I have a history of a dozen games under my belt that do the same – all those jam games are not worthless.

WHAT ABOUT THE JOB?

I had taken a long hard look at the situation. I really wanted the money, and really didn’t want to move. I wanted to be released of my indie responsibilities, but not have a boss.  I was very much flip-flopping on the whole job offer, and had to go renegotiate a few times for more concessions in my favour. But still, this was a casual game company. Their primary focus was a style of games I didn’t agree with or enjoy. I wasn’t sure I was willing to sell my soul for any price.

In the end, I decided not to take the job, and continue on my own special indie career. All the same, the company was snatched up by Zynga a few months later, and I would have lost all my potential indie cred then.

I AM NOT SPECIAL

I know this has sounded a whole lot like bragging so far, but here’s the thing: I’m not very good at this ultra-fast-game-dev-thing. I’m just one of the few that tries. Everybody else I know that takes my 5-minute game challenge makes better, more interesting games – faster than I can imagine possible. I’ve seen 48-hour game jam games that absolutely blow me away, being made at my own local game jams, by people I’ve never met before.

I’ll bet that nearly all the game designers/engineers out there reading this blog could do better than friggin’ D.U.C.K. if they set aside just 3 hours of time tonight. So why not give it a try? It might land you that dream job… or it might set you off on an indie development career. Go to game jams. Take the Ludum Dare challenges.  MAKE SOME GAMES.