There’s an irritating bug in Flash where the up state of a SimpleButton briefly appears when the button is clicked, causing a bad-looking flicker effect and making the button look broken.
I’ve been plagued with this bug since 2010. There has never been a fix for it, and very few people on the web have mentioned it (I can only find references here and here). Those people didn’t find a solution either.
The only way I was ever able to get around it was by compiling projects in the Flash IDE (ugh) instead of with the Flash Builder/Flex compiler. Ugh. I could only assume that outside of the Flash IDE’s library, the SimpleButton code was broken.
Actually, no. Turns out that compiling in Flash Builder is no more broken than compiling with the IDE, and the bug only shows up in the debug Flash Player. Even in the Flash IDE, a test with ctrl-shift-enter (debug) instead of ctrl-enter (regular) will show the bug. In other words, it’s not actually a problem.
When I come across an issue like this with no answers, I feel some responsibility to write about it on the web to help out other lost Googlers.
I’m mainly posting this here because I’ll need it again one day and might forget what it’s called!
Icaros. It replaces Window’s built-in video thumbnail generator with one based on FFmpeg and not relying on any external codecs. It’s useful for instantly adding FLV thumbnail generation to Windows, and has the really good feature of being able to specify from which part of the video (in percentages) the thumbnail is generated from; so no more useless black thumbnails generated from the fade-in at the start of a clip.
Fixed-point arithmetic was a common way of approximating real numbers in computers when floating point units weren’t present in consumer PCs. For example, Doom uses 32-bit integers with 16-bit integer and 16-bit fractional parts, to ensure that it would run on 386 computers. Even today, many embedded devices don’t include FPUs so that they can save power, and fixed-point arithmetic is used internally.
Are fixed-point numbers a sensible choice for optimising Flash games? No.
Is there any use for them at all in Flash? Yes! Determinism.
Because every operation is performed on integers where the result is well-defined and identical on all architectures, it’s easy to be sure that a result using fixed-point numbers will be the same on any computer. This isn’t possible with floating point, where even running your compiler in debug mode can leave you with different results. It’s just not possible to use the Number data type in Flash and expect it to run on all computers identically.
Why is determinism useful?
- It means we can run logic locally and it will match any other machine it’s running on. Multiplayer games now only need to synchronise input changes across the network, instead of the full state of the game.
- Recording gameplay can also be stored as a sequence of timestamped inputs, instead of game state. Without determinism, the recorded gameplay would play back differently on different machines, or even Flash versions.
- Logic can be ported to other environments and run identically. Playing back a player’s inputs in a C# server-side program is now possible, as the same result is generated.
Unfortunately it’s not easy to implement fixed-point arithmetic in Flash. We have a 32-bit integer type, but no 64-bit type. We need that larger type for overflowing operations, else we’re essentially limited to multiplications and divisions in the 16-bit range (an example format would mean an integer part ranging from [-128, 127] and a fractional part with a granularity of 1/255. Not great!). I wanted 16:16 fixed-point numbers, anything else was too small to work with in any useful way.
My first attempt involved doing bitwise multiplications and divisions manually over an array containing the bits of an emulated 64-bit type. I knew this would be slow, but had hoped it might at least be usable. It wasn’t. Loops that took 1 millisecond with Number took 5.5 seconds with this fixed-point type. Unusable.
Would writing the fixed point code in C, compiling it with Adobe’s FlasCC Flash C compiler as a SWC library work? Would that 64-bit data type, (internally emulated or not) magically turn out to work quickly through the magic of LLVM-targeted code with undocumented Flash opcodes? Amazingly, yes!
Operating on a simple Flash int with the following simple C functions provides 16:16 fixed-point multiplication and division operations:
int32_t fixedPoint16Mult(int32_t a, int32_t b)
return (int32_t)((int64_t)(a) * (int64_t)(b) >> 16);
int32_t fixedPoint16Div(int32_t a, int32_t b)
return (int32_t)(((int64_t)(a) << 16) / b);
just works, and at a reasonable speed too. Despite the overhead of function calls over the Flash->LLVM interface, the fixed-point code runs around five times slower than native arithmetic with Number. Not perfect, but certainly usable! 10,000 divisions clocks in at around 5 milliseconds of execution time in debug mode on my ageing, budget laptop. Game-worthy performance. The same code drops-in to a .NET-based server program and gives numerically identical results after a million divisions and multiplications. Spot-on determinism!
I've included an example of an oversampling Mandelbrot-set renderer implemented entirely with integers using fixed-point arithmetic, to show that this can be used for serious number-crunching:
This trick makes keyboard handling much, much easier. It’s not Flash-specific, but it is particularly helpful in Flash.
When you’re developing a keyboard system for games in AS3, the first problem is converting the interface you’re given for reading the keyboard into something suitable for games.
We have a key down event, and a key up event. That’s no use. An event-driven keyboard system is useful for GUI software where you run a function when a key is pressed, but games need to poll for the keyboard state. They need to know whether the key is held down at any point in time.
Look at what happens when we just react to keyboard events:
(Use WASD or arrow keys to move and jump)
The character only moves when the keyboard event fires, which includes key repeat. Horrible! Keyboard events don’t work for games without a little abstraction.
Store a flag for the key when the KEY_DOWN event is fired, and clear the flag when KEY_UP is fired. It’s a simple problem, and common sense suggests that you should encapsulate this behaviour for all keys by creating a class that maintains a table of key up/down states.
With this method, you can poll keys with an “isDown” function and find out the key status at any time. It’s as if we’re not working with an event model at all, and everything feels smooth and good:
(Use WASD or arrow keys to move and jump)
Problem 1 is something any Flash developer using keyboard input for their games will have encountered and solved. But there’s an issue with this solution: what happens when you need to do a double-jump by tapping the jump button twice in quick succession?
The solution to problem 1 is no use here, because we can only poll if the key is down. We don’t know if it has been released and pressed again since the initial keypress that caused the jump. In this one case, the event model is more suitable, but implementing that alongside the polling method will only lead to confusion and bugs. There’s another obvious solution that sounds fine at first, but is also inadvisable.
So you know it’s a brand new keypress if you poll the key since the initial jump and find that it has been up since the last jump, right? And with that knowledge, any positives must signify a brand new press.
Great, but we can’t poll instantly and constantly. The player might release and press the key very quickly before we even get a chance to read the key state and notice that it’s happened. Not a good solution.
Stamp each keypress with a number. Whenever the key is pressed, store a number that identifies the keypress as unique, and use that number in your jump logic. So we keep polling keys, but instead of a simple “true” to signify that the key is down, we get a positive, increasing number that is set at the point the KEY_DOWN event is generated. The double jump logic now only needs to check that the jump key is down, and that its stamped number is higher than the previous jump.
(Use WASD or arrow keys to move and jump)
Bingo! Simple logic and an elegant solution to a fundamental problem.
Note: Don’t use an actual timer like getTimer() to stamp the keypress, as it’s possible that the player will have pressed the key multiple times for each timer value. Instead, a simple counter that increases each time a KEY_DOWN event occurs is good enough.
I’ve attached a simple AS3 keyboard class to this post that you can use in your own projects. The constructor expects you to pass stage. The method isPressed(keyCode) will return -1 for no press, or a positive timestamp when the key is down. isAnyPressed will do the same, but for an array of keys (useful if an action has multiple keys assigned to it).
The game help demonstrate the technical properties of the new revision of their Cayman series of cars.
My role was lead programmer/technical lead for the games part of the site, with lots of game design chats with producer Garry Samett.
The games are fully responsive, highly compatible HTML5, and work well on desktop and mobile devices. Wheee.
Released 28th March 2013.
A zombie game from the programmer who promised he’d never make a zombie game (formally the programmer who promised he would never make a Geometry Wars game).
It’s a mini-game with the production values of a larger game. Go play it!
Released 18th December 2012.