Thursday, May 20, 2021

Project Breach #6 - "The Demon Update"

 Project Breach #6
"The Demon Update"

The Transformation
Its been over a month since my last update and to say a lot has happened would be an fairly massive understatement. Between then and now I published a video titled "The Dangers Of Being Public" (link here), in which I said the following:

"I’m not opposed to pivoting a game's direction if I feel it’s necessary. With the upcoming demo for Project Breach, I feel that some people might misinterpret this. But hear me out. That's the whole point of a demo, to figure out what's fun, what works, and what doesn't. If it turns out that controlling pawns RimWorld style isn't fun for a tactical game, then I see nothing wrong with changing the game direction or even changing it entirely. The cool thing about building everything the way I have is that its all been built very generically, which means everything I've made applies to all sorts of different games. If I decided the game was to be an RPG or a survival horror, nothing I've made so far would really need to change to accommodate that. I have an armor system, I have a weapons system. Most games would benefit from these things. No work will have been lost. The map editor, weapons system, even enemy AI will be just as useful on any other project as it will be for this one."

I've often said "I've been making an engine not a game", but it was only while making that video I realized I had never said it online. Even builds of the game refer to it as "Perlinia Engine 3".

I kept working on the game but it wasn't feeling any closer to being fun to play. I kept thinking that a tactical game like this just doesn't work with RimWorld controls because you need more precise commanding than that. So I was faced with three options:
  1. Scrap the engine: It sounds unbelievable but after 3 months of work and the game still feeling like it wasn't coming together, this was tempting. Also the fact that I was working on a 2D game instead of one of those beautiful 3D ones I see other indie developers posting on Reddit. But I knew in my heart that the problem wasn't the engine itself but rather that the idea just wasn't working, so I was dedicated to using this engine no matter what.
  2. Redo the controls: Maybe "A Rainbow Six Siege style game but top-down with RimWorld style controls" just doesn't work. But perhaps with another control system it would?
  3. Pivot the game: What if the player controlled a pawn like a normal person instead of an RTS? But leave all the other programming the same? It'd take me awhile to program all new systems for the player to use (I don't want them actually controlling a pawn, just controlling a body with systems similar to a pawn), but it just seems like it'd be more fun.
Any of these options was a major dedication that would require lots of work. But in the end, I went with #3 and I'm so glad that I did.

I started off creating a sort of horror-feeling map where you moved slowly and had very limited ammunition but I quickly realized that I wanted something more like a power fantasy.





I also realized that the existing weapons & enemies were definitely balanced for an RTS-style game and not for one where you were controlling a player. So I deleted all existing weapons and enemies, grabbed some demon textures I had laying around, and made a demon map. It was insane how well it instantly worked. It only took half a day to program a new AI script for the demons to use, a ranged demon enemy, a weapon for the player to use and a map to test it all on. And after that went so well, I worked on the map some more & added a melee demon enemy, and here we are:







Player Body
It took about half a month to program a body for the player to control that had all the same systems as a pawn like equipment, inventory, visuals, combat, movement, health, a new camera and more. I could've potentially just had the player control a pawn as they already existed, but I wanted the player to use completely separate systems so that way they could be changed & polished to better suit a player without effecting pawns. This has meant I've been able to more finely polish player movement & combat than what would otherwise be possible & I think that the positive feedback from testers has shown that it works.

New Pawn AI
I'm proud of how the tactical AI I programmed in the last update turned out. There are still some problems with it but overall it works really well. But enemies that hear gunshots, investigate, take cover, etc. just doesn't match a game about running around killing demons. I remember watching an Extra Credits video (link) about developing AI that best suits the game which sometimes just means having a few simple AI rather than 1 complex AI system. So I thought I'd do just that, after all, the enemies in DOOM felt fun to play against and they boiled down to "Wander in place, chase the player where we last saw them & attack the player when we have sight". So I created my own pawn brain to mimic those behaviors. 

They don't wander yet because after just implementing the last 2 they already felt more fun to play against with this new style of game. This less complex behavior also means they're easier for the CPU to handle. I didn't delete the old pawn brain so I or any modders can use it in the future, I'm glad I had the foresight to write the system in a way that supported multiple brain types!

UI
Most of this speaks for itself from the previous screenshots. There's a new player UI, weapon UI, and game cursor. But something I haven't shown yet is the engines new error screen:




Although not all errors are going to be so straightforward. Sometimes you just mistyped something in the mod file, in which case you'd get a generic JSON error. But at least this error screen tells you which script you made the mistake on:




Having all the games default content be its own mod has let me see things from the perspective of potential modders, so from pretty early on I've implemented systems for debugging what could go wrong when developing mods. For awhile those have been restricted to just being error messages that wrote to the console and I had every intention of keeping them that way & modders would just need to check the games player log to see what went wrong. But I decided that it wouldn't take long for me to implement something easier for modders to see what went wrong so I made the UI. It'll also serve handy in the future as being a popup for potential important errors that could occur in the game.

