The day is finally here – Kickstarter Beta backer and Alpha tester keys will be going out early tomorrow morning (November 25, 2014).

The Steam Early Access page is up and the game will go on sale when keys go out. I’ll get a steam widget up on the front page some time soon.

Thank you again to all the Kickstarter backers, the alpha testers, Peter, Colin, Rob, Christine, Eddie, and everyone else who contributed to this release.

This is just the beginning! I’m excited to see all the new spaceships everyone is going to build, and I’m excited to get tons of feedback from the new influx of beta testers and get back to work. Please direct suggestions and bug reports to the forum!

Note on Linux Support

I wasn’t able to get Linux Steam integration ready in time for the deadline. The game already runs on Linux and some of our Alpha testers run the Linux version – I expect that it should be ready on Steam within a week or two.

Beta Progress

It’s been about a month since the last update and we are well on our way to Beta release!

Async Multiplayer

Screen Shot 2014-11-20 at 11.05.39 PM

wormhole (perlin noise!)

After flying into a wormhole, players can now upload their current fleet to the server. These fleets will be downloaded from the server and injected into newly generated worlds. Players can conquer their way across each world, defeating other player fleets, and then fly thorough a wormhole into a new world. Injected fleets will stick together, get in fights with ambient ships, and generally behave like the player’s own fleet.

Server authentication works either via steam or by reusing the Anisoptera Games Forum login info. This is essentially to prevent players from impersonating each other and so we can keep track of which fleets each player uploaded. Login is only necessary for uploading fleets.

There is still a lot to do with respect to notifications and organization. Eventually we want to allow players to track statistics from their uploaded fleets – how many players did it kill? How many people fought against it? There should be a way to browse uploaded fleets, maybe upvote especially cool ship designs, and so on. We are also considering some form of steamworks integration.

Tutorials and Introduction

We were able to playtest the newly improved beginning of the game through our showcase at the MIX at GDC Next just last week and found that people were able to start playing the game without instruction much more effectively than at PAX Prime the month before that. In several instances players asked me a question, only to have it immediately answered by an in game tutorial prompt. There is still work to do in this area but I’m confided that Beta testers will have a good first impression.

Steam Integration

steam logo

steam logo courtesy of Eddie Peters

The folks at Valve have done an excellent job making the steamworks integration process as painless and straightforward as possible The steam overlay, for example, required a grand total of one line of code to enable. Beyond setting up the store page and uploading builds, we have also added support for the steam cloud so that saved games will be seamlessly transitioned between computers. As part of this work we enabled gzip compression on the (plaintext) save file format, making save files much more compact (previous alpha builds could generate hundreds of megabytes of persistent data as the world was explored).

Other Changes

gaussian blur on pause screen

sweet gaussian blur on pause screen

Beyond these main items and fixing lots of bugs we also found time to do some graphics improvements. There are new snazzier shader effects for resource blobs. The gpu-based particle system was modified to use GL_POINTS instead of triangles, making it both faster and prettier, and the inter-menu gaussian blur effect was greatly improved. The same blur shader is now applied at a much lower setting to add bloom to weapon and particle effects. These effects can all be disabled on low end systems.

There is also a new box on the devlog page to the right (just below the twitter widget) showing recent source code commits.

Reassembly Beta Plan

The Reassembly BETA is scheduled for release this November. The goal is to have the overall structure of the game in place at this point, then spend the time between beta and release polishing and adding content. I wanted to outline the major features that will go into that.

In general the gamedev process (at least for me) involves iteratively looking at the game and then trying to change it in a way that makes it better. There is a lot of trial and error and it is hard to plan too far into the future. We got Kickstarted though, and the backers deserve to know how we intend to use the resources they so graciously provided us with. This is what I plan to work on for the next month. These items will continue to be developed through the beta period, but this month will be dedicated to laying the foundation.

  1. Asynchronous multiplayer
  2. Tutorials and introduction
  3. Steam Integration

Asynchronous Multiplayer

The basic idea is that spaceships you create will show up under AI control in other people’s game worlds and vice versa. The intention is twofold: first to do something really meaningful with player creations and secondly to provide more content than I could possibly design myself. This sort of feature is often called “User Generated Content” but I think “Async Multiplayer” is more appropriate for Reassembly because the content creation (spaceship design) phase is an integral part of the gameplay itself.

