Project Breach #8
"The engine is finished! (2/2)"
The engine is finished
This is it, and what a journey it has been. It's easy to see a game engine like RPG Maker and think that it's quite simple, but these last 7 months have taught me otherwise. It's not where I expected to end up when I started writing another one of my random voxel engines all those months ago, but here we are. Phase 1 of my very own game engine built on top of Unity is complete. A working engine that I can use to make games with.
This update focused on 3 things:
- Finding out what core gameplay features were left to finish, I'm sure there are many more I'll discover once I start making a game with it, but there were plenty I could think of to do now.
- Getting rid of all test systems (like having to press Ctrl+Enter to spawn at a hard-coded position) and replacing them with final ones
- Making sure the engine can be used reasonably on its own without Unity
There were even several systems I started on, some of which I even got pretty far on, which I then dropped because I realized that although they'd be cool additions to the engine, they weren't necessary for the game. The code I wrote is still there should I decide the game could use them.
This update is definitely the largest I've done so far. So for this update, I'm not going to go over every change one by one, if you want to see those you can read the bottom of the blog post. I'm just going to go over the ones I think actually matter.
So far everyone who has tested it says it feels better than it did before so I'm excited to share with you how I got there. The update splits into two parts, before I took a break & after I took a break, so without further ado lets begin.
Before I took a break
Making way for the new
Remember when this engine was an RTS/Strategy game for a few months? Well, a lot of that code was still lying around and I had left it there just in case I ever wanted to use it again. But having lots of old code clog up the engine was getting annoying so I saved it somewhere safe (a separate git branch) and deleted it from the engine. It only occurred to me afterward that I should've counted how many lines I deleted but my guess was somewhere between 1.5k and 3k. So for a while, this update had less lines of code than the last.
After that, it was time to update some of those old systems to the new & move forward with finishing the engine.
Combat
Starting off on a strong foot, I wanted to make combat feel juicier, after fixing any remaining bugs with it of course.
The camera now shakes when the player takes damage and the shake now zooms instead of just swaying you side to side. The players and pawns accuracy with a weapon are now based off of how fast they're moving. These two simple changes were surprisingly effective at making the game feel more responsive when taking damage and give a little bit more consideration to the player about moving.
And finally, after watching 3klikphillip's "The Game Making Journey" (for the third time) he mentioned in one of his games questioning traditional game mechanics like reloading. Although weapons already had the option to not use ammo, it made me think a bit outside the box and add the ability so that the player could have to reload a magazine but still have infinite ammo to reload with. I think I prefer this as having to loot ammo would only take away from the action I want the player to be constantly engaged with.
Gameplay:
And of course, with all this new combat, I needed the player to be able to die without having to restart the game every time. So I spent time making so that when the player dies, it will lock their controls, create a corpse, then show a game over screen. Then after a little bit, the map automatically restarts.
Well now that you can lose I figured the player should also be able to win. So now there's a map event action which will make the player win the map. It also now tracks and saves their time so they can see their best on the menu.
And of course it wouldn't be Project Breach if I didn't add some customization for modders. If you want players to have to beat all of your campaign's maps in a row or if you want them all to start unlocked, you have that option:
UI
The player can now interact with things just as pawns can. For this I created a nice interaction prompt:
The player can now see a pawns health. This was actually already a system in the game back from when it was still an RTS, it's just that the UI was only visible if the pawn was friendly. So all I had to do was make so the UI appears when the pawn is an enemy too. It had some other bars like showing the pawns cooldown and amount of ammo remaining, I left those in but only for friendly pawns so for enemies you just see the health.
Since I now have 2 UI which track an object in the world (Interaction UI & Pawn UI) I needed to improve the code responsible for tracking them because when the camera was moving fast, the illusion would break. Thankfully I was pointed in the right direction & shown "World Space" canvases which were exactly what I needed, I just had to do a little tweaking to the UI themselves.
I've also redone the players cursor system so it'll show you how accurate your shots are going to be. It does this in 2 ways, first by how fast you are moving and second by how far away you are aiming.
And finally for UI, I added cinematic text. So now during cutscenes you can show dialogue, or use it for whatever else.
Map Editor
Mostly what I wanted to do with the map editor was focus on making sure it was user-friendly and bug free so when I start making a game with the engine, I don't need to worry about it.
Besides that, I also added some new features. You can now finally create player spawns! For the longest time, it was hard-programmed into the game that in order to spawn you had to press Left Control and then Enter. Left Control would set your players team and then Enter would spawn your player with some test gear at the coordinates 10, 10.
Between this and adding the ability to win & lose, it actually feels like I could make a game without having to give people a list of instructions like I've been doing:
I'll throw this out here, while finding that image I found one of when one of the testers played with the mod files:
And him testing the version before that where the walls accidentally had health & he broke out of the level:
Since the beginning of the project I've been tweaking the lighting but I actually recently got in contact with the guy who made the light system the engine uses and after a short conversation with him I was able to finally get the lighting looking how I've always wanted it to.
And of course, I added many new map events.
Player
I decided to get rid of the camera sway. It made the game feels slightly more cinematic but ultimately just felt like unfairly throwing off the players aim. I also fixed a jittering problem with the camera tracking the player so now moving around the players visual quality stays much more smooth.
I also added a new camera effects system. Currently, the only one being "rain" which you can turn on & off with map events.
The player's visual is now based off of where they're aiming not where they're moving. And the player only shows left/right instead of up/down. This was a style I did for my GMTK 2021 game jam game and it felt really nice so I implemented it here:
Project
There were some old systems lying around that were bothering me, that I knew when I made them would eventually need to be rewritten once I came up with a better solution. Things like looking up a mod object by ID when you don't know what type it is. Well those systems are now much more optimized which should help to reduce any lag spikes.
There were also some quality of life changes. You no longer need to use decimals when deciding how much a block tiles. Originally to make a block's texture take up a 2 by 2 area you would put the scaling as being 0.5. The scaling formula was just 1 divided by however many tiles you wanted it to cover. I've just made so that calculation happens internally so now if you want a block to take up 2 tiles you just put 2. I also renamed all previous systems called "Pawn Dialogue" to "Pawn Prompts" since I might add an actual dialogue system in the future and don't want the two to be confused with each other. Also previously I had 2 different map loading scripts, one for the map editor & one for the game which were 80% identical. I was able to merge them into one system so now when adding things to the map system I only need to do it once.
And finally, for these changes before the break, I cleared up most of the existing data. No more wood walls or demon enemies. It's all test objects & textures now. This is so I'll have a clean slate when starting on the new game. You may have already noticed that from the screenshots & GIFs.
And with that, I considered the engine officially ready to make a game with. After my break I'd learn it still had a few more tweaks to be done in order to work on its own, but for the most part, this was finally it.
Taking a break
I've talked before about needing to take a break but I really did need to. I won't go into too much detail, but I will say that I've never intentionally taken a week off of working on projects. Not since Middle School when I first got into more serious game development. I've never taken a vacation from working, and I work almost every day including weekends. Here's what I wrote at the time:
"I've talked about it before but I'm a bit of a workaholic, I don't know how to spend my free time doing things other than working. I don't even take weekends off. So I decided now that I've finished up the engine, before I start on a game with it, I'm gonna take a break, refresh myself, figure out how to exist without working all the time"
Now, I was still doing my full-time job but just not doing personal projects. I spent most of that time playing Old School RuneScape and had a constant craving for work, I felt like an addict going through withdrawal. It almost felt like the only way I could stop being obsessed with working all the time would be to replace that obsession with something else. Eventually, I branched out into playing Counter-Strike: Condition Zero (Released in 2004) which I had never played before & I actually had a ton of fun playing it. It felt good to really enjoy a video game again since for a while its felt like games have been kinda... meh.
Since then I've bought Darkest Dungeon & Ultrakill and I'm actually excited to play games again. With only 100 minutes Ultrakill has quickly become one of my favorite games of all time.
I haven't been cured of being a workaholic, and I'm not sure that I could or that I'd want to. But finding a balance between work and life is clearly something I haven't done & it's more apparent than ever that I need to. This break helped me figure out at least a couple of methods of avoiding work & how to be more engaged in the things I do outside of work.
After I took a break
Working without Unity
Before I published this update, I wanted to get at least a test map with some enemies going so that I had something to show of the new engine and make sure that the engine could be used without Unity. It took a few changes to get there, but eventually, I was able to prove the engine could comfortably be used on its own without Unity. I even managed to get a good visual studio setup for it (since it's all JSON files & a map editor):
Combat
Stumbling on the game Ultrakill by watching a FUNKe YouTube video was a dream come true. I really wanted my game to be inspired by Enter The Gungeon but I hate to say that game felt like it was close to being fun, but never really did it for me. Ultrakill however has given me infinite inspiration and is likely to continue to be a great source of it for the length of the entire project.
One big change I made was to increase the player and the enemy speed. This one change turned out to be the most important combat tweak I had ever made. Immediately the game felt more responsive & action-packed.
(The cursor is black because I had to make the game window really low resolution in order for the GIF size not to be too large which made the cursor downscale) |
After that, I increased the health and damage numbers so that it felt like you were packing more of a punch and with these two changes and the previous ones the combat really felt strong and is making me excited to add more enemies and experiment with level design.
Gameplay
I created a test map for the player to play on which also utilizes the new lighting. It's really basic but it plays better than previous test maps and I think looks much better.
I was also discussing the topic of A.I with my friend Phineas and thought my game could probably handle about 200 pawns at once. But then I remembered I did the optimization of making so pawns can only target the player and wanted to put it to the test. So I created a map with 512 pawns and to my surprise, it ran fine. But I have a good PC, I was still expecting that many to crash a lower-end computer. To my surprise once again, the lower-end PC I tested it with ran at 30fps with the enemies idle and only got as low as 8fps when all 512 enemies were trying to fire projectiles at them at once. Considering I was expecting them to crash once those shots were fired, that's awesome. It means I can safely have 100~200 pawns in a map and still work with low-end PC's. And there are still many optimization techniques I could apply to get this performance to be even better.
Map Editor
I added player templates. This allows you to specify what gear & stats a player starts with in a map. Because there are no item pickups at the moment, this might be a good way to do progression. You could gradually start with better gear or health or speed. It also lets you define what visual the player has.
Project
A big thing I learned about having the engine separate from Unity was not having access to the editor console was a pain. So I made sure to add plenty of errors & warnings into the engine so if something went wrong you could figure it out without needing the Unity console. The cool thing is that I'm not the only one who benefits from the engine being self-sufficient as modders will also have an easier time debugging their mods if things go wrong.
There are also now 2 mods that come with the game. One is "PE3" which contains all of the engines default content like a test player, prototype blocks, and some other things. Another is "Main" which will contain the content for the actual game being made with the engine. The goal would be that the game eventually doesn't use any of the default engine content, but that the default engine content is there so that when first starting on a game you have something to prototype with. Some other of the default content include things that the engine needs in order to operate such as the "Air" block which needs to be in the engine & always have the same ID.
Closing Notes
So here we are. It feels weird saying the engine is done. I don't think in my heart I could ever consider it done since there are a million things I'd love to add and parts of the project I'd like to redo as I've learned so much. But this is it. Phase 1 of the engine where the engine is capable of making a game but doesn't have an application UI, is done. A version of the engine for my own use.
This marks the end of the Project Breach blog posts. Project Breach started off as a voxel engine, then became an RTS, then it became a top-down shooter, and finally it became an engine for:
- Games that are 2D
- From a top-down perspective
- In which you control a player and
- Does not require programming knowledge
It's likely I'll eventually make a public version of the engine where people can make their own actual games with it. But that's something I'm not going to think about for awhile. Right now it's time to make a game. I'm sure there's still plenty of programming ahead of me as the game takes shape & I think of new features the game needs. But the days of programming big systems every day are over.
Project Breach has come to an end, but my new game, Project Fire has just begun. I'm nervous, I think I'm a pretty good game programmer, but game designer? I don't know. As a programmer, I make great tools that other people use to make great games. But I realize that there's a lot I don't know about game development and design itself. Level design, audio, game feedback & art. It always felt like these were things I never paid much attention to with my previous games and often just by throwing stuff together somehow managed to make games people enjoyed playing. But I want to think about it now. There's a lot for me to learn, truth is, this almost feels like my first game in a way because it'll be the first time where I actually really think hard about these things instead of just rushing along. Where most of the game development will be the game and its content and not the programming. I'm not after making anything big, but I still question will I be able to make something fun & really better than what I've made before. I want my games to be successful, not just pay for themselves but to be successful enough to pay the bills.
So with all that, with this new project ahead of me and all this learning to do, I'm going to take my time. I'm going to spend the extra time to study, polish and iterate. To make not just a fine game but a good one.
So with that, I start Project Fire. The blog posts will continue but they won't be the same. Instead of going over every change like I do now, it'll be about how the game as a whole changed each update. I want to spend less time writing about making the game and more time actually making it, so they'll also be less frequent.
Already even with this test level testers are saying it feels much better than what's come before it. So, here's to Project Fire. And as always, I'll see you guys in the next update.
Sincerely,
Blake Gillman