Campaigns
There's now a "Campaigns" file in mods so you can create your own custom campaigns too if you should choose.




Campaigns can be a series of maps related to each other (a story) or just a pack of different maps. All you have to do is have a campaign name, a thumbnail for it to use, and then all you have to do is write down what maps it'll include in order. When the player launches the game, any campaigns that are loaded from mods will check if they have a save file & if they don't, create one. That's right the engine now supports saving player data too!




Map Editor
The map editor is now a separate application from the main game. This was necessary in order to implement campaigns. The problem before was that since the map editor was a part of the game, you couldn't cache maps because you had to assume they might be edited. But reading all map files every time you need to access map data is extremely slow & led to opening the campaign screen taking ~5 seconds. That doesn't sound like much but consider there were only ~6 maps in the game at the time, as that number increases it'll get worse and worse. So now loaded maps are stored in RAM (cached) when the game is loaded so their data can be quickly accessed in-game.




Now, since I'm developing an engine more than a single game, I've almost always taken the harder option among many easier alternatives. The engine didn't need to have multiplayer which doubles development time, and I didn't need to make the multiplayer super secure by using the server-side authoritative model. It certainly didn't need to have mod support which also increased development time. I didn't need to go as far with mod support as I did, etc. But I did it anyway because this engine might be used for many games to come, and I want it to be the best it can be. I was presented with a similar dilemma when I wanted to add a win trigger to the level. It would've been easy to just program a collider that when the player touched it made the level end in victory & then to have the player place it in the map editor. But I'm so close to being done with most of the major engine features & being ready to focus on just the game, so why take the easy route now?

So, I've been working on a new major feature for the map editor: Map Events! I used to play a lot of WarCraft 3 when I was younger & loved using their map editor. The map editor included a map events system that let you program events without using code. Now I'm not going to make it quite as complex as theirs (I'm just a one-man team after all!) but having something like that in the map editor would let me & other map makers make truly unique levels with different events.




Each map event boils down to having triggers & actions. The event which every map will need to add will be when the player touches an area trigger to make the level end with a win. Even though the map events system is complete, I haven't finished area triggers yet which is a priority for my to-do list, so soon players will be able to complete levels.

This was a more time-consuming undertaking than I originally thought mostly with figuring out how to get the data to save & load to maps properly. But I'm glad I went the extra mile to do it.

Improved Pawn Performance
With this game pivot I saw a great opportunity for improving performance. About 45% of the games CPU usage was pawns trying to determine targets. That may sound like it's a really unoptimized calculation but it's in my opinion just a testament of how well optimized everything else is. It is after all having to do many line of sight checks which involve physics & can be expensive.

Because it was such a major part of performance, I wanted to do something about it but after optimizing it so much last update I wasn't sure where I could make any major difference. But then I realized because the game pivoted I could make so in a pawn file it was optional if pawns could target other pawns. After all, if a pawn solely exists to attack the player, why should it check if other pawns are targets? So for each pawn you can now configure if they're able to target other pawns or the player:




How much performance does this save? Well tests showed that when pawns were set to not try to target other pawns, their performance improved 256~161% depending on how many pawns the level contained. That makes even more sense when you consider that because each pawn must at the very least perform a distance check to every potential target & then do a line of sight check if they're close enough. That means the CPU usage of the pawns combat system scales exponentially with the number of potential targets. That also means reducing the number of potential targets exponentially improves performance!

This doesn't mean the engine can't handle pawns which target other pawns, it just means if you use pawns that do you'll just have to use less of them to get the same level of performance.

Closing Notes
This update was pretty massive & required a lot of work but it's all really coming together. I've been letting some of my close family & a few other people play test a test level I made, and the feedback has been more positive than the testing was for any other game I've made. This makes me think I really have something good going.

There are 2 big things I want to finish before focusing on game content, those being finishing area triggers & adding a cinematics editor. The area triggers shouldn't take much longer since I'm already pretty far with them, it's the cinematics editor that's going to be time consuming. I want the game to be able to have cutscenes. This will be useful not just for while you're playing a level but for the start & end of a level too. I haven't decided how I want to tackle this problem & how in-depth I want to go with such an editor so I have no idea how long it'll take, but it's another one of those things I know I don't need to make but that I feel the engine could really benefit from & since I'm so close to the end, I might as well uphold my record of going the extra mile.

That's it for the major changes, but trust me there were a lot more. You may have already noticed some of them as there were many visual improvements to both the game overall, combat, and effects. If you want to know them all then be sure to read the full notes in the summary at the bottom of the blog. And as always, thanks for reading!

-Blake Gillman