Sunday, August 8, 2021

Project Breach #8 - "Finishing the engine (2/2)"

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:
  1. 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.
  2. 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
  3. 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:
  1. Games that are 2D
  2. From a top-down perspective
  3. In which you control a player and
  4. 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


Extras

>Lines of code written:
33,210 lines / 377 scripts.
(+1,459 lines / +31 scripts since last update)

Notes & Technical Extras

>Doubts, Regrets & Mental Health
I doubt my ability as a game developer and designer. I think I'm a good game programmer and programmer in general. I actually think I might be one of the best when it comes to Unity specifically. I mean how many other people could create a game engine (even if on top of Unity) with a voxel engine w/ hybrid renderer, map editor, all the gameplay mechanics it has, mod support, and all built on a client-side network architecture model. The time it was made in also being impressive, and even more so considering the amount of pivoting. But I said it: I make great tools other people use to make great games, that doesn't necessarily mean I'm capable of great games myself. That realization hit hard and it's not like this is my first game but it's the first one I've really thought about these questions.

Do I regret making the engine and would've preferred to just make the game without it? The answer to that question depends on my mood that day. I go between "This engine is awesome, it's a combination of many of my interests as well as some of the cleanest code I've written. It'll make making future games easier and could even be a commercial project on its own" and "I could've made an awesome game in the amount of time its taken me just to make the engine. And here I am programming multiplayer again which I hate & said I wouldn't do. Working on this engine feels like Atlas holding up the world & it's so big it can feel like walking through honey, diminishing returns and all that". So take from that what you will.

Above all, my mental health has been out the window recently. I've had chronic depression for most of my life at this point (being 21 at the time of writing) but I thought I'd finally gotten past it last year. And for months that was true. But here we are again. I think it's a little bit of everything. I haven't released a game in 2 years, I'm skeptical that I'm even capable of making good games despite people enjoying my previous ones. I don't know what I want out of life, what do I have to aim for that is so intrinsically correct that it justifies my suffering? Not to mention the current political state of the United States, which I'm so tired of and want to say "Don't worry over stuff you can't control" but it's really scary the direction this country is headed with the rise of authoritarianism and modern liberalism. Sometimes I think I'm going to have a panic attack at night thinking about how we have more debt than U.S dollars in circulation and hyperinflation could come at any moment and destroy my savings. I wonder what it must've been like growing up knowing there would be no civil war, that you could save for retirement, and that humanity would strive for greater enlightenment. It's making me feel pretty hopeless for the future.

I'm writing this down now because I know my mood will probably change tomorrow. I'll sleep on it and realize that objectively things are pretty good and my game will probably turn out fine and I shouldn't worry about things I can't control. But I'm writing this anyway because it's a glance into where my thoughts go every few days or so. I used to find enjoyment in reading and watching lectures on topics like economics, politics, and especially philosophy. But I've stopped reading altogether, my memory problems are so extreme that by the time I finish a book I've forgotten what was written in 90% of it, and by the next year I won't be able to remember more than a few sentences. Sometimes I think that if I retained any decent level of memory I could call economists and philosophers my peers with the depth of my knowledge. There's a fair bit I remember but I know it only scratches the surface of what I've studied. It's not too much of a stretch to say I've forgotten more on the subjects of economics, philosophy, politics, and theology than most people will study in their life. And so not even my hobbies outside of game development bring me joy anymore. Sometimes I think the only reason I've maintained an interest in them for as long as I did is because I'd just forget that I'd read & heard it all before.

I'm also having problems with sleep. No matter how much or little, no matter what schedule, consistent or random, I'm always tired. I swear it didn't use to be this bad but then I remembered that before the start of this year I drank Mountain Dew every day for basically this exact reason and only stopped because I don't want to get diabetes. I believe the term is narcolepsy but I don't want to self-diagnose. I've fallen asleep drinking Red Bull. These memory problems & sleep problems have been with me my entire life. Hard to feel optimistic when you'll forget everything & be tired all day. In fact, I bet there are many accomplishments and good times that I could look back on to cheer me up if I could remember them. But lucky for me, emotions are associated primarily with strong emotions particularly negative ones (negativity bias), so there's plenty of bad to keep me awake at night.

Sorry if that's depressing, like I said, I'll wake up tomorrow, and objectively things are good. But a few days later or a week or so, my thoughts will drift here again. I'm hoping to complete this game & hopefully seeing it achieve some success will fill the hole in my life. I'm glad I took that break, it'd been a while since I've been able to enjoy gaming.

Blog Summary

>Notes used to create this post
=====[ Before Break ]=====
Player:
-Changed camera zoom
-Created an entirely new interactable system which can be used by anything (Players, Pawns, or just the Server). Also made so this interaction system can have timed interactions (hold down)
-Added inventory pickups
-Added currency to network inventories & loot tables
-Added currency-only drops
-Got rid of the slow camera sway effect
-Fixed player jittering with the camera
-Made bloom less obnoxious
-Added camera effect "rain"
-Reduced camera interpolation
-Made so player direction is based off of where they're aiming not moving
-Made so player only displays left/right not up/down
-Made so camera shake takes into consideration depth/orthographic size (zooming)
-Improved player aiming, both feel & got rid of bugs (Now uses the system created in Black Company 2D)
-Made so when the player dies they create a corpse
-Made so when player dies, it acts the same as if input and movement had been locked
-Fixed other player's atlas index being based off of local clients aim position and not that players aim position
-Made so player aim position doesn't network update if the player dies
-Made so the player's weapon rotation doesn't update if they've died
-Created GameOverManager.cs & moved "OnPlayerDied" code from player health to it