Functionally, this is a “glue” feature that requires moving data around without disruptively changing the game code. In the first iteration players will upload their fleet by flying into a wormhole. Opposing fleets will pop out of wormholes and engage the player and surrounding AI ships. We will track statistics so you can see how the alternate dimension versions of your fleet are fairing. The server will automatically validate and sort fleet uploads. Since the world is already procedurally generated and fully serializable none of this requires new technology.

The unit of ship interchange is going to be the “fleet” – a group of ~5-10 ships designed by the same person with a unified color scheme and design sensibility. Players naturally design and fly a range of different ships as they play the game, trying out new weapons and gradually increasing their point cap, and a fleet of mixed ship types is interesting to fight against and makes sense in the game world.

I am really excited about this feature. Seeing players design new spaceships that I would never have imagined has been really fun for me, and having them all come together in a world is going to be awesome. We saw during the tournaments that there is not a single best spaceship design and many different strategies are competitive. The ship sharing feature should create a feedback loop that keeps the game fresh and interesting for a long time.

Tutorials and Introduction

Reassembly is a complex game and introducing new players of all skill levels gracefully continues to be something we work on. We want to be respectful of player’s time and intelligence, providing guidance where confusion and frustration would otherwise result but without being patronizing. The paying beta players that will soon descend on the game should have as good of an initial experience as possible.

Steam Integration

The goal is to do the Beta release through Steam Early Access. This will let us take advantage of the updating, crash reporting, cloud saving, etc. functionality built into Steam. This will save us a lot of work in the long run but it will take at least a week to integrate the steamworks API and set up the storefront page.


These features should keep me busy for the next month. There are also several features that are planned for final release but will be added in the beta period: new block types, gamepad support, improved AI, more polished graphics, etc, etc. The great thing about an open beta is that we will be able to respond to player feedback and improve the game. Feedback from alpha testers has been integral to getting the game to where it is today.

PAX Prime 2014 Postmortem

Submissions for PAX East 2014 are opening soon so I thought I would write up my experiences showing Reassembly at PAX Prime in the Indie MEGABOOTH Minibooth last month. The MEGABOOTH was a very positive experience for us – in addition to having a great time we launched a kickstarter campaign the day we got back and successfully raised $35,000 to finish the game.


I (Arthur) wrote Reassembly and run Anisoptera Games. I’ve been working on Reassembly full time for about a year and a half, before that I worked at Nvidia. Peter Brown composed music and sound effects for Reassembly. Colin, Rob, and Christine from Indie Voyage ran the kickstarter and are helping out with PR, marketing, QA, and production. We shared a hotel with my friend Greg Batha who was showing Bit Bit Blocks at the Minibooth. All of us have been to gamedev conferences before but this was the first time exhibiting for any of us.



Peter demos the game at our booth

Willy Chyr has written a really good overview of the Minibooth setup which I will not duplicate.

In preparation, Colin and Christine hand emailed approximately 200 journalists and youtubers resulting in ten interviews during the show. The Indie MEGABOOTH provided a press list which was invaluable here. We had a number of impromptu interviews as well, possibly as a result of this outreach. We also organized a press dinner with demos for several more people.

We designed and printed official game t-shirts for ourselves as well as postcards to give out. Having never done this before we followed the guide at Indie Boothcraft. I also recommend Indie Hangover’s five part guide to getting the most out of a convention and Andy Moore’s guide to PAX on a budget (Also his latest game ROCKETSROCKETSROCKETS is really really good).

Cost breakdown

The table below details our booth costs excluding travel, lodging, and meals (which cost us about $3000). All told team members spent about $5000. The Indie MEGABOOTH provided the kiosk itself, placard, computer/monitor/keyboard/mouse, and 3 exhibitor passes. Colin had an additional 4 day expo pass through speaking at PAX Dev.

We also brought a pair of headphones.

Item Cost
Indie Minibooth $1400 for 4 days
T-shirts $400 for 12 (nice) shirts
Postcards $216 for 2500 postcards
Fliers $0 for 10,000 fliers (via cross promotion with Indie Hangover)
Press Dinner ~$120 in Pizza and Beer
Water, Granola bars ~$30

