Written by Harry Krueger, lead programmer on RESOGUN at Housemarque.
RESOGUN is a fast-paced, explosive horizontal shoot 'em up that was released alongside the PS4's launch in November 2013. It was developed by Housemarque, a company that has been around for 20 years now, and published by Sony XDev Europe.
RESOGUN was in development for a total of about 20 months or so, with an additional 12 months added to develop the two expansions for the game: Heroes and Defenders. The core team was 12 members strong, with frequent support from our R&D and art departments, so in total about 20 people total worked on the original version of the game.
Voxels are essentially 3D pixels, and are quite literally the building blocks of the RESOGUN universe. At Housemarque, we've been making arcade-style games for a while now by marrying timeless gameplay values with cutting-edge tech. During the time of RESOGUN's inception, we were considering ideas for our next big game and voxels seemed like a natural way to express this "neo-retro" design philosophy. We quickly came up with a few concepts to utilize this aesthetic approach: one of them was a shoot 'em up, another morphed into an unreleased mobile game, and a few more never made it out of concept phase.
The name "RESOGUN" was coined by Petteri "Petsku" Putkonen, one of our guys at the time. The "RESO-" prefix touches upon the concept of high " RESOlution", and the "-GUN" postfix was added since -- being a shoot 'em up -- we predicted you'd occasionally be shooting things.
The pre-production process was rather simple: Before we started development we made a concept video of the game, featuring a rough estimate of what the visuals and gameplay would be like. I remember when Harri Tikkanen, our creative director, first showed the video to me; being a huge shoot 'em up fan I instantly recognized this as my dream project, and I insisted I'd work on the game if we went ahead with it. A few months later, development started.
Image taken from the concept video.
Prototyping and Early Development
In the beginning we were fairly platform-agnostic. At the time we had PS3 and PS Vita dev-kits in house, so we used those as a reference for potential platforms. When considering possible multi-platform development though, the weakest platform always becomes the lead. In the context of our early development, this meant that RESOGUN was initially targeting PS Vita hardware, and all the technical possibilities and limitations that came with that.
We started implementing the game using the Super Stardust Delta engine. Since both games shared a similar design approach (being shoot 'em ups mapped onto a 3D surface), we were able to utilize many of the existing sub-systems and start working on the base version of RESOGUN immediately.
Preliminary concept art for an early version of the game.
Aesthetically, we started out on a somewhat lighter note. Initially we were planning on having brighter colors, blue skies, and a more naturalistic tone, to represent environments that we thought would be the human habitats. The first level we prototyped had a huge tree in the background, and the humans were in small huts. We eventually shifted away from this and went for a darker tone.
For the gameplay, we knew from the start that we wanted a horizontal, fast-paced, skill-based shoot 'em up. We've been largely inspired by classic arcade games, and we wanted to do our part in keeping that arcade spirit alive. Our goal was to achieve that "one more go" feeling, and create a game that's easy to pick up and hard to master. "Depth without complexity" was a mantra we followed; allow the main game to be simple to pick up and play, but create some layers of depth for those looking for that extra challenge.
Adding some humans for the player to save worked well with this approach. Much like Defender and Datastorm (two of our key inspirations), introducing this extra gameplay layer of saving the humans created an interesting tension for the player, as they needed to balance their "shoot and survive" abilities with a clear secondary goal. We adopted the human-saving mechanic from our very early prototypes, and the humans ended up largely defining RESOGUN's identity.
Another thing we knew early on was that RESOGUN's gameplay would take place on a cylinder. When having a horizontal looping playfield in a purely 2D environment, some kind of minimap is essential to communicate the extended surroundings to the player. Mapping RESOGUN's gameplay to a cylinder eliminated the need for a minimap, as the player can always see around the bend and plan ahead. This helped instantly create intuitive gameplay, and from a visual standpoint the cylinder also made RESOGUN stand out even during early prototyping stages.
Image from an early prototype version.
One other key aspect of RESOGUN was of course the use of voxels. Due to our technical constraints at time, early versions of the game merely simulated the voxel look through carefully constructed meshes and particle effects. Originally we had also envisioned the voxels playing a larger, more direct role in the gameplay. We intended to have the player pick up and manipulate voxel objects, and maybe shoot them towards the enemies. During very early prototyping we realized that this careful voxel management would conflict with the intense arcade action we were shooting for, so we quickly abandoned the idea.
In hindsight, it's actually really hard to differentiate between the development of "the prototype" and "the game." You can easily hack together a working prototype in a couple of weeks, and then proceed to spend two years continuously refining and polishing it to perfection. With RESOGUN, we aimed to create something unique from the start, so we attempted to innovate from very early stages of development, which led to a lot of different iterations.
Iteration Process and Discarded Ideas
When looking at a finished game, everything often feels effortless and naturally integrated into the final product. However, reaching the end result is usually a process of "natural selection" where countless features are eliminated and very few make it into the final cut. At Housemarque, we subscribe to the common game development notion that it's better to iterate and fail quickly. We try to test simple versions of ideas immediately, and then let the game decide: If it works, we keep and refine it, and if it doesn't we discard it and move on.
Below are some of the many ideas we tried for RESOGUN that didn't make it into the final version:
The Tower: We knew from the beginning that we'd require some kind of "drop off point" for the humans. Initially we experimented with a tower-building mechanic, which would collect humans and grow over time. One version had the player collecting all the humans at the tower, and the humans would then run around on a treadmill to generate power ups for you. Outside of feeling a bit abusive towards the humans, as a gameplay mechanic it also felt unnecessarily complicated and hard to communicate.
The Weapon Shop: By killing enemies and saving humans throughout the level, the player would collect "orbs" which functioned as an in-game currency. At the end of each phase, the weapon shop would descend onto the playfield and allow you to exchange your orbs for weapon power-ups. Although the actual implementation was great (it even allowed you to preview items before purchasing), it severely affected the pacing of the game: just as the intensity was ramping up and the player was getting into the zone, we were pulling them out of it and asking them to decide on weapons purchases. Unacceptable.
The weapon shop was one of many ideas we tried but ultimately abandoned.
The Weapon "Options": For the weapons, we also tried having some Gradius-style "options" (helper ships that assist you by shooting alongside your main weapon) which sported a variety of different weapons. The Options didn't work that well with the relatively confined shooting gameplay we were going for, so we went with traditional power-ups instead.
The World Map: We were originally planning to have 10 levels in the game, and had an ambitious plan to incorporate a world map to connect them with each other, hoping to lend the game more cohesion and structure. In between levels the player would get thrown onto this world map, where they'd select the next level from multiple routes. It was unnecessarily complicated, and we ended up discarding it because, once more, it affected the intensity and flow of the experience.
One of the many concept renders for the "World Map" we tested.
The Humans: We had lots of different iterations over the humans. Originally we had humans that would be easily killed by enemies' bullets, and eventually even by the player. Later we iterated over humans with an extra glow or ring around them, to indicate what kind of power up they'd give you. We even tried having special "scientist" humans that award you with power-ups, while the "normal" humans wouldn't.
All of this was once again difficult to communicate and hard to keep track of during gameplay. Initially humans would also spawn from their own "huts", which we would burn to the ground before releasing them. We shifted away from this and trapped them as prisoners in "human chambers" instead, where they'd always be visible to the player.
Originally we had humans escape from their burning houses.
360-Degree Shooting: This is an interesting one. When we got the first prototype of RESOGUN running we naturally tried 360-degree shooting as well, just like Super Stardust HD had. Shooting in 360 degrees generally allows the player more freedom, and this encouraged a more passive play-style that basically transformed the player into a "moving turret": you'd move to a safe location, shoot around, move somewhere else, shoot around, and so on.
By limiting the player to shoot only horizontally, we also forced them to move a lot more; this meant making more decisions and taking more risks, which ultimately created more gameplay. We eventually revisited 360-degree shooting (as a separate "challenge") for our free expansion called Challengers.
Many of the aforementioned flaws in our early designs were highlighted during some of our frequent test sessions. We'd invite people from outside the company to test the game with new eyes, and we'd pay close attention to their initial reactions and feedback. This often helped us gain a fresh perspective on things; as a developer it's easy to get used to how everything works, and even the most obscure features start feeling intuitive after a while. Although these test sessions didn't strictly guide our design process, they often helped us understand when we were over-complicating things.
Establishing a unique visual style for the game also involved lots of iteration. We weren't happy with the bright, more colorful tone we initially targeted, as it lacked a certain "edge" and made gameplay difficult to read. So we eventually shifted to a darker tone, and decided the level environments would now belong to the "Sentients" (our enemies in game) rather than the humans. This also lent itself well to a clear contrast between bright gameplay and dark background elements, which directly helped the game's readability.
Refined concept art from the later stages of development.
The PlayStation 4 Transition
After about a year of development, our planned release schedule seemed to largely coincide with the launch window Sony was planning for the PS4. This was the first time when the idea of a PS4 exclusive came up. Transitioning to a different platform at such a late stage represented a moderate risk, but after several talks with Sony everyone agreed that RESOGUN would benefit greatly from becoming a PS4 exclusive and harnessing the extra power we'd get from such a machine.
Although we received devkits fairly late (roughly eight months before the PS4's launch), we were already largely aware of the possibilities the PS4 would allow through features like compute shaders and 8GB of unified GDDR5 memory, so we started working within these lifted constraints immediately.
A target render put together during our transition to the PS4.
The design of the core game remained largely undistracted by this transition -- after all, gameplay always comes first. The decision to keep the game focused in scope also meant we could throw all of this newly found processing power at making the core gameplay much more satisfying and rewarding, and create a truly rich sensory experience while maintaining our original 1080p/60 target.
Needless to say, switching to the PS4 was a hugely positive transition for the project. We needed to re-think practically everything related to the game's tech and presentation, as we now had the power to abandon many of our early compromises and push the game to its full potential. Being freed of the shackles of potential cross-platform (and cross-generation!) development meant that we could confidently "look ahead" and not have to compromise on our vision. We had more options than before, but expectations were also much higher; we now needed to deliver a true "next gen" experience that would stand alongside other giants during launch.
Let there be Voxels!
Voxels were obviously a huge part of the game, and with the PS4 we had a chance to explore their utilization anew. Before, we needed to combine traditional polygonal meshes and effects to merely approximate the "voxel look"; now we could use actual voxels to construct (and blow up) everything and create a much more visually cohesive experience.
All of this sounded great of course, but we still needed to somehow put all this into the game...
Asset Generation: Voxel Levels
Working on one single platform meant we could now standardize our export procedure and streamline our asset generation pipeline.
Generating voxelized assets for RESOGUN involved two separate systems: one for the static voxel levels, and another for the entities (humans, enemies, player ships etc.) Having two separate exporting procedures for these allowed for more control and optimization.
For the levels, we created custom Maya tools for generating and exporting them. As a first pass, we would build an asset in Maya using traditional mesh tools. A custom "voxelizer" tool would then process this by raytracing the structure, and generate a "hollow" voxelized cube mesh from it. Meshes were left hollow because aside from the redundancy of generating the inner cubes (they'd be very hard to edit), it also significantly helped with Maya performance.
Our voxel level generation process.
Once the hollow cube mesh was generated, our artists could then edit the surface cubes and define material attributes per-vertex. The material of the "inner" cubes (which are exposed during gameplay after e.g. an explosion chips away the surface) would be decided during the export phase using a separate attribute.
Aside from the surface and inner cubes, we also needed to create "indestructible frames" inside the level objects, so that we could maintain some structure and readability during gameplay. To create these, we used our same "voxelizer" tool, which built voxels at specific locations inside our modeled mesh. The voxelizer tool also defined the "density" (how far apart) these inner frames would be. We would then mark this generated frame as "indestructible" and the export process would combine these with our final asset.
Each level could be composed of multiple objects, each with their own materials and properties. During export, all of the objects composing the scene would be mapped to a large 3D grid, and then exported as a custom 3D texture. This process was used to generate the two key assets for each level: one for the "centerpiece" (which had a maximum size of 512^3), and another for the outer "gameplay ring," which was exported as a 128x128x1536 rectangular prism and rendered in-game using a separate "curved voxel" technique (more on this below).
Creating our levels like this meant that we had a fixed grid size for all levels, which standardized many of our exporting and in-game procedures. It also compressed well, and allowed for more complex levels within the same grid without much overhead.
These are the "cube mesh" constructs we used for things such as the Player Ship, Enemies, Humans and various decoration items. Although our levels used voxels in a more traditional sense (adhering strictly to a grid), for enemies we allowed for cubes of different sizes, which could be rotated and animated freely.
To create these cube meshes, our artists would again use standard Maya tools to define rough planes and primitives, which would define the basic shape of the entity and where the cubes would go. Our custom tool would then iterate over all primitives, and generate individual cubes based on each polygon's location, orientation and size. This process often required a bit of guesswork, but thankfully re-generating the voxel data from adjusted primitives was fairly fast so iterating over entities was efficient.
The steps of creating the Ferox ship using the cube mesh generation tools.
During export, everything was "flattened" into raw cube data, which contained per-cube offset, material, orientation, and grouping information. We needed to separate cubes into groups and sub-groups to correctly define their connectivity and behavior, so that e.g. if an arm of an entity is blown off during gameplay, all logically connected cube groups would be detached at the same time. The cube groups were also used to define separate bounding spheres for more accurate gameplay collisions.
Voxel Levels: In-Game Handling
Earlier on, we needed to be careful about memory consumption, but now we could potentially use more memory for a single level's voxel grid than the PS3 had in total. This meant we could keep the entire level's voxel data in memory, and update the state and material of each block individually. This allowed for fully destructible environments built out of millions of cubes, that could blow up in a voxel-perfect and spectacular fashion.
To construct the levels in-game, we utilized two separate (but fairly similar) systems: one for the level's centerpiece, and another one for the gameplay ring. Both shared the same geometry generation compute shader code, but the gameplay ring's rectangular prism was curved/"bent" during rendering to allow it to form an actual circle.
Once the static level data is loaded, our compute shader iterates over all the voxels and their materials in the 3D texture, and constructs the surface geometry of the level. The level data is broken up into separate 64^3 voxel blocks, and only the ones containing something are processed. The surface area of each voxel block is then polygonized as a series of quad-strips, and base colors are sampled from the 3D textures and combined with different material textures for the end result. We're only constructing the surfaces for the outer voxel layer, so no geometry actually exists for the inner cubes until they're exposed.
The surface geometry for our levels was rendered as a series of quad strips.
When an explosion occurs during gameplay (which is quite often) and a part of the world is "chipped away", the affected geometry for that segment is reconstructed in real time. Since we're keeping all level voxel data in memory, all material properties for the inner cubes are preserved.
With each explosion, every individual voxel that is chipped away from the world is converted to a "physical cube" (see below). The entire process of updating the level grid geometry and chipping away individual cubes from explosions is performed entirely on the GPU through compute shaders.
In addition to the static, fixed-size cubes we used for the levels, we needed to implement a separate system for rendering free-floating, dynamic cubes as well. Compute shaders lent themselves well to this problem, as their architecture allows for very efficient handling of large chunks of small data like particle (or cubes!)
The geometry for each individual cube was constructed dynamically using our vertex shader. Since each cube is a volumetric entity, it has its own material, receives its own lighting, and casts its own shadow. This simple, lightweight system is what we used to render hundreds of thousands of cubes in-game, both for constructing CPU-controlled gameplay entities such as enemies, and also for GPU-controlled physical cube effects.
Cube mesh entities consisted of thousands of cubes that were individually processed and animated. While these cubes were "attached" to an entity, all their new positions would be updated exclusively by the CPU, and the rendering information was simply passed to our shaders. Tracking all of this cube data wasn't cheap of course, so we ended up using about 1GB of memory just for the entity cube meshes.
All entity cube meshes utilized a fairly simple but sophisticated damage model, which allowed individual cubes to be chipped away when parts of them received damage. When cubes were detached from an entity, ownership of them would be transferred (in a "fire and forget" manner) from the CPU to our GPU-based "physical cube" system. This separate sub-system would then assume control of each individual cube's behavior, and update its physics, collisions and lifetime completely independently of gameplay.
Keeping the level's static voxel grid in memory lent itself well to quick collision lookups, so that each physical cube could bounce off level surfaces naturally. We also implemented another sub-system which allowed us to feed additional collision info from the gameplay side to our compute shader; this was used to make physical cubes react to gameplay events, so that e.g. cubes would be pushed away during a nearby explosion or when the player boosted through them.
Each individual cube had its own geometry, material and physics.
With this revamped voxel tech, the game gradually transformed into a much more elegant beast. By constructing everything from the same building blocks and using one single system for rendering all the voxels in the game, RESOGUN achieved a much more cohesive and unified presentation. Everything in the game could now be accurately destroyed in a spectacular fashion, and all the individual cubes flying around made the game feel very reactive and dynamic, which dramatically improved the player experience.
"Turbo Particle System"
In addition to our voxel tech, we also worked with compute shaders to create a GPU-based particle system, which we internally called the "Turbo Particle System."
Offloading the workload exclusively to compute shaders meant we could have much more impressive effects without a performance overhead. Effects for this were simply spawned and controlled by the CPU, and the updating of each effect was left to its designated compute shader. The particle update performed sub-frame simulation for all effects, so that even super-fast moving particles at very high spawn frequencies would still look good and fluid. This system also supported a collision system similar to that used for the physical cubes, so that each individual particle could potentially collide and deflected off gameplay entities such as enemies.
This system was very powerful and allowed for spectacular looking effects. It was used in specialized hand-crafted effects like the player's Overdrive beam, the lightning bolts, the player's shockwave/bomb and even the "Save the last humans" texts you see in the game. However, since each effect needed to be hand-coded, this system wasn't very artist-friendly. So we still kept and heavily utilized our "normal" CPU-based particle system, which was easier for artists to work with and lent itself better to simple effects like explosions.
The player's "shockwave" was one of several effects which utilized our "Turbo Particle System."
Game Logic and Multiplayer
For our gameplay systems, we utilized a multithreaded fiber system which was originally developed for our PS Vita title Super Stardust Delta. This framework allowed hundreds of lightweight gameplay tasks to run independently across multiple threads, and their execution order would be determined at run-time by resolving each the tasks' dependencies. This was a very flexible and high-performance framework, and was directly responsible for keeping our CPU footprint very low during gameplay.
For our online multiplayer, we went with a deterministic execution model. The theory here is that given the same exact input, the game should produce the same exact output across multiple running instances. In practice, this meant that we only needed to send the player's input over the network, and only run the next frame when input from both players was available. This resulted in very light network packets, and also drastically streamlined our online multiplayer development.
Of course, the downside here was that we needed to actually get the game running deterministically. Doing so in a heavily multithreaded environment was not an easy task, and the delicate nature of determinism meant that even simple human errors (such as leaving a single variable uninitialized) could cause the game to go off-sync. Attempting to find these corner cases ourselves would be an exercise in futility, so we created an automated system that would detect determinism errors for us during execution instead.
The architecture of our fiber system lent itself well to such a change. We first extended our fiber tasks, so that each one would calculate its own running CRC checksum from variables we needed to keep deterministic. We then wrote a quick (...and not very smart) "AI" to play the game automatically for us and record the CRC data for each frame. The system would then run the game again multiple times with the same exact input, and if a CRC mismatch was detected it would trigger an error at the exact variable and location that caused it.
Once this system was in, it allowed us to effectively test the stability of our deterministic model even locally, as we only needed one instance of the game running to "emulate" the multiplayer rules and perform the checks. So everyone would leave these automated "determinism checks" running when away from work, and see if we had any surprises waiting for us when we got back. This automated checking helped us identify and fix countless errors (both determinism-related and otherwise), and proved instrumental in achieving a high stability for the final game.
By the time we shipped RESOGUN, it was stable enough to "survive" our automated checks for over a week at a time. Fun fact: the same AI we used for the determinism checking made it into the "Attract mode" of the game, which you can see if you leave the game idle for too long at the title screen.
First Expansion: Heroes and Construction Kit
It’s kind of tricky when you are working on an expansion, because if you deviate too much from the core formula, people are going to be disappointed. On the other hand, if you give them something too similar, they’ll also be disappointed. So for both of our expansions we decided to have the best of both worlds: something familiar, and something entirely new.
Survival mode was our take on the "endless" formula, something we wanted for RESOGUN from the start. We knew that it needed to restrict the player to a single level which would get progressively harder. Just like the Arcade mode, each game session would be focused and tight, and not require players to invest hours of their t