Inspired by classic space shooters, Never Not Shooting is all about chaos. Grab up to 4 players and start by customizing your ship. You have 27 possible weapon configurations to choose from. You'll need to experiment to find the best team to take down a never-ending horde of procedurally generated waves of enemy ships all trying to destroy the sun. The longer you survive, the more enemies you'll face in each wave. The enemies will become more and more deadly as the game progresses. But no 2 games are exactly alike. Survive as long as you can so you can beat the high score.Available on Steam
Blog Post June 2018:
Perk and I are both software developers in our day jobs and in our nightly pursuits. We’re also big proponents of testing our code and striving for a high percent of test coverage over all our logic. In my day job, this comes pretty easily. There are known inputs, outputs, and for the most part the business logic that we construct is linear and straight forward. Get data from a database, filter it based on business requirements, transform it to some other model of information, push it out of the system. This kind of work flow is, hopefully, well defined and thought-out ahead of time by someone whose job it is to document the process and make sure it gets created. It turns out that creating a video game is a little different than a business request.
In our first released game, Never Not Shooting, we created a whole set of systems that are procedural in nature and are built to be randomized every time a player loads up the game. A new game starts, an enemy type is selected at random from the basic list of enemies, a spawning pattern is chosen at random, and the starting positions of the enemies are chosen randomly (while adhering to the selected spawn pattern). Introduce a new enemy type repeating the same process. Repeat until the game is over. All of this is happening while the player is given the ability to do whatever they’d like in the meantime. The amount of chaos that is contained in that system makes the game unpredictable and surprising, but it is so daunting from a testing standpoint that we wrote off the idea of trying entirely.
The idea behind automated tests in code (unit, integration, or functional) is that when the code inevitably needs to change, there is a set of tests defined that dictates what a process is supposed to do in all cases. Test coverage is the term for how many of those scenarios are dictated. Usually, the type of changes required to a system do not require the system completely. They are more often, tweaks to existing logic. It may be a need to add a new step amidst a process, or a new scenario needs to be handled. Test coverage allows a developer to add their new code or tweak the old code and be sure that all the things that are supposed to happen still do. The trick to having a high amount of coverage is that you have to think about the testability of the code you’re writing while you’re writing it.
There are many ways to accomplish an end goal in programming and some of them are more difficult to test than others. When we wrote off the idea of testing a game because we thought it would be too difficult, it enabled us to pick many of those ways to accomplish our goals that were basically untestable. Looking back at our old code for Never Not Shooting, we definitely chose many of those paths and to make the code testable would require a whole rewrite of many classes. Additionally, since we don’t have any test coverage of the existing behavior we’d be adding a lot of risk for bugs being created in the process. We’ve learned from our mistakes in the past and as we move forward with our new game and start to expose more of our process with all of you out there, we’ll be demonstrating how games and their systems can be tested if you take the time to plan for testability in the creation process. I’m looking forward to what we’ll be sharing over the next several months.