1. Nova Drift
  2. News
  3. A Deep Dive Into The Soon-To-Be-Released Enemies 2.0 Update

A Deep Dive Into The Soon-To-Be-Released Enemies 2.0 Update

Our next major update, releasing on January 18th, represents the first part of "Enemies 2.0", Nova Drift's largest ever overhaul. Enemies 2.0 will be rolled out in several parts, the first of which focuses on enemy encounters. The update is currently being tested on the Beta Branch, if you'd like to give it a try. We've created special channels on the Discord server for you to discuss the changes and submit feedback. Please keep in mind that the update is not finished and we've still got a lot of work to do, especially on difficulty tuning!

To access the BETA branch on Steam: Right click the game in your Library and go to PROPERTIES, switch to the BETAS tab, and choose the "beta" branch. You might also have to exit Steam and restart it to force the update.

Nothing is set in stone for these updates, but things may go a bit like this:

[h3]Enemies 2.0, Part 1:[/h3] (Launching Jan 18th)
  • Dynamic waves overhaul
  • Enemy formations
  • 6 new enemies & boss overhaul (Station Omega)
  • Battlefield zoom


[h3]Enemies 2.0, Part 2:[/h3]
  • 5 alternate bosses
  • Boss Rush challenge mode
  • Draft challenge mode


[h3]Enemies 2.0, Part 3:[/h3]
  • More new enemies
  • More classic boss overhauls
  • Further refinements to dynamic waves


And as usual, these updates will also contain a whole lot of new stuff to play with, balance changes, quality of life changes, localizations, and other surprises.

[h2]What are DYNAMIC WAVES?[/h2]
Long story short, we've ripped out all of the enemy waves you're used to and replaced them with a system that procedurally generates them. Some people have expressed interest in exactly how they work, so let's break it down!

[h3]Step 1: Choosing The Enemy[/h3]
The first thing the script does is decide which enemy to spawn by picking from a weighted list. Some enemies are a lot more common than others. Some enemies don't have a weight until you've reached a high enough wave to encounter them.



Note that "waveInfo" is outputting exactly what the spawner is doing to both the debug console and the in-game wave log, which is accessible with cheats. This will really help us balance these huge changes during the beta.

It's getting all of this spawn data from a different script where many parameters are defined for the enemies, enemy spawn types, enemy entrances, and enemy formations.



Each enemy has a defined set of ways it can spawn, enemies it prefers to be paired with, and followers it's capable of supporting in formations.

[h3]Step 2: Choosing Spawn Type[/h3]
Next, the spawner must look up the different types of spawns that are valid for the selected enemy types and, again, choose one by weight (some spawns are more common than others). Spawn types determine the position and order enemies spawn in, whether they have followers, and if they do, how the followers behave.



Spawn types include: standard, arc, centered, fleet, pincer, v formation, v formation pincer, spiral, spiral double, spiral triple, box, cascading pincer, cascading pincer opposing, cascading fleet, cascading adjacent, cascading edges, formation: orbit, formation: flank, formation: rank and file, formation: trail, formation: protect, formation: support

[h3]Step 3: Choosing the Enemy Entrance[/h3]
Some enemies can enter the battlefield via a portal or by emerging from the background. This time the entrance is selected randomly from the choices.



[h3]Step 4: Determining Enemy Quantity[/h3]
A lot of factors determine how many enemies should be spawned. First, the script uses triangular distribution to get a base value from a low, mean, and high value derived from the spawn info. Then, it adds some random factor and scales it based on how far the player has progressed. Next it determines if this is going to be a paired wave. Paired waves mean that two dynamic spawns are happening at once, each with reduced enemy quantity.



Paired waves are usually inherently more difficult, so the two waves add up to 85% of the original quantity. (52.5% quantity for the first wave and 32.5% quantity for the paired wave).

Later, in step 6, it'll multiply quantity yet again based on which spawn type is being used.



Spawn types with a high quantity multiplier tend to be easier, distributed gradually, or more infrequent.

