This is the Postmortem blog post for Starcom.
- Game Design
- Art & Sound
- Distribution & Monetization
- Initial Reception
Starcom is a single-player Flash game where the player commands a starship from a top-down perspective exploring the galaxy and fighting off an encroaching enemy invasion force.
This was the second Flash game I ever wrote and was an extraordinarily ambitious project. I conservatively estimate the game took 500 hours to make, including coding, game design, artwork, sound and playtesting.
I wrote this postmortem document to help me recognize what I did right and what mistakes I could avoid if and when I decide to do a sequel.
My original conception of Starcom was based on an old DOS game I played as a teenager called “Starflight.” In Starflight, you command a starship in a Star Trek-like universe, meeting and battling aliens, exploring planets, and collecting cool stuff and artifacts. It was a remarkably detailed universe given the fact that it fit on a couple of 5 1/4” floppy disks.
At the same time, I had been watching the new Battlestar Galactica series. I wanted to capture some of the intensity of the epic space battles in the game.
In a space-based game, players expect the universe to be far more open than in, say, a dungeon. In a dungeon it is perfectly natural to have to explore one level before moving onto the next, and so forth, in a linear fashion.
I originally didn’t want the game to be linear. I wanted the player to be able to explore a vast Galaxy of generated systems looking for cool stuff. I even had a random system generator. But playtesters complained about the lack of direction. With no storyline, they felt no compulsion to keep playing. Or even any hint that there was cool stuff for them to see and acquire in distant systems. This is probably why there are so few non-linear single-player games. So I abandoned the idea of an open universe in favor of a mostly linear plot.
In space, constraining player movement is difficult. The first mission of Starcom forces the player to learn the basics before acquiring the Nexus Navigator and leaving the Star System. But I was forced to use a number of contrivances to keep the player moving through the story in a linear fashion. The main trick was having new Warp Nexii appear only after the player has completed certain missions.
A lot of players have requested a bigger universe to explore. Perhaps in a sequel I will try to incorporate more freedom to go “off map” while still providing some direction for a linear narrative.
The question “How should a spaceship control in a top-down video game?” is surprisingly tricky. Most Flash games restrict movement to the screen and use a cardinal movement system, i.e., you push right and your ship moves right on the screen, which wouldn’t work well at all for this game. The first version of Starcom used a control scheme very similar to this one, but where your direction of movement was always in the direction your ship faced. Easier to control, but playtesters found it too “car-like”. I tried various momentum conservation techniques (including no “space resistance,” which while physically more accurate wasn’t as intuitive) before settling on the version in the game now.
A related issue that I hadn’t foreseen was the problem of speed. Players want to go fast. It feels more exciting and it allows you to move between objectives quickly. The problem is, the view port is 500 pixels wide with your ship in the center. You have 250 pixels between you and the edge of the screen. If you’re moving fast and the enemy is heading straight toward you, he may have passed you before you’ve had time to react.
Speaking of speed, how do you let players know that they’re moving at all? Realistically, of course, you don’t. But that’s no fun. So you have to provide reference points to show movement. Other ships work well, as do celestial bodies, but if none of those are on screen, you need something to “feel” the movement. A scrolling background doesn’t work well in space (I tried it using a star field). Expanding on a technique I saw in another game where there were three layers of stars moving at different speeds, I used a random scattering of stars with different alpha values, which were shifted as the player moved by an amount proportional to their alpha, so faint stars moved more slowly and appeared farther away.
Given post-release feedback, there were still a significant number of players who weren’t happy with the handling of the ship. A possible solution for a sequel would be to give players a choice of ships, each of which handles differently, and perhaps has different capabilities increasing replayability.
In addition, I should have offered players the option of configuring their keyboard controls. The default control scheme works well for right handers, but some of the keys are poorly positioned for left handers (e.g., Turbo Thrust and Jump).
Probably the second biggest complaint after “this game is too short” was the lack of a good map of the universe. Players found it too easy to get lost. I initially planned on adding a star map, but this feature was never fully implemented. Definitely if a sequel is going to be larger, than a good mapping system will be essential.
Likewise, players couldn’t remember which Nexus went where. The game should have had some way of letting players know where a Nexus they’ve already entered leads to.
To be written…
The inventory system was re-written from scratch once, but it’s still something I’m not happy with. Inventory items were sort of a tacked-on feature. Part of the problem was that conceptually, I imagined all game items (things that could be picked-up, bought and added to the ship) could be handled more or less the same way, with subclasses handling special cases. It turned out to be a lot more complicated than that.
Here are some issues that arose with my various attempts at an inventory/item management system:
- How should inventory manager be laid out visually? There’s a lot of information to display: what items the player has installed, what items the player has in cargo, items in Starbase, the item description, its sell price, the actions that can be taken on the item, any stats, any stat modifiers, etc.
- Many items modify the behavior of other items. For example, a yield maximizer changes the performance of the missile weapon system. There are lots of different cases here. Where is this information stored? When displaying stats on an item, should its modifiers be displayed as well? What about when the item isn’t installed? Or even bought?
- How are unidentified items handled?
- Does every item in the game have a unique identifier?
- Can there be multiple instances of the same item, or should every item have a unique identifier?
- How do you represent “where” an item is? E.g., installed on the player ship, in the player’s cargo, in the Starbase store, floating around in space somewhere, or in some abstract enemy treasure trove waiting to “drop”.
Inventory management is an issue that is likely to be more complicated in a sequel and I’ll need to have a much better plan for handling it if I don’t want it to be headache.
Balancing the various weapons and armaments was more or less an exercise in trial-and-error that I don’t think came out that well. The Havoc system is underpowered and shields charge so slowly that players found little use in upgrading them.
I think it is only the short length of the game that kept players from complaining about component upgrade disparities.
In a sequel, I’ll need a better system for measuring the relative value of each upgrade.
A Flash game is a game that can be run by Adobe’s Flash Player. It’s interpreted (not compiled) so it isn’t nearly as fast as a native application. On the other hand, Flash is ubiquitous, and more importantly, a Flash game doesn’t require any additional downloads. If someone goes to a web page with your game on it, they can play it as soon as it finishes loading.
This is the number one reason to develop a game in Flash– you can get massive exposure very easily, and consequently lots of feedback. If you develop a stand-alone download game, unless it’s a hit you probably won’t get very many plays. Maybe a few hundred, including friends. So you won’t get a lot of feedback. Without feedback, you can’t learn what you’re doing right and what you’re doing wrong. Which makes it harder to develop a hit game.
But there are problems with developing in Flash. One of which is monetization, which I’ll discuss later. Some of the technical limitations:
- If you’re making a Flash game, you probably want to have it distributed to portals. Which means it should be 700×500 pixels or smaller. That’s a lower resolution than Diablo II.
- Flash runs much slower than native code, even slower than Java (which is interpreted byte code). You can’t do all the fancy graphics that standalone games from five years ago did. Flash also can’t use video card acceleration. (This might be a good thing, since video card capabilities vary wildly, and if developers started writing Flash games assuming GPU acceleration, a lot of people would see Flash games that ran like a slide show.)
- Flash games are expected to be casual, quick loading affairs. 1-3MB is typical. Starcom is a bit hefty. It’s 3 MB without any music. All three music tracks add up 5MB. Since 8MB is way too big for a Flash game, I embedded only the first track. There are triggers in game that tell the game to download additional tracks when required, so they don’t slow down the game load time.
How do you develop a Flash game? Flash games are written in some version of Actionscript. I’m only familiar with the latest version, AS3. And what do you use to write and compile Actionscript?
One option is to use Flash, Adobe’s design tool. Lots of people go this route, especially people coming from a design background. Personally, I don’t think it’s a good method. Flash may be great for designing “movieclips” (timeline based animations), but it’s a terrible coding environment. The movie metaphor doesn’t map well to organizing code. If you’re coming from a programming background like me, you may be lost as to where to put your code and classes.
A second option is to make what is called a “pure Actionscript” application. You can do this using a third party IDE like FlashDevelop, using either Flash or the Flex SDK to compile. You could theoretically write all your AS in notepad.
A third option is to use Flex. What is Flex? That’s a little confusing. Flex Builder is the name of Adobe’s development tool, which can be used with or without the “Flex.” Flex is a collection of components and a markup language called “MXML” designed to make creating Rich Internet Applications easier. Because Flex contains a lot of great UI tools, such as lists, layout containers, dialog boxes, etc., I decided to try to use Flex for Starcom’s UI.
I should mention first that Flex pre-compiles MXML into Actionscript. So if you’re using MXML, you still are doing everything in AS3, but there’s an additional layer of abstraction on top where you set up the application layout and components.
It turns out that this layer of abstraction can be confusing. I wasted a huge chunk of time trying to understand the nuances of Flex components.
For example, normally when you create an object in Actionscript, you call the class’s constructor and get an object back, ready to roll. With Flex components, you get an object back, but it may not be completely ready to use. Flex uses something called “deferred instantiation” where complex components are assembled and laid out during free CPU cycles. Maybe it’s ready right away, maybe in a little while. So you need to attach an event listener for when the object is really ready.
This is a minor inconvenience, but more importantly, creates scenarios that are very unpredictable. In a game, it’s not uncommon to be using the CPU heavily most of the time. One bug I spent several days working on was the mission update dialog box, which informs players about various in game events. The dialog is non-modal, meaning the game play continues while it’s on screen. Sometimes this dialog would show up instantly, sometimes after a few seconds, and sometimes wouldn’t show up at all until the game was paused. The reason, I eventually surmised, was that Flash wasn’t giving it enough priority. “This is a deferred instantiation object. It’s not critical. I’ll finish it later.” Flash was procrastinating like a programmer. Since in an action game it’s always crunch time, the object often never got finished. (Incidentally, in Flex Builder you can suspend execution of an application while in debug mode to investigate what all the objects are up to. Theoretically, nothing executes while the application is suspended. Bizarrely, I discovered that if I put a trace statement in one of these missing dialogs, it would report that it finished building sometime after the game was suspended.)
I’m not sure if I would recommend using Flex for game development. It is very nice to be able to layout the UI like a web page and customize pre-built components to cover the various interfaces. But I don’t think I’m alone in my difficulty to understand the vagaries of Flex’s layout system.
Overall I’m happy with how I chose to structure the code. In any large project there are inevitably going to be code decisions you regret down the road, but Starcom didn’t turn out to be a disorganized mess of hacks. There was one ground-up re-write a few weeks after I started working on it, and a few small re-factorings.
Starcom’s Overall Architecture:
- The main entry point into a Flex application is an MXML component that subclasses the mx:Application component (unlike an Actionscript application where the main entry point is a subclass of Sprite). So Starcom’s main application class is a light-weight component that handles the preloader, site lock detection, opening the game menu dialog and adding a game window component.
- The game window component is what you spend most of the game looking at. It consists of a ViewPort object (the top down view of space and your space ship), a ScannerView object (the mini-map/radar), a console list object (the status of various key ship components) and some menu controls.
- A game is loaded from XML, either the default “new game xml” or the xml from a previously saved game (see below for the implications of using this system).
- The game object is a container for everything in the game. I made a concerted effort to keep this class from growing too large, but functionality did have a tendency to find its way in there.
- When the game was playing, the game’s enterFrame handler executes the following major actions:
- Clear the particle layer (a single bitmap layer where particle effects such as sparks and explosions are drawn)
- Call the update method on the player entity, which handles not only moving the ship, but updating all components such as weapons, shields, jump charge, etc.
- Tells the map to update entities near the player. (See comments on the map class below)
- Updates particles
- Fade the “smoke” layer using a combination of blurFilter & colorTransform.
- When a player first enters a star system, a map object is created that represents the two dimensional space. This map is partitioned into a grid of nodes, which help with both broad phase collision detection (deciding if two objects can interact) and allowing the game to only update entities near the player. This meant that a star system could have a very large number of enemies and objects without dragging the game to a crawl.
- In-game help, missions and achievements are handled with an action/trigger system:
- A trigger manager maintains a list of active triggers. Every frame, each trigger’s isMet() method is called. If it returns true, each of the triggers’ action objects’ execute() method is called.
- A trigger can look at any of the public properties of the game object, including sub-objects like the map, the player’s inventory, etc. This allowed great flexibility in what triggers I created.
- A downside of this system is that every active trigger needed to be called every frame to see if it’s met. Since the isMet condition was generally a fairly simple boolean, this didn’t impact performance too much.
While I say I was happy with the game architecture, there are always improvements that can be made and if I rewrite the engine I’d like to correct some of these mistakes.
I made the classic beginner object oriented mistake of overusing inheritance. For example, the basic game entity has only the properties that all game entities share, such as position, radius, owner, velocity, etc. A slightly more complex entity, called a physical entity allows for collision detection (there’s overhead for maintaining an entity’s map node, so I didn’t want unhittable objects burdened with this feature). While another entity is the projectile, a non-physical entity that has properties and methods for dealing damage. Then came the missile entity– a projectile that could be shot down. AS3 doesn’t support multiple inheritance, so I had an awkward situation where I created a physical entity for the missile itself then a projectile entity representing the warhead to deliver damage.
Instead, I should have either used composition or interfaces to keep the game entity tree small.
Most Flash games have fairly anemic save & load functionality, if they implement it at all. Often, they simply store the last level you completed.
Starcom needed a real save system, since players were exploring a large and interconnected universe while modifying their ship. The game needed to save what map they were on, their ships position, what equipment they add, which enemies had been killed, which missions they had and had not completed, etc. At the same time, I didn’t want to save everything, such as the position of every bullet and particle active.
My solution was to only allow the player to save in one location (Starbase) and save the complete game initialization xml– everything necessary to initialize the state of the game universe.
This worked well, but suffered the following drawbacks:
- Players complained about only being able to save at Starbase. While the engine could theoretically save anywhere, I was worried about the testing nightmare if they could save willy-nilly.
- Since a save captured the entire game initialization xml, if I made a change to the master game xml, it wouldn’t be reflected in a save. So I couldn’t easily modify the game once it was released.
- Probably the biggest problem though was in testing. The game xml evolves as the player plays the game. The only way I could reliably test whether some change to a mission worked was to replay the game from the beginning. This wasted a colossal amount of time as I would make a minor fix, play for twenty minutes only to discover the fix didn’t take because Flex missed the change in XML.
I’m not an artist but I am somewhat of a perfectionist. When working on Starcom I often found myself unable to continue working on a feature until I was happy with the asset that representing it. I estimated that I spent at least as much time working on various art & sound assets as I did on coding. I lost huge amounts of time working on various ship assets in Photoshop, despite the fact that there are only about a dozen different craft in the game.
If I do a sequel I either need to hire an artist to create the ships, or learn to use a 3D modeling tool to create ships.
One visual aspect of the game I really liked were the various planets. While they serve no in-game purpose other than landmarks, they provide a great sense of atmosphere. I think the game would have been a lot duller if every star system looked the same.
I only rendered about a half-dozen unique planets, but created the illusion of many more by modifying the size and colors.
A lot of the particle effects, particularly the explosions, were pre-rendered in Wondertouch’s ParticleIllusion. ParticleIllusion creates some very realistic particle effects (particularly of the pyrotechnic variety) for use in film and games. I rendered them out to bitmaps, then used ImageMagick to stitch them into a “film-strip” bitmap, then scaled them in Photoshop. Once they were imported into the application, they were “blitted” to the particle layer for a high-quality bitmap animation without a lot of CPU expense.
Additionally, sparks were added to the screen to provide some more visual oomph. These are single pixels drawn to the particle layer. The pixels were stored in objects that tracked their position, velocity and fade.
One major success of the game was the soundtrack. It was provided free of charge by Justin Durban. Originally written for his Kings and Kingdoms project, he graciously allowed me to use of the tracks in the game. Quite a few players loved the epic atmosphere.
The only problem with the sound track is that as MP3 sound, it’s quite large. The three tracks combined are larger than the rest of the game put together. Large file sizes are double-whammy. Not only do players not want to wait for the download, but there’s a bandwidth cost as well if you host your own game.
To mitigate the download time, I embedded only the first track used. The other two tracks are loaded later as needed. This made the game loader faster and reduced the total bandwidth cost, since not everyone who started playing played until the end.
Here’s a problem I imagine most independent game developers have. How do you find unbiased playtesters for your game? Friends and family are great, but they may be reluctant to give negative criticism, or may be outside your target demographic.
Flash Game License has an interesting service where you can buy first impressions. For one dollar you can have an anonymous user play your game and write a review.
The downside of this service is a) you have no idea if the anonymous user chosen is anywhere near your target market and b) they only are required to play for a minimum of 5 minutes.
For a casual game this may be fine, but it doesn’t help you find big problems late in the game.
Once Starcom was released on Kongregate, early players identified several bugs and gameplay problems that were missed:
- There were some bugs in the save system that led to corrupted save data.
- There was a bug that prevented the Prometheus mission from registering as complete if a player left the star system before finishing it.
- The anti-climactic ending was a disappointment for a lot of players.
To be written…
Starcom went public on Kongregate.com on June 10th, 2009. On its first full day on Kongregate, it was played 68,000 times from 35,000 distinct IP addresses (a play being counted when a user created a new game from the in-game menu or loaded an existing game, so users who visited the page but did not play weren’t counted). After a few early bugs were fixed, the initial reception was excellent with the game ranking 3rd for the week with a score of 4.1 out of 5, the top 1% of Kongregate games.
Jayisgames gave the game a fantastic review shortly after it appeared.
After Starcom dropped off the new releases on Kongregate, the number of gameplays fell off dramatically to about 3000 plays per day.
On June 17th, I uploaded the game to Newgrounds.com, one of the premier Flash portals on the web. I imagined that starting out of the gate without of any of the bugs from the initial Kongregate release would cause it to be well received and looked forward to shooting to near the top.
I was surprised when it came out of the initial “under review” phase with a score of 3.6 out of 5. Not horrible, but a disappointment. After a few hundred more scores, it had slid further to about 3.5.
Clearly, something about the game bothered a large number of Newgrounds users enough to vote it down. Something that didn’t bother Kongregate users. But it’s the same game, apart from API, there’s no difference. Looking at the written comments on Newgrounds offers no clue– everyone who wrote a comment loved it.
I still have no idea what happened. The demographics between the two sites are a little different, but not that different. My current best guess is that Starcom was sponsored by Kongregate.com and features the Kongregate logo prominently. Is it possible that Newgrounds users feel a sense of brand loyalty and voted the game down because of the Kong logo? Or possibly that Kongregate users, upon seeing the Kong logo, decided to vote it up? It seems unlikely, but I have no other explanation.
To be written…