Magnaut

A top-down shoot-em-up in which you attach the hulls of defeated enemy spacecraft to your ship, using them as both weapons and armor.

Overview

Magnaut is a side project I started ago when I decided to expand my entry for a Ludum Dare game jam into a full game. Initially, the project was built in ActionScript 3 using the FlashPunk library, but between frustration with the Flash platform's lack of support by Adobe, a desire to rework a number of the game's mechanics, and an interest in trying out engine development, I decided to transition to a custom-built C++ engine. Though the game itself is not yet in a playable state, the engine itself (called "ECSE") has some interesting technology already in place.

Downloads

Engine source code (requires SFML 2.4.1, Boost 1.62.0)
Pre-compiled demos (Windows)

ECSE

ECSE, short for Entity-Component-System Engine, is an open-source engine built to tackle several problems that I had when developing Magnaut in AS3. It makes use of the SFML library for rendering and sound, as well as Boost for some low-level memory management tools.

ECSE has a lot of features that I'm excited about, but I don't have room to go over all of them here, so here are some of the highlights:

Below, I'll cover two of ECSE's major systems in greater detail.


Collision Detection

While working on Magnaut in FlashPunk, I repeatedly ran into two major issues with collision detection. First of all, FlashPunk's collision detection is entirely based on axis-aligned rectangles, but in Magnaut, ships are almost always at an angle (especially the ones attached radially around the player's ship). Secondly, the game features a lot of fast-moving, tiny bullets, and with discrete collision detection, it's easy for those bullets to "phase through" other objects, which is extremely frustrating to the player.

To solve these problems, I came up with my own collision detection algorithm with the following features:

  • Colliders are currently either circles (e.g. bullets, rotating ships) or lines (e.g. lasers), which is a cleaner abstraction of the shapes that tend to show up in Magnaut.
  • Collision detection is continuous and can trigger multiple collisions per frame for the same object if its path is changed by a collision.
  • The system is optimized for smooth performance with dozens of moving objects on-screen even in Visual Studio's debug mode (which is more than enough for the purposes of Magnaut).
Collision Detection: Algorithm Breakdown

Replay System

Being inspired by arcade shoot-em-ups, I always wanted Magnaut to include a title screen "attract mode" featuring videos of gameplay. Rather than include huge video files with the game, I decided to implement a replay system that would take advantage of ECSE's deterministic nature. As an added bonus, this lets me record buggy gameplay and replay it perfectly every time for easy debugging!

ECSE's replay system records the player's inputs at each physics step, then plays those inputs back identically to recreate the same gameplay as before, which is fairly simple to do in ECSE thanks to its input system and fixed time step. Instead, most of the work for this system went into determining how to save the data with minimal file size. To that end, I developed an input scheme that rounds off analog inputs in-game without making it too obvious to the player, then created a compression scheme that reduces the replay files to an extremely small size.

Replay System: Technical Overview