Certain enemy types either always repeat (like Saucers) or sometimes repeat (such as Interceptors or Shredder Mines). As the players reach higher waves, these waves are able to repeat more times. There is also a function here that determines how long the delay should be between a repeating wave. This is useful in some spawn types, too, like the spiral spawn.



[h3]Step 5: Enemy Followers[/h3]
One of the most exciting features of Enemies 2.0 are enemy formations.



There's more: Protect (stay between the player and the leader) and Support (cower behind the leader).

To make a formation, enemy follower quantity is first determined using the same method as the leader quantities. Followers may also have the ability to cascade their actions. For instance, if a formation spawns with a leader orbited by 8 Wardens, they might fire one at a time, slightly offset, instead of firing all at once. This makes things a bit more interesting. Also, followers might decide to break off from their leader, one at a time. The values that drive those behaviors are defined here, too.



Formation break off is especially interesting with the new kamikaze unit, the Hammerhead!

[h3]Step 6: Creating Enemy Spawners[/h3]
First, some default values are defined for the enemy spawner to use, many of which are overwritten by the unique needs of each spawn type. Now the script has generated all the variables it needs to tell the spawnEnemies() script what to do! A switch statement contains the spawn conditions for every spawn type that may have previously been selected.



This is code for 3 of the 22 different spawn types.

[h3]The Enemy Spawner[/h3]
The enemy spawner objects are responsible for a lot, too, but covering how those work could be a whole separate blog post. In short, they do the following:

  • Determine, based on what was spawned and how many things were spawned, how much time should be added to the clock before the next wave automatically advances
  • Stores an array of all enemies to spawn, coordinates where they should spawn, and determines their rarity (meaning the enemy could upgrade to elite or champion)
  • Handles creating portals, warnings, etc
  • Sets timers to create the enemy objects at the correct time and place
  • Creates and arranges the enemy's followers, if any
  • Repeat for incremental or repeating spawns, as needed
  • And, finally, silently self destructs and experiences unending peace in the great beyond


But the Dynamic Waves script isn't finished yet...

[h3]Step 7: Creating Paired Waves (And Friends)[/h3]
Almost done. Now, the script sees if a Cherub (a new support enemy) wave is paired with the wave (at no extra charge!). This is something that happens very rarely. Next, paired spawns are handled. If it was determined earlier that the wave would be a paired one, it runs the dynamicWaves script again, this time with instructions to create that specific enemy wave with reduced quantity (and with formations excluded).



[h3]SO! What's Left To Do On The Update?[/h3]
While procedurally generated waves do add massive variety to Nova Drift, I ultimately decided that I did not want to have every possible wave (except bosses) be this unpredictable. There are some particularly mean or wacky things (like the above example) that are much better handled as "mostly curated" waves. I'd like to create a system that takes an array of such handcrafted waves and scales them based on a few simple variables like wave progression. The player would encounter these waves at wave multiples of 5 or 10, instead of Dynamic Waves, when the player is not facing bosses.

Also a bunch of other new stuff is coming that needs wrapping up...







[h3]Thanks For Reading[/h3]
It's been very interesting and extremely challenging crafting this system with the enormous help of our resident "Code Elf", Ultraken. It pulled me wayyy out of my comfort zone, it took half a year to create all the related assets, and I learned an almost overwhelming amount. When I started Nova Drift 7 years ago I was coming from an art background and was barely able to code, relying mostly on Game Maker's "drag 'n drop" functions and forum-copy-pasta. I feel like I've come a long way, this may be the first time I wasn't entirely embarrassed to show the "guts" of our game. Thanks for reading the blog and being a part of that journey with me. I'd also like to thank the other coders on our Discord that were able to provide feedback and guidance.

[h3]Want to help Nova Drift grow?[/h3]
Steam reviews really help! As a tiny operation, Nova Drift relies on its quality and reputation to sell, and reviews also encourage the Steam algorithms to show the game to more people. Please do take a moment to fill out a short review, even if it's only a few words. It just might make a big difference.

Best wishes,

Chimeric