Firstborn is looking for a senior Flash/AS3 developer, of all things

Posted by Zeh Fernando on 21/February/2014 at 11:28

Just as a heads up, Firstborn is looking for a senior-level AS3 developer for our NY offices. You can find more information about this position here.

We’re still saying to ourselves “I can’t believe we’re looking for a Flash developer”. Truth be told, while Firstborn has established its reputation for visual interface acuity in the heydays of Flash-based websites, the bulk of our target platforms now are HTML and (native) mobile.

When you look at problems in a framework-agnostic way, however, Flash still solves some challenges in a faster and better way than the alternatives. With that said, we’re hiring for a very specific project, and one I’m very excited about; it is a “sister” project to the one I’m currently working on. It’s a commercial thing (not a game), but still one interesting interface and a chance to work on a product-like project.

If you’re interested, please contact us. If you know someone who might be, please forward them the link.

As a side note, this is a full time position for our NY offices. Due to the way this is deployed and tested (it is not a web project), and because it is supposed to take a while, it cannot be a freelance or remote gig.

KeyActionBinder is growing up

Posted by Zeh Fernando on 14/February/2014 at 0:14

After a lot of breaking things, refactoring, and testing, I’ve finally merged the experimental branch of KeyActionBinder into the main branch of the project. The biggest change, of course, is making the functionality of this gamepad support library more automatic, in the sense that it tries to detect whatever game device the user has connected and map its inputs accordingly, so game developers don’t have to care about writing hundreds of lines of code to have their games work when doing cross-platform (or even single-platform) development in AS3 and Adobe AIR.

On top of that, I’ve also started doing a lot more of mapping work (using the test interface I mentioned earlier) and adding them to KeyActionBinder’s new separate list, which is now just a long JSON meant to be easily edited. This is what the library supports right now:

  • Windows 7
    • XBox 360 controller
    • PlayStation 4 DS4
    • NeoFlex (generic Gamepad)
  • OUYA
    • Native controller
    • XBox 360 controller
    • Playstation 3 DS3
    • Playstation 4 DS4
  • OSX
    • Playstation 3 DS3 (standard plugin version)
    • Playstation 3 DS3 (standard plugin version)

However, several other developers started contributing to the project, and I have a long list of mapping that I will be adding soon (I have to adapt them to a new format I’m using in the JSON file).

Syntax-wise, it hasn’t changed much. Usage is like so:

// Initialize (first frame of SWF)
KeyActionBinder.init(stage);

// Create an instance somewhere
binder = new KeyActionBinder();

// During startup, add as many bindings as you want, using your own action ids
binder.addKeyboardActionBinding("move-left", Keyboard.LEFT);
binder.addKeyboardActionBinding("move-right", Keyboard.RIGHT);
binder.addGamepadActionBinding("jump", Keyboard.SPACE);
binder.addGamepadActionBinding("move-left", GamepadControls.DPAD_LEFT);
binder.addGamepadActionBinding("move-right", GamepadControls.DPAD_RIGHT);
binder.addGamepadActionBinding("jump", GamepadControls.ACTION_DOWN);

// Finally, during the game loop, check the values
if (binder.isActionActivated("move-left")) {
    playerSpeedX = -1;
} else if (binder.isActionActivated("move-right")) {
    playerSpeedX = 1;
}
if (isPlayerOnTheGround && binder.isActionActivated("jump", 0.03)) {
    // Will only jump if activated in the last 0.03s
    // This prevents a player being able to press jump while in mid-air
    playerSpeedY = -1;
    // Consume action so it won't be true in next frame
    // This prevents a player from jumping continuously
    binder.consumeAction("jump");
}

There are other use cases, but that’s the basics. See the rest in the project page.

I started this project just as a support system for a game I’m developing in my free time, but considering the complexity of supporting several different devices and their own custom control inputs, it soon became obvious this had to be a more public effort – one that more people could help, and benefit from. I’m pretty excited it’s finally taking form! It still has a long way to go, but it’s quickly becoming a pretty solid solution, in my opinion.

A GameInput testing interface

Posted by Zeh Fernando on 8/January/2014 at 16:19