We gave out approximately 95% of the postcards and about half the fliers. It’s hard to measure how many people actually visited our website as a result of this, but we assume it was some. It was convenient to have something to hand people interested in the game.

Reassembly was miraculously nearly bug free throughout the expo. The game is written in C++, is multithreaded, and is still in an alpha state so embarrassing crashes were something I was very worried about. Right off the bat we had a flickering problem with the Adaptive VSync implementation in the game and had to do a new build to turn it off. Luckily I had brought my laptop and this took only five minutes. We did have a couple hard crashes and general gameplay bugs but by and large our bug fixing paid off and everything went smoothly. The machines provided by Indie MEGABOOTH were extremely fast and we had no performance problems whatsoever.

We had 5 people working to make our booth a success: Arthur (me, developer), Peter (composer), Colin and Christine (Indie Voyage), and Yoonah (Arthur’s wife). Manning the booth turned out to be extremely exhausting even with this many people and having the ability to take breaks was essential. Talking to hundreds of players was also very dehydrating – we went through two 24 packs of water bottles (and a number of red bulls). Through some combination of sleep deprivation, overexertion, and constant contact with large numbers of people I also ended up contracting the “PAX Plague” and spent the last two days sniffling. All that said it was very exhilaration – PAX is full of amazing things and we were all glad to get a chance to enjoy the rest of the show.


Exhibiting at PAX was extremely valuable for us, both personally and for our fledgling business. The legitimacy and publicity that being a part of the MEGABOOTH brought and the contacts we made with press and other developers were instrumental to the success of our Kickstarter and will continue to be greatly valuable.

For me (Arthur) personally, having spent more than a year writing a video game in a very solitary way, the chance to show it to hundreds of people in person was extremely rewarding. Being able to talk to other MEGABOOTH developers from around the world on approximately even footing was just amazing and inspiring. I shared a kiosk with Samantha Kalman showing Sentris and Paul Greasly showing A Fistful of Gun and they were both extremely welcoming, friendly, and interesting. Two different fellow r/gamedev screenshot saturday’rs came to the booth to say hi. Part of the Minibooth package included invitations to a number of parties with free food, alcohol, and the chance to informally network with other developers and with representatives from Valve, Sony, etc. It is hard to overstate how much work five minutes of talking to the right person can save. I have been to GDC and related parties a number of times but being part of the show was a completely different experience.

On the show floor, explaining the game succinctly over and over again and watching people’s reactions completely changed how I though about the game myself. Many things I thought of as core features turned out to be irreverent or too complex to explain, and things I thought of as trivialities turned out to be very significant to people. It is very easy to completely loose perspective on a project and showing it to new people is the solution. Every single person at PAX was positive and helpful – people who aren’t interested in your game will simply play one of the thousands of other games.

The tutorial we had built into the game turned out to be almost completely useless in the distracting context of the expo floor, and the progression rate at the beginning of the game was too slow for new players to experience the breadth of the game in the short time they had available to play. We ended up loading players into a mid-game save game and walking them through the controls in person. We lost the chance to playtest that first critical part, but have a much better idea of how to fix the tutorial and teach players to play.

I had read about Alexander Bruce (Antichamber) and other’s experience playtesting their games at conventions and was excited to try this out with Reassembly. Reassembly is a very sandboxy game though – there aren’t specific parts of the game that are trying to elicit specific emotions from the player. Rather it’s an interesting world that generates open ended circumstances that you can interact with on a variety of levels. I learned a lot about the UI – this is awkward, this is confusing, this is intuitive. Many people shared suggestions about the game, new types of weapons or armor, strategies for procedurally generating spaceships. I got a much better idea of what kinds of people are interested in the game and why (lots of software engineers, for some reason…). Overall it was more of a mind-expanding experience than a focused playtest.


Arthur and Peter on the official PAX twitch stream

We were selected to appear on the official PAX twitch stream for a ten minute interview on the third day of the show. This was quite an experience and I was frankly terrified beforehand. When I started working on Reassembly it did not occur to me that “being on tv” would be part of the process. Luckily our host, Justin Flynn, turned out to be extremely charismatic and Christopher Floyd from the MEGABOOTH team offered some perfectly targeted words of encouragement. Having spent two full days explaining the game to people, we were vastly better prepared than before PAX and it went smoothly.