Gameplay:
-Created threaded loot table systems
-Map now won't start until all players have finished loading the map
-The server now auto assigns slot indexes & teams to players
-Increased blood splatter lifespan from 5 minutes to 10 minutes
-Fixed host not checking for network objects attached to chunks when clearing the map
-Made the game no longer use fog of war lighting (Potentially might add back later)
-Made so game automatically restarts if a player dies
-Made so a map can be won & lost
-Made so you can now write map save data to a campaign file & that it only writes if it's better than what it was previously (i.e higher score or faster time)
-Made game track how long you've played on a level so it can update your best time if you win (NOTE: This is tracked by the server and not per-player so that way its consistent for everyone)
-Made an option in the campaign file so players can't play the next map in a campaign until they've beaten the previous one

Combat:
-Added option in weapons for it to require reloading but not require ammo in the players inventory
-Weapon accuracy is now based on the speed of the user
-Fixed error caused by switching to weapon slots with no weapon
-Camera now shakes when the player takes damage
-Fixed a bug where semi auto weapons required right click instead of left click

Pawns:
-Made so pawns can drop items on death
-Made so pawns no longer use ammo from their inventory
-Made in pawn file so you can customize how fast a pawn repaths
-Fixed pawns not being able to be assigned to a slot
-Fixed pawns aiming weirdly (Now uses the system created in Black Company 2D)
-Fixed bug where a pawn goes to (0, 0, 0) if they take damage but don't know where their target is

UI:
-Added interaction UI
-Made so the player can see the pawn stats bar (health particularly)
-Made so the pawn UI clears when a pawn dies, not waiting for the object to destroy (since it takes a few seconds after death)
-Redid the player cursor system, which expands/shrinks to reflect weapon accuracy (Which takes into consideration both the speed of the player & the distance away from themselves that they're aiming)
-Fixed pawn & interactable UI not tracking exact object positions when camera moves quickly
-Started on a player hub UI
-Created a game over UI
-Created game win UI (From which the player can return to the main menu)
-Added cinematic text UI

Project:
-Got rid of all old code related to the RTS portion of the project
-Unified map loading logic (From separate game/editor loaders)
-Optimized many internal mod object utility scripts such as those responsible for retrieving mod objects. Mod Objects no longer require an enumerator.
-Cleared most of the existing mod textures and data to make room for text data/textures
-Make "Texture Tiling" in block files automatically divide so user doesn't need to type elaborate decimals. So 1/x.
-Renamed all things "Pawn Dialogue" to "Pawn Prompts" since if an actual dialogue system is added in the future, it'd be confusing
-Added value to inventory items
-Started on a shops system. Have good data structures & mod files but isn't actually being used anywhere in the project
-Made PawnCorpse.cs into a generic CharacterCorpse.cs so it could be used by the player
-Made so loading a new map always clears the previous one
-The server can now track what campaign & map you're playing on

Map Editor:
-Added new map events
-Added player spawns
-Added a "gizmo frame" to all map editor gizmos so it's obvious they're icons for the editor
-Map editor will alert you if you save without any player spawns
-Fixed some internal errors caused by the engine trying to place or remove objects where ones already exist / nothing is there.
-Made "ModsUtility.IsValidMapName" take into consideration illegal characters
-Fixed bug where map effects (clouds) were still visible after a map is cleared
-Made ambient lighting default to (155, 155, 155)
-Made pawns, players, and drops clear when the map cleared
-Finally fixed PEColor32.white being red
-Made map event generic string inputs longer & so they don't show rich text
-Fixed some map events unnecessarily doing a "body null check"

=====[ After Break ]=====
Combat:
-Made the damage numbers & health higher
-Increased player & enemy speed

Gameplay:
-Created a test map
-Created a performance test map (512 pawns)

Project:
-Fixed FModFile.cs considering all files in the "Maps" folder a map
-Made missing file (ReadFileBytes) cause an engine error
-Made missing audio files cause an engine error
-Made errors on "ReadBinaryFormat" in FileManager.cs create an engine error
-Fixed FModFile.cs considering all files in the "Biomes" folder a biome
-Made BaseCache.cs "AddCacheData" error cause an engine error
-Made failed entry grabs in BaseCache.cs cause an engine error
-Fixed music ID lookup in environment screen in map editor causing an engine error
-Fixed mod objects not caring about lighting
-Improved complex lights casting shadows on walls
-Separate default engine content & the games content into separate mods (PE3) & (Main)
-Updated JSON files to use more visible properties where appropriate & organized JSON files formatting a bit

UI:
-Expanded engine error screen text so it can take up more of the screen
-Made the mods loading engine errors highlight in a different color the mod that caused the error so it's easier to read
-Added component UI for player body spawns

Map Editor:
-Added new map events
-Fixed maps manager not updating selected mod when selecting a new mod
-Added player templates which player spawns can use
-Made so its optional if player templates start with their weapons loaded
-Made so complex/sprite lights start at 0.5 intensity
-Made sprite lights start at the same size as a complex light
-Made so the players health & movement variables can be adjusted in the player template file

No comments:

Post a Comment