To build the list of known GameInput controls spreadsheet, I had to build a small sandbox-like application test for controls reported by connected devices. It was my intention to make this available to other people so they could do their own tests, so here it is: just wait for the following Flash movie to load (reload the page if it gets stuck), click on it, then use whatever connected game devices you have to test for input controls, their values, and their injected Keyboard events (if any). The values you see should be the same for both the web version of Flash Player, and Adobe AIR.

It’s a simple application, but it does its job: the first column will list the connected devices, their available controls (buttons and axis), and the state of each of those (including whether granular values were detected for analog buttons and axis). The middle column will show the state of pressed keyboard keys; this is useful when testing on Android and the OUYA. Finally, the third column will display a log of everything that has been pressed, in the sequence it happened; this helps detecting injected keys, especially on mobile versions of AIR.

The embedded version above is provided just as a demo; you can open it in a full page/tab here. An Android/OUYA AIR equivalent can be found here in the form of an APK that needs to be installed to your device (same with the OUYA). Also noticed that the source for the tester interface is available on GitHub; it is part of the KeyActionBinder library. It doesn’t really use the library, though, since it’s more of a debugging and development tool.

In defense of reinventing the wheel

Posted by Zeh Fernando on 5/November/2013 at 16:48

When I am programming something that requires a module or a sub-system of any kind, my first impulse is to always write it myself; sometimes, even rewriting things I had already written before. While there’s a danger in doing too much of this and avoiding well-established solutions to common problems – the syndrome of Not Invented Here is a thing – I have always justified this decision by rationalizing that I have a better understanding of tools I build from scratch than some mysterious library with unknown side-effects, and that it is more fun to do it myself anyway. Obviously, this is not a solution that should be used all the time, as sometimes the time spent building complex systems (say, a rigid body physics system) can easily outweigh the benefits, but it’s one I find myself doing time and time again, and feeling guilty doing so.

In reading Game Engine Architecture by Jason Gregory, however, I ran into the best rational defense of the practice I’ve seen so far. When talking about building custom container classes for certain data structures, the author gives the following reasons why game developers normally choose to do so:

  • Total control. You control the data structure’s memory requirements, the algorithms used, when and how memory is allocated, etc.
  • Opportunities for optimization. You can optimize your data structures and algorithms to take advantage of hardware features specific to the console(s) you are targeting; or fine-tune them for a particular application within your engine.
  • Customizability. You can provide custom algorithms not prevalent in third-party libraries like STL (for example, searching for the n most relevant elements in a container, instead of just the single most-relevant).
  • Elimination of external dependencies. Since you built the software yourself, you are not beholden to any other company or team to maintain it. If problems arise, they can be debugged and fixed immediately, rather than waiting until the next release of the library (which might not be until after you have shipped your game!)

I could not have said it better, and have to confess I felt a bit vindicated when reading it. It’s very often that I have to dig into a certain class to either add a missing feature, or to tweak something in an otherwise unorthodox way to provide some much-needed performance boost for a particular edge case. For good reasons, generalized solutions tend to go against that; and while tweakable, open-source solutions exist, nothing beats knowing the behaviors of a particular system inside and out because you built it.

Joel Spolsky talks a little bit about the subject in much a much better manner than what I’d be able to conjure, and comes up with an advice for software teams (as a short tenet, in true Joel Spolsky fashion):

If it’s a core business function — do it yourself, no matter what.

There’s an advantage in using stuff that has been tested by a big group of people, of course. I probably need to get better at using other people’s stuff. In the meantime, though, I’ll happily continue reinventing when I can. It’s more fun this way.

Playstation 4 Controller in Adobe AIR and Flash

Posted by Zeh Fernando on 29/October/2013 at 15:37

As expected, the new PS4 controller works out-of-the-box once connected to a Windows PC (using a USB cable) with no need for any special drivers. As such, it works seamlessly when using the GameInput API in Flash or Adobe AIR applications.