Stay tuned for a Part 2 discussing our Kickstarter.

This one macro trick for easy data definitions

Commonly cited advantages of dynamic languages like Javascript or Python over C/C++ are the ability to easily mix data definitions with code in source files and to introspect classes and other code structures as if they were data. Standard C++ syntax also often requires duplicate and otherwise annoyingly verbose syntax when declaring many similar objects.

Thankfully, as with many other problems, we can overcome these limitations by creatively using the C preprocessor. Contrary to prevailing C++ doctrine, I believe that cpp macros can be the most concise, easy to understand, and high performance way to solve certain problems. With a little functional macro programming we can define reflective structs and enums with zero overhead.

Let’s say we are writing a game about building spaceships out of blocks. We have a class to represent the persistent data for each block, and we want to be able to serialize and deserialize that class, but we also read the fields of this class a gazillion times each frame and need them to be normal struct members – we can’t use a hash table or something instead. We also add or remove members frequently and don’t want to have to change the code in six places every time we do this. Here is a simple way to accomplish this.

(Note: This is simplified code from Reassembly – I hate iostreams and am not actually using them in Reassembly but for the sake of exposition it was the simplest way.)

#define SERIAL_BLOCK_FIELDS(F)                                   \
    F(uint,              ident,                   0)             \
    F(float2,            offset,                  float2(0.f))   \
    F(float,             angle,                   0.f)           \
    F(uchar,             blockshape,              0)             \
    F(uchar,             blockscale,              1)             \
    F(FeatureEnum,       features,                0)             \

    if ((NAME) != (DEFAULT)) os << #NAME << "=" << NAME << ",";

struct SerialBlock {
    std::ostream& operator<<(std::ostream &os)
        os << "{";
        os << "}";
        return os;

That’s it. Now we can add and remove block fields without having to update the serialization routine. We can manipulate the struct fields any way we want by writing new macros and passing them into the field declaration macro. Useful examples include parsing, resetting fields to default, operator==, or listing struct fields for purposes of tab completion.

Another useful application is reflective enums/bitfields.

#define BLOCK_FEATURES(F)                         \
    F(COMMAND,        uint64(1)<<0)             \
    F(THRUSTER,       uint64(1)<<1)             \
    F(GENERATOR,      uint64(1)<<2)             \
    F(TURRET,         uint64(1)<<3)             \

#define SERIAL_TO_ENUM(X, V) X=V,

At the risk of pissing off both the Effective C++ crowd and the hardcore C crowd I will introduce an elaboration using templates and the visitor design pattern for better generality. We define a function called getField(object, name) that returns the value of a reflective struct field given by name. We can use the same technique to parse/serialize arbitrary structs, list members, generate UI for editing structs, etc.

The actual game code for this is on my github repo, together with some convenient macros for defining reflective structs and enums.

    vis.visit(#NAME, (NAME), TYPE(DEFAULT)) &&

struct SerialBlock {
    template <typename V>
    bool accept(V& vis)

template <typename T>
struct GetFieldVisitor {
    T*           value;
    const string field;

    GetFieldVisitor(const char* name) : value(), field(name) {}

    bool visit(const char* name, T& val, const T& def=T())
        if (name != field)
            return true;
        value = &val;
        return false;

    template <typename U>
    bool visit(const char* name, U& val, const U& def=U())
        return true;

// get a reference to a field in OBJ named FIELD (the same as getattr in Python).
// will crash if field does not exist or type is slightly wrong
// use like getField(block, "angle")
template <typename T>
U& getField(T& obj, const char* field)
    GetFieldVisitor<U> vs(field);
    return *vs.value;

Reassembly Standalone Ship Builder

The standalone ship builder is a self contained version of the complete spaceship editor component from the full game. It comes packaged with a few tracks from the full soundtrack and all the ships from the last two tournaments to try out and test your creations against.

To enter the tournament, just upload your creations to the Tournament Ship Submission Page. Everyone is welcome!
Complete rules and discussion on the forum post.

Don’t forget to back our Kickstarter!

Ship Contest!

As some of you may know we held a ship design contest where the goal is to design a ship that can fight against other player’s ships in an asynchronous AI controlled multiplayer battle.

We had a lot of great submissions from alpha testers and we are running the actual contest live on twitch in about 20 minutes.

You can see it live here:

We will post a recorded version on Youtube later and edit the link in.


The competition is complete! There were some dramatically close battles and unexpected upsets, everyone learned a lot about building ships, and we have a list of AI behaviors to improve! Thanks everyone for submitting ships and tuning in. We will be posting the results and recording soon.

The Crusier category finals were postponed due to technical difficulties – we will finish running them soon!

Here are screenshots showing some of the entrants. Protohara Probe Mk. 2 narrowly defeated Protohara Drone in the Probe category (both Protohara proton beam’d the rest of the probes without difficulty), while Ontos very narrowly defeated BATTLEDEATH in the Dreadnought category after several changes in position.

Screen Shot 2014-08-25 at 7.16.54 PM

Screen Shot 2014-08-25 at 8.04.41 PM

Indie Megabooth / PAX Prime

We are excited to announce that we will be showing off Reassembly at the Indie Megabooth at PAX Prime at the end of August, just a few weeks away! We will be at kiosk 19 of the Minibooth section – if you will be at the convention come say hi, try out the game, and grab some fliers.

Reassembly in the Press

* Indie Hangover is streaming Reassembly RIGHT NOW on twitch
* Let’s Play from SpaceMonkey9288
* Screenshot roundup on Indie RoundUp
* Screenshot roundup on REGRETZERO

How to fix color banding with dithering

Update: Since found a much more in-depth presentation on this topic titled banding in games by Mikkel Gjøl.

Color Banding

Computers represent colors using finite precision – 24 bits per pixel (bpp) is standard today, with 8 bits for each of red, green, and blue. This gives us 16 million total colors, but only 256 shades for any single hue. This is typically not a problem with photographs, but the discontinuities between representable colors can become jarringly visible on gradients of a single color. This artifact is called color banding.

Space games often have dark gradient backgrounds and thus suffer from visible color banding. Games following in the tradition of Homeworld 2’s gorgeous vertex color skyboxes are particularly afflicted compared to games with texture art because the gradient is mathematically perfect and there is no noise to obscure the color bands.

Here are some screenshots from a few games showing the effect. Make sure to click through to the full size image and verify that the color bands are indeed typically only one bit apart (DigitalColor Meter on OSX is great for this). The color banding is easier to see in a dark room.

Homeworld 2 (R.E.A.R.M.)

Homeworld 2 (R.E.A.R.M.)

Obviously these games are still incredibly beautiful! I just wanted to point out that many popular games exhibit visible color banding despite the existence of well understood solutions. Color banding in Reassembly bothered me enough to fix, and I thought that the solution was simple and effective enough that it should be more widely known.


As mentioned above, color banding is caused by 24 bit color being unable to perfectly represent a gradient – the limit of color resolution. We can increase color resolution at the expense of spacial resolution via a process called Dithering. Since we are just trying to draw a smooth gradient and don’t care about spacial resolution, this is great. Dithering takes advantage of the fact that a grid of alternating black and white pixels looks grey. Please read the wikipedia article for a full explanation, and see also Pointalism for an early application.


Bayer Matrix

There are a lot of fancy dithering algorithms but I chose to implement Ordered Dithering via a Bayer Matrix because it can be done efficiently in the fragment shader. The basic idea is to add a small value to every pixel right before it is quantized (i.e. converted from the floating point representation used in the shader to 8 bits per channel in the framebuffer). The idea is that the least significant bits of the color that would ordinarily get thrown out are combined with this added value and cause the pixel to have a chance of rounding differently than nearby pixels. Bayer Dithering takes these values from an 8×8 matrix which is tiled across the image.

I store the Bayer Matrix in a texture which I sample at the end of my fragment shader. Here is the code to generate the texture. Note that we enable texture wrapping and nearest neighbor sampling and are using a one channel texture.

static const char pattern[] = {
    0, 32,  8, 40,  2, 34, 10, 42,   /* 8x8 Bayer ordered dithering  */
    48, 16, 56, 24, 50, 18, 58, 26,  /* pattern.  Each input pixel   */
    12, 44,  4, 36, 14, 46,  6, 38,  /* is scaled to the 0..63 range */
    60, 28, 52, 20, 62, 30, 54, 22,  /* before looking in this table */
    3, 35, 11, 43,  1, 33,  9, 41,   /* to determine the action.     */
    51, 19, 59, 27, 49, 17, 57, 25,
    15, 47,  7, 39, 13, 45,  5, 37,
    63, 31, 55, 23, 61, 29, 53, 21 };

GLuint tex_name = 0;
glGenTextures(1, &tex_name);
glBindTexture(GL_TEXTURE_2D, tex_name);
             GL_UNSIGNED_BYTE, pattern);

Then at the end of the fragment shader add the scaled dither texture to the fragment color. I don’t fully understand the 32.0 divisor here – I think 64 is the correct value but 32 (or even 16) looks much better.

gl_FragColor += vec4(texture2D(dither_sampler, gl_FragCoord.xy / 8.0).r / 32.0 - (1.0 / 128.0));

That’s it.

It’s important that this happens in a shader where the full gradient precision is available – if you do it in a post processing shader reading from a 24 bit color buffer it won’t work. In Reassembly I actually do it in two different places – in the tonemapping shader which reads from a floating point render texture and in the shader that draws the Worley background.


Background halo with color banding


background halo with dithering


shield with color banding


shield with dithering

How to prevent dangling pointers to deleted game objects in C++

Early versions of Reassembly were plagued with crashes due to game object lifetime problems. For example, the object representing the AI for a first spaceship would have a pointer to the enemy spaceship it was targeting. If the targeted spaceship was destroyed (and the object was deleted) the first spaceship could cause a crash the next time its AI ran. Alternatively, various parts of the user interface reference the player’s spaceship object and then crash when the player spaceship is destroyed and its object deleted.

There are a lot of potential solutions to this problem. We can delay deletion of doomed objects for a few frames and any code that references these objects can check if they are still alive before using them. We can traverse any objects that might reference a game object every time a game object is deleted and NULL any pointers to the deleting object. When there are many types of game objects and they all reference each other in erratic and complicated ways this can quickly become burdensome.

My eventual solution was inspired by an article on Coding Wisdom recommending the use of “Watchers” and arguing against reference counting smart pointers. To quote from the article:

  1. Create a base class “Watchable” that you derive from on objects that should broadcast when they’re being deleted.  The Watchable object keeps track of other objects pointing at it.
  2. Create a “Watcher” smart pointer that, when assigned to, adds itself to the list of objects to be informed when its target goes away.

This is the sort of thing that is probably common knowledge among AAA game programmers but was not obvious to me. I implemented this suggestion and it has worked out really well.


My version is available on on my github in stl_ext.h

  1. Game objects that will be pointed to should inherit from Watchable.
  2. Objects that store a reference to game objects should declare the pointer as watch_ptr<GameObject> m_ptr;. m_ptr will automatically become NULL when the pointee is deleted. watch_ptr is a smart pointer so use is the same as GameObject* m_ptr
  3. watch_ptrs are only used when the pointed object may be deleted while the pointer is stored.

It works by adding each watch_ptr to a doubly linked list, with the list pointers stored in the watch_ptr itself. When the watch_ptr destructs, it removes itself from the list. When the Watchable object destructs, it traverses the list and NULLs all the pointers.


Obviously the doubly linked list traversal is not thread safe. Reassembly uses two main threads, a render thread and a simulation/event thread, with a few more workers. There are a few rules for safe usage.

  1. When the update thread is done with the object, NULL all references to it (call nullReferencesTo()). This will prevent any further references to the object from that thread.
  2. Only delete game objects that need to be referenced by the render thread from the render thread. This is often necessary anyway because destroying these objects can also delete OpenGL buffers, which must be done from the render thread. I push ready-to-delete objects in the update thread to a queue, then delete at the end of the render thread frame.
  3. Always copy the watch_ptr to a normal pointer before checking NULLness when using from the render thread. This will prevent the update thread from NULLing the pointer after the NULL check but before the render thread is done with it. Since the render thread will not delete the object until the end of the frame, we don’t have to worry about referencing free’d memory