Tag results

Deadlines are a good thing

PAX West 2016Alpha Access

PAX West is nearly upon us, and there’s absolutely nothing better than an external deadline to help turn on the afterburners. I’ve been working at a feverish pace for the past few weeks, adding a ton of new content, refinements, and going on a bug-squashing rampage. I’m relieved to see that some of my development lists are actually shrinking for the first time. I’ll be in Seattle for the week surrounding PAX, so updates will be slower (or nonexistent) for a short period of time. If you’re going to be attending the expo, please stop by booth 6014 and say hello!

In other big news, alpha access to Invisigun Heroes is now open to the public! This is sort of a trial run to see how this goes, but it should at least be available through September. If all goes smoothly, alpha and beta access will be open to the public until release. The game is purchasable through itch.io, with some very clear alpha disclaimers (not feature complete, online coming soon, etc). If you know anyone that missed out on the Kickstarter and is interested, please let them know!


I was never fully satisfied with placeholder sprites and aesthetics for some of the newer worlds, so I took some time to give them a much-needed facelift. In particular, Arx-515 has updated boundaries that fall more in line with the cute-cyberpunk feel that was originally intended, and pulls some of the distracting neon signs out of the levels where they were seemingly important. Glaciarii also has reskinned boundaries, and players finally look appropriately frozen by the Yeti. Arenae has some global value adjustments so that objects (rugs, shifting walls, etc) don’t stand out so much and feel more at home within the temple walls.


Much of the focus for the past few weeks was trying to get as much of the planned final content in. This means the latest update has tons of new maps (and refinements to existing ones), new and exciting powerups (Ability Recharge, Split Shot, Diagonal Shot), a handy Field Guide to serve as in-game reference for new and studious cadets, mastered music tracks, and most importantly – a fundamental gameplay adjustment with ability cool downs. If you don’t spam your abilities, you shouldn’t notice that last one. If you DO, you’ll find that constantly activating your ability will incur longer and longer cool down periods (during which you are visible). It is very easy to stay away from this, but this solves a number of situations where abilities could be abused, and also creates an extremely useful tool for balancing them.

I know that a lot of you are eagerly anticipating online-play, and it’s still a top development priority. I’ve made a lot of headway and am constantly chipping away at edge cases and synchronization issues. From a development perspective, the annoying thing is that I can’t release it for testing until all the loose ends that I’m aware of are cleared up. You can’t play a networked game if it only partially works, like you can with a local game; if something is broken locally, everyone is at least still on the same page. I just want to let everyone know that online play is moving along, even though it’s taking longer than expected. Thanks for your patience, and see you at PAX West!

Artificial intelligence, dev status, and expos!

Hey everyone, hope you’re having a great summer so far! It’s been around 105°F here in Pasadena, which is just a few degrees above “pleasant.” As a reminder, if you haven’t received your download keys or your physical rewards, please message me on Kickstarter (or here) and we’ll get it squared away. Almost everything should have been delivered by now, barring the soundtrack and some late surveyors.

Along with plenty of bug fixes, the latest alpha update (v0.8.98a live on Itch and Steam) has bots enabled. The foundation for the bots was in place for a while, but they have a lot of logic now to react to the environment, search for opponents, and try and follow game mode objectives. Their logic will be improved with every update to address any feedback, but feel free to try them out!

Bots fighting bots
Bots fighting bots

Over the past couple of weeks, I’ve made serious headway into online play. I ran into a few stumbling blocks and it’s definitely not going to drop as early as I’d previously hoped, but most of the major technical barriers are out of the way. I’m focusing on the basics, starting with being able to connect via IP address. Currently connections, disconnections, player selection, game setup synchronization, and basic in-progress match actions are synced correctly.

IP connections and player synchronization
IP connections and player synchronization

In all honesty, this foundation was one of the biggest hurdles and technical challenges, so it’s a relief that most of the issues have been resolved. It’s based on a new and not-so-battle-tested networking system in Unity, so it’s been somewhat painful for most early-adopter developers. We spend a lot of our dev cycles in networking forums, trying to figure out if bugs are on our end or theirs, helping each other, and trying to decipher incorrect documentation. There are lots of edge cases I need to find and tackle before turning the feature on, and after that, it will be more fixes and progress on public and private match listings.

While the focus was definitely 95% on network play, I managed to sneak in a couple of new Nemoris maps for testing, and I worked on some content lists for the final stretch. There is less time for experimentation at this point, though the game is by no means feature-locked (still alpha). I will still work with the Heroes to design new characters, and I’m still planning out the Cartographer details for the backer maps.

Ali and I have completed the soundtrack and the first final mix / mastering pass is complete! The updated tracks will be in the next update, though some of them still won’t be heard until their associated planets (Craterus and Arenae) are released. Stay tuned for crispy-sounding tracks in the next drop. Once all the final audio assets are in place, the game will go through an entire mix pass before release as well. And of course, those of you who backed the project at the Composer tier or higher will receive download codes for the soundtrack once it’s ready.