I have updated the spreadsheet of known GameInput controls with the appropriate control ids. However, this is how it works, in a nutshell:

  • The device is reported as “Wireless Controller”, with 24 controls
  • The left stick X axis is reported as “AXIS_0″, going from -1 (left) to 1 (right)
  • The left stick Y axis is reported as “AXIS_1″, going from -1 (down) to 1 (up)
  • The rick stick X axis is reported as “AXIS_2″, going from -1 (left) to 1 (right)
  • The right stick Y axis is reported as “AXIS_5″, going from -1 (down) to 1 (up)
  • Directional pad up, down, left, and right are reported as “BUTTON_6″, “BUTTON_7″, “BUTTON_8″, and “BUTTON_9″, respectively, and their value is either 0 or 1
  • Square is “BUTTON_10″, with value 0 or 1
  • Cross is “BUTTON_11″, with value 0 or 1
  • Circle is “BUTTON_12″, with value 0 or 1
  • Triangle is “BUTTON_13″, with value 0 or 1
  • L1 and R1 are “BUTTON_14″ and “BUTTON_15″, respectively, with a value of 0 or 1
  • L2 is reported as either “AXIS_3″ (analog, -1 to 1) or “BUTTON_16″ (digital, 0 or 1)
  • R2 is reported as either “AXIS_4″ (analog, -1 to 1) or “BUTTON_17″ (digital, 0 or 1)
  • L3 (left stick down) is “BUTTON_20″, and R3 (right stick down) is “BUTTON_21″, with a value of 0 or 1
  • The PS button is “BUTTON_22″, with value 0 or 1
  • The Share and Options buttons are “BUTTON_18″ and “BUTTON_19″, respectively, again with a value of 0 or 1
  • Clicks on the touch pad are reported as “BUTTON_23″, with a value of 0 or 1; no way to get the touch pad position, though

After so many years of ghetto solutions, it’s great to see this gamepad finally working “natively” in Windows. Even more so knowing it can easily be used in Flash content.

Big changes to KeyActionBinder: automatic game control ids, new repository

Posted by Zeh Fernando on 12/October/2013 at 12:10

When I set out to write a class to simplify game input control in ActionScript 3, I started from the assumption that Adobe AIR’s GameInput device control ids (the ids that relate to each button or axis) would be fairly consistent between platforms. The idea was that the class would just hide away the Keyboard and GameInput events needed for proper game input, and not try to do much else.

As it turns out, that assumption was a mistake. Now that more people are testing GameInput control, it has become obvious that control ids vary immensely between platforms, even for the same device (e.g. the XBox 360 Controller has completely different control ids triggered on Android, Windows, and Macs). The spreadsheet with all known game control ids is getting out of hand. In retrospect, I suppose this is to be expected – each platform will have its own device drivers, sometimes not necessarily maintained by the controller manufacturers.

In my original implementation of GameInput support for KeyActionBinder, I had decided to have all GameInput control ids listed in a separate class, and then it was up to developers to properly bind the correct controls based in which platform the code was being executed on.

While this works, it’s a very verbose approach and one that will probably have very little – if any – customization over time (e.g. “left stick” will always be treated as “left stick”, regardless of the platform). Over time, I came to believe that a more universal, automatic, cross-platform approach with control ids hidden away from the developer – the solution James Dean Palmer took with his own GameInput classes – is a better solution.

So in essence, something that looked like this:

// Setup bindings
if (isAndroid) {
	binder.addGamepadActionBinding("move-left", GamepadControls.OUYA_DPAD_LEFT);
} else if (isWindows) {
	binder.addGamepadActionBinding("move-left", GamepadControls.WINDOWS_DPAD_LEFT);
} else if (isMac) {
	binder.addGamepadActionBinding("move-left", GamepadControls.MAC_DPAD_LEFT);
}

Should look like this:

// Setup
binder.addGamepadActionBinding("move-left", GamepadControls.DPAD_LEFT);

Checking the actual actions (via isActionActivated(), etc) would remain unchanged.

This may sound like an obvious, sound solution. The hidden implication, however, is that the class has to discover which platform and device are being used behind the scenes and bind events with the correct control ids where appropriate. This is not as easy as it sounds (certainly not infallible), because it requires prior knowledge of all possible platforms and devices (rather than leaving it to the user to add arbitrary control ids) and some creative guessing based on device names and player “manufacturer”/OS strings. Needless to say, devices have to be individually “supported”; if a player tries to use a new, random device in your game, it wouldn’t work by default, because the class has no knowledge of it.