My time at the moment is divided between development and all the logistics for the upcoming conventions. We’ll have a booth (#6014) at PAX West from September 2-5, and also at XPO Tulsa from September 23-25. There’s a ton that goes into planning these, involving extra help, flights, hotels, shipping gear, arranging on-site resources, preparing promo materials, and of course, finalizing the convention game build. I want to thank you all again for supporting this campaign, as part of the funds were definitely reserved for this, and it’s because of you that we’ll have a presence there!

If you’ll be at any of the conventions, please stop by! I’d love to meet you in person, and I’ll have more expo details as the dates approach. This does mean that Invisigun development will slow down in September, though I’ll have the middle of the month for progress on that front.

That’s it for now, please enjoy the updates and while I can’t promise when, I hope to have network play via IP address turned on soonish!

AudioMixerSnapshot transitions independent of timescale

Unity Audio Mixer

One of the great new features of Unity 5 is the overhauled audio system, including the fancy new mixer and audio mixer snapshots. As a sound designer, this was one of the major selling points that pushed me to upgrade from 4.6. In particular, the AudioMixerSnapshot class lets you define a bunch of settings (for example submixer settings, filter effect values, etc) and transition between them – either instantly or over time. For example, one classic and emotionally-effective use is to low-pass filter your music when in a pause menu or item selection screen that takes you “out” of the action.

The only problem is that many people set Time.timescale to 0 when pausing their game, and this actually prevents the AudioMixerSnapshot.TransitionTo() function from transitioning smoothly. I was tired of waiting for a native solution to this, so I wrote a coroutine in my AudioManager class to handle snapshot transitions, and this is not affected by Time.timescale. Here’s the sample code, easily adaptable to your own class:

private Coroutine transitionCoroutine;
private AudioMixerSnapshot endSnapshot;
public void TransitionSnapshots(AudioMixerSnapshot fromSnapshot, AudioMixerSnapshot toSnapshot, float transitionTime)
        transitionCoroutine = StartCoroutine(TransitionSnapshotsCoroutine(fromSnapshot, toSnapshot, transitionTime));
IEnumerator TransitionSnapshotsCoroutine(AudioMixerSnapshot fromSnapshot, AudioMixerSnapshot toSnapshot, float transitionTime)
        // transition values
        int steps = 20;
        float timeStep = (transitionTime / (float)steps);
        float transitionPercentage = 0.0f;
        float startTime = 0f;
        // set up snapshots
        endSnapshot = toSnapshot;
        AudioMixerSnapshot[] snapshots = new AudioMixerSnapshot[] {fromSnapshot, toSnapshot};
        float[] weights = new float[2];
        // stepped-transition
        for (int i = 0; i < steps; i++)
                transitionPercentage = ((float)i) / steps;
                weights[0] = 1.0f - transitionPercentage;
                weights[1] = transitionPercentage;
                audioMixer.TransitionToSnapshots(snapshots, weights, 0f);
                // this is required because WaitForSeconds doesn't work when Time.timescale == 0
                startTime = Time.realtimeSinceStartup;
                while(Time.realtimeSinceStartup < (startTime + timeStep))
                        yield return null;
        // finalize
void EndTransition()
        if ( (transitionCoroutine == null) || (endSnapshot == null) )

Self-destructing test builds

Well… not exactly self-destructing. This is a simple example of ensuring that a published build won’t run after a certain date.

Why would you want this? It can be useful if you are distributing pre-release alpha builds, press builds, or any version that should only be available for short-term testing. You may have early prototype information and art assets that shouldn’t really be leaked over time. It can also ensure that continued testing means your recipients need the latest version (which still works and isn’t locked out due to being old). It’s not an ultra secure solution, but simple enough to implement for a quick time-based lockout.

You can first define a constant to hold your expiration date (or use another build-configuration variable somewhere). With that in place, it’s simply a matter of making a function that checks if you’ve passed that date, and quits if this is true. If the expiration date is blank, this won’t ever expire (for final public releases).

// define your build's expiration date somewhere, or leave blank to not expire
private string BUILD_EXPIRATION_DATE = "2015-01-01";

// call this function from anywhere (for example in your title scene) to check
// if this build has expired
void CheckBuildExpiration()
    if (!string.IsNullOrEmpty(BUILD_EXPIRATION_DATE))
        Debug.Log("This build will expire on: " + BUILD_EXPIRATION_DATE);
        if (DateTime.Today >= DateTime.Parse(BUILD_EXPIRATION_DATE))

Pixel-perfect discrepancies in OpenGL and DirectX

Since this project has a low-res pixel-art style, it is very important that everything is presented as point-filtered textures with no anti-aliasing, or it defeats the intended look. I noticed that my Windows builds had a very “soft” look to them, while my builds on OS X were perfectly crisp with no blurriness.

OpenGL vs DirectX pixel offset discrepancy
OpenGL vs DirectX pixel offset discrepancy

I have a quad that covers the entire visible area with a pass-through shader on it that is used for occasional visual effects. With no effects active, it simply passes the pixels behind it onwards. This is achieved using Shader Forge’s “Scene Color” nodes. After discussing this with Shader Forge’s developer Joachim Holmér, he suggested that the issue may be a different pixel boundary in DirectX vs OpenGL. Sure enough, this was the case and I was able to account for this by using a custom “Code” node in combination with Unity’s pre-processor shaderlab macros:


It’s a simple edit, but you can see that a pixel offset is first calculated. This is 0 (none) for OpenGL and 0.5 for DirectX. This value is then used to offset the screen’s UVs by an amount calculated using that offset and the screen dimensions. I’m sure there are other ways to solve this, but this is working for me and hopefully the information is helpful regardless.

©2021 Sombr Studio LLC