Still, this is the kind of solution that I think will only get better over time. In certain platforms (at least Android and Windows via XInput), game input is more or less universal, and as long as the device recognition code is lenient enough, it can probably work reasonably well even in rogue new devices.

This is a big change to the code, so on top of that I’m also doing some other changes to the class. Those include adding game pad index parameters when checking for action activations (for a more flexible easier multiplayer support), some automatic keyboard-to-GameInput bindings (to support weird keys such as START or HOME that get mapped to Keyboard.MENU or Keyboard.BACK) and re-mapping of some axis values for consistency (so developers don’t have to care about the direction of the Y-axis on their sticks).

This is still a work in progress, but a working version of that (sans some of the features mentioned above, and only supporting a few devices and platforms) is up on GitHub: I have a new repository just for KeyActionBinder (easier for forking). The main branch still contains the original version of KeyActionBinder, and the new one – with automatic mappings – are on the auto-controls branch. Check the list of changes done so far for more information.

I will be adding the rest of the devices and features to it over the next few days, and publish my web/Android GameInput test SWFs so it’s easier to add more devices to it, as well as a full log of all the changes. In the meantime, this post is just to let people know there’s a new version that’s worth trying.

Commenting JSON files

Posted by Zeh Fernando on 21/September/2013 at 18:58

I use a lot of XML files on my most of my projects (Flash, Android or otherwise). I like the idea of having some configurations parameter on easily editable text files, and not having to re-compile a project just to change a behavior slightly; where I can, instead, just edit a configuration file, re-run the application and see it behave in a different way.

Recently, I started moving most of my the static data on some applications I build – data that would normally be inside a XML file – to JSON files instead. JSON files are less verbose, and just easier to edit and parse. This seemed like a smart move, until I realized something: JSON files cannot have comments. In my infinite ignorance, I was just assuming JS comments were going to work.

Several workarounds exist (and were suggested on Twitter to me) but in my opinion none of them are ideal. I especially dislike creating new, bogus or redundant properties.

Instead, what I’ve come up with on my own work is simply pre-parsing the JSON files I work with to remove JS-like comments from it prior to decoding a String as a JSON object. This is not ideal – the file won’t be a valid JSON file – but I think it’s the least inelegant way to deal with the problem. That’s also what Douglas Crockford suggests, which is somewhat strange given he’s the one who made the decision to keep comments out of the standard (for a good reason, but still).

Anyway, since I always use my own AssetLibrary class to load and manage JSON files, I just had to add an easy String replacement prior to parsing the JSON file from the URLLoader data. The code is simple, and looks like this (paraphrased [paracoded?] to be more readable):

public function getAsJSON():Object {
	// Object after loading
	var loadingObject:URLLoader = ...

	// Get raw data as String
	var data:String = loadingObject.data as String;

	// Delete comments using RegExp
	data = replace(/\/\*.*?\*\//sg, "");

	// Finally, create and return JSON data
	return JSON.parse(data);
}

The above code is ActionScript 3, but the implementation is simple enough that it can probably be easily applied to other languages.

Public service announcement: full Game Developer Magazine archive available online

Posted by Zeh Fernando on 20/September/2013 at 12:36

Game Developer Magazine

The full archive for the Game Developer Magazine is now available for free on the GDC Vault in PDF format. This is an incredible (and sadly missed) magazine. I recommend any aspiring, hobbyist, or independent game developer peruse through this archive. It contains many insightful articles for all fields related to game development, from audio to graphics to programming to design to marketing to management.

Game Developer, an in-depth monthly magazine for exposing ‘the art and business of video games’, was published by UBM Tech (which also runs Game Developers Conference and Gamasutra.com) from 1994 to 2013. Following the magazine’s closure in July 2013, we’ve compiled an archive and made them freely available here for all to enjoy. (Also check out the Game Developer section on Gamasutra for some of the best reprinted articles from these issues.)

I previously wrote about how you should subscribe to this magazine. Unfortunately the magazine is now gone, but you can read everything that was published before.

Using Adobe Scout to profile OUYA games

Posted by Zeh Fernando on 18/September/2013 at 8:57

Adobe Scout is Adobe’s most excellent profiler for Flash (web and AIR) content. Although it’s a somewhat recent application, it has easily become my go-to tool for measuring and optimizing performance of Flash content. It’s truly an invaluable resource for doing things like detecting memory leaks and performance hiccups, and something that should be used by all kinds of ActionScript developers (although game developers will probably benefit the most from it).

Teaching anyone how to use Scout is out of the scope of this post; Thibault Imbert does that and more in this article anyway. What I’d like to share is the list of steps one needs to take to use Scout to profile content running on the OUYA. While this tool on pretty well support on Android, the steps are not as trivial on the microconsole. But I was curious about some information I could only get through the use of Scout (maximum GPU memory consumption), so I had to get it working soon. Here it goes.

  1. Install Adobe Scout (you may need Adobe Creative Cloud, and a Creative Cloud account).
  2. Download the installation file (APK) for the companion Android app for Scout. This is not as trivial as it sounds, since the OUYA doesn’t have access to Google Play and there’s no link to the APK file. You will probably need to download it to an standard Android device and “backup” it so the APK is stored somewhere accessible (more information here). Hopefully Adobe will make this available publicly in the future.
  3. Install the APK to your OUYA. If you have the Android SDK installed, you can connect your OUYA to your PC using a micro USB cable, get it to be recognized as a USB device, and use ADB to install the file using the command line (adb install -r filename.apk); if you don’t, you can host the file somewhere else on the web and point the OUYA browser to it. The former is recommended, however, since you also need it to be able to test OUYA games directly from your PC without much hassle.
  4. Run Adobe Scout on your machine.
  5. Run Adobe Scout on the OUYA (under the “Make” menu) and enter your PC IP (apparently it should list your computer automatically, although it didn’t happen to me). Your OUYA has to be on the same network as your computer. You will get a message stating whether it was able to connect or not, and the list of features it’ll profile (CPU, ActionScript, etc).
  6. Run your game normally from your PC with the OUYA as the target, as you would while testing/debugging. Be sure to have the telemetry option on for the compiler (--advanced-telemetry=true).
  7. Switch to the Scout window on your PC and you will see the data coming in. Strangely, it takes a while for the data to start streaming in (it is sent with some delay), but the information it contains seems to be accurate.

Here’s an example of an OUYA debugging session with Scout, an unoptimized version of my game prototype with an intentional GPU memory leak; you can see the memory usage increase triggered after 60 seconds:

Profiling the OUYA with Adobe Scout

Profiling the OUYA with Adobe Scout

To answer my original question: I was able to allocate 449,851 kilobytes of data on the OUYA’s GPU memory, as BGRA textures. This was done by testing in increments of 96kb, and I got the exact same number 3 times, so it’s probably fairly accurate. Ironically, it’s more than what my PC can do – I was only able to push it to 404mb.

Lastly, I had some bad luck running my game in debug mode – my game would crash sooner than expected while testing maximum memory usage. This is probably because of the added overhead; both debug mode and the telemetry switch debug execution performance, so be sure to compile a correct SWF before release, or to test a release version while doing Scout profiling (this is also recommended by the application itself).

Drawing super ellipse rounded corners in ActionScript 3

Posted by Zeh Fernando on 16/September/2013 at 18:34

Super ellipses. If you’re of the mathematical type, they are a geometric figure defined in the Cartesian coordinate system as the set of all points (x, y) with (x/a)ⁿ + (y/b)ⁿ = 1 where n, a and b are positive numbers. If you’re everyone else, they are those fancy rounded corners used in icons for iOS 7.

Regardless of your inclination, the fact is that corners rounded with that formula do look great – especially on a screen, I’d say – and as such, I decided to roll them into the standard rounded box drawing classes that I use in pretty much everything I build. Since it is a well know geometric figure, Wikipedia comes to the rescue as usual, so implementation is trivial. This is a comparison of the result:

Superellipse example

In my case, the implementation just tries to mimic Flash’s own drawing APIs. So in my RoundedBox class, I normally had this:

graphics.drawRoundRectComplex(0, 0, _width, _height, _topLeftRadius, _topRightRadius, _bottomLeftRadius, _bottomRightRadius);

But I now have this:

drawRoundRectSuperEllipse(graphics, 0, 0, _width, _height, _topLeftRadius, _topRightRadius, _bottomLeftRadius, _bottomRightRadius);

Your mileage will vary depending on how you implement rounded corners. However, the equation is easy enough to allow it to be applied on every kind of case with relative ease. The code is fairly simple too, so I would assume it’d be easy to adapt it to other languages, especially JavaScript (using the Canvas drawing API).

This is the actual implementation of the function (well, functions):

private function drawRoundRectSuperEllipse(__target:Graphics, __x:Number, __y:Number, __width:Number, __height:Number, __topLeftRadius:Number, __topRightRadius:Number, __bottomLeftRadius:Number, __bottomRightRadius:Number):void {
	// Draws a normal rectangle, but with "super ellipse" corners
	// https://en.wikipedia.org/wiki/Superellipse

	// TL
	if (__topLeftRadius <= 0) {
		graphics.moveTo(__x, __y);
	} else {
		drawSuperEllipseCurve(__target, __x + __topLeftRadius, __y + __topLeftRadius, __topLeftRadius, __topLeftRadius, 180, 270, true);
	}

	// TR
	if (__topRightRadius <= 0) {
		graphics.lineTo(__x + __width, __y);
	} else {
		drawSuperEllipseCurve(__target, __x + __width - __topRightRadius, __y + __topRightRadius, __topRightRadius, __topRightRadius, 270, 360);
	}

	// BR
	if (__bottomRightRadius <= 0) {
		graphics.lineTo(__x + __width, __y + __height);
	} else {
		drawSuperEllipseCurve(__target, __x + __width - __bottomRightRadius, __y + __height - __bottomRightRadius, __bottomRightRadius, __bottomRightRadius, 0, 90);
	}

	// BL
	if (__bottomLeftRadius <= 0) {
		graphics.lineTo(__x, __y + __height);
	} else {
		drawSuperEllipseCurve(__target, __x + __bottomLeftRadius, __y + __height - __bottomLeftRadius, __bottomLeftRadius, __bottomLeftRadius, 90, 180);
	}
}

private function drawSuperEllipseCurve(__target:Graphics, __cx:Number, __cy:Number, __xRadius:Number, __yRadius:Number, __startAngleDegrees:Number, __endAngleDegrees:Number, __moveFirst:Boolean = false):void {
	// Draw a "super ellipse" curve
	// https://en.wikipedia.org/wiki/Superellipse

	const SEGMENT_SIZE:Number = 2; // In degrees.. more = more precise but may be slower if done repeatedly

	// Enforce always min->max
	while (__endAngleDegrees < __startAngleDegrees) __endAngleDegrees += 360;

	var p:Point;
	for (var angleDegrees:Number = __startAngleDegrees; angleDegrees < __endAngleDegrees; angleDegrees += SEGMENT_SIZE) {
		p = getSuperEllipsePointOnCurve(__cx, __cy, angleDegrees, __xRadius, __yRadius);
		if (angleDegrees == __startAngleDegrees && __moveFirst) {
			__target.moveTo(p.x, p.y);
		} else {
			__target.lineTo(p.x, p.y);
		}
	}
	// Last point
	p = getSuperEllipsePointOnCurve(__cx, __cy, __endAngleDegrees, __xRadius, __yRadius);
	__target.lineTo(p.x, p.y);

	return;
}

private function getSuperEllipsePointOnCurve(__cx:Number, __cy:Number, __angleDegrees:Number, __xRadius:Number, __yRadius:Number):Point {
	const N:Number = 5; // The n of the curve; 4 according to wikipedia, 5 for a stronger corner
	var cn:Number = 2 / N;
	var angle:Number = __angleDegrees / 180 * Math.PI;
	var ca:Number = Math.cos(angle);
	var sa:Number = Math.sin(angle);
	return new Point(
		Math.pow(Math.abs(ca), cn) * __xRadius * (ca < 0 ? -1 : 1) + __cx,
		Math.pow(Math.abs(sa), cn) * __yRadius * (sa < 0 ? -1 : 1) + __cy
	);
}

One last note: in my own code, I multiply the radius of every corner by 2 before drawing each corner, just so the super-ellipse corner looks roughly the same size as the original corner. The above code omits this tweak, but it’s something I’d really recommend if you just plan on replacing corner drawing functions with this curve.