Sunday, 24 September 2017

XZ-03: Post-mortem

It's been a while since I've posted anything here! I mostly use Twitter these days for talking about what I'm working on but I figure it's easier to write longer stuff here. Writing anything of any length on Twitter makes it read like the ramblings of a madman. Which it is but that's besides the point.



XZ-03 is finished and you can now download a copy here. I actually finished the initial version about a month ago, but I've been going back to it every now and again for the past few weeks to tweak and balance a couple things in relation to feedback. I've also added a couple of features, mostly backend stuff to smoothen the experience out but I've also gone ahead and added a stat tracker so you can see fun things like the amount of enemy aliens you've slain, bullets fired and time played! I love things like this in games so I had to go ahead and add it. I also vastly improved the look of the UI with only a few simple boxes. There maybe an update or two coming during the next month if any bugs or other issues arise but at this point XZ-03 is officially a finished project. My first in Unity! The project itself was really enjoyable and challenging to work on & I'm so glad I decided to put in the extra energy to finish it. That said I am burntout as all hell and will probably be taking a week or so off from gamedev to just chill. Well chill and look for work. Which is like the opposite of chilling.

Also of note is my entry into Ludum Dare #39. For those that don't know Ludum Dare or LDJAM is a sort of challenge/competition where participants are given a theme and 2-3 days to make a game from scratch. While I've entered a couple of these in the past I've never put much work into it but this time around I decided to give it a real try. The result was a short platformer game called "Delivery To The Underpass" which you can give a try here! It actually did really well and helped a lot with XZ-03's process as it worked as a fun playground to test out Unity's post-processing effects and audio functionality.

As the Mood category was one of my main targets I was incredibly happy with the result.
Graphics is another big one for me as well, as I am not an artist in any sense
so to nail a high mark like that is a good sign I'm improving!
Placements are out of 1361 jam entries.

But now back to XZ-03, and why I made it.

The Goal:

I started this project with the goal to make a game covering many various mechanical techniques and bits of functionality that I hadn't used in Unity before or at all. Things like: more complex AI spawning & functionality, randomisation of various elements and locations (object spawning), object pooling, weapon selection, pausing, UI menus, turret building (a big one for me as I love Tower Defence games), volume options and many other little things. In addition I wanted to put additional effort into 'game feel' and graphical/post-processing effects to make a game that plays and looks just right, as poor graphics and a lack of what I've taken to calling "Gameplay je ne sais quoi" have been common elements in past projects. All in all my goal was to use this short project as a jumping off point for Unity. Learn how to use the engine proper, get some stuff in place I can use for future projects & even get some experience I can put to use for an actual job!

So. What went well?

What went well:

For the most part I achieved everything I set out to do. And more. I managed to make massive progress with the programming side of things. I wrote a bunch of scripts to handle various useful bits of functionality that can easily be transferred into other projects. For example, I wrote a neat ass daylight script that effectively handles light intensity (brightness) based on ANY length of time (effectively emulating a day/night cycle) & a reusable object that can control the audio in my projects and link to simple volume settings. The former while not reusable among many projects, the mathematical functions themselves (which use a percentage to affect variables between 0 and any other number) can, and will be used again. The latter however is something that I will most certainly be building upon in future projects as I am a huge fan of audio as a dynamic component in games & would love to work more with such concepts in future games.

I also got around to learning and in some cases better using other programming techniques & features of Unity. For one, I finally got around to learning object pooling. For those that don't know, object pooling is a way of handling the creation and destruction of objects (sometimes many 1000's of objects) by creating them all at the beginning of a level and deactivating them. Then, during gameplay, if an object, let's say a bullet, needs bringing into the game, this collection of pre-created bullets is searched through for one that is currently deactivated. It is then activated, given some properties (direction fired, bullet speed, damage, etc.) and let loose. Upon hitting an enemy or wall instead of being destroyed it is instead simply deactivated. and thus available to be "pulled" again. It seems long winded, especially as creating (Instantiating) and destroying objects is so simple & readily built into Unity. Problem is it's also REALLY intensive and thus a game with lots of bullets, enemies and pickups (kinda like this one) slows down terribly. This system allows me to have games full to the brim with stuff & things, with minimal worry about in-game slowdown. That said it does increase the initial load time of a level so it's not a "silver bullet" by any means!

Creating a bunch of bullets (400), giving them a basic name, deactivating each one,
then adding it to a list for later use.

Searching through the list of bullets until one is found that is deactivated.
We then pass this bullet object to wherever it needs to be used!

We take the bullet that was passed  through (if one was found!) and
give a bunch of info for it to use. A direction, rotation & speed for movement.
Various stats for mechanical effects. Then it's activated and sent on it's way.

Another thing I tried for the first time was some element of random-generation. It's something I've surprisingly not gone near before. I say surprisingly because it can be a really effective way to build games like roguelikes & dungeon crawlers and other types of explorative games. Some of which are my favourite games! It also saves a lot of time on level design, although that time is passed into developing the random-gen so... not always the best solution. All in all I made a compromise with building the level manually but placing elements, mainly crates & escape pod parts, in randomly chosen locations. To me this gave the game enough randomisation that players wouldn't always go to the same few points of interest to beat the game but not so much randomisation that they could still learn where the various points of interest were on the map. This meant they could still find where in the crater they were, which was especially important as I chose not to add any sort of map (only a short-range compass) in-game. The code itself actually works by searching through a list of placeholder objects placed around the map, picking one at random, spawning a crate or part at it's location and removing it from the list. Once enough of each type of object has been spawned it destroys any remaining placeholders to leave only "randomly" placed objects. While it's not much this is just the start, and I definitely plan on working more on this sorta thing in the future.

On the graphical side of things, this was the first game I've truly put some forethought into graphics, and use of graphical design principles I know about, but have yet to properly implement. Examples include: using graphics as elements to aid player decision (light components on defences to show range), use of graphics to set mood, specifically increasing tension (growing dust storms and particles in ratio to difficulty increase & to affect players ability to see), thematic effects and overall style (using a limited palette but using post-processing to apply a red tint & other effects to the game, giving it a more distinct look).

During day the red tint is low. At day one the dust storm has yet to arrive...

At night the red tint is much stronger and by day 21 the storm is here!

I put a lot of effort into the graphics themselves as well. It's the first time I've even attempted any sort of perspective before and while it shows in a few places some look pretty damn good. I made vast improvements on shading in pixel art and thanks to Aesprite I started to get a handle on some animation as well. By no means is it anything special but it is still a massive improvement over what I used to draw.

A Mining Droid. Somewhat suggestive but nicely animated.

The Mechanic Turret (Terrible Name).
Perspective is a bit wonky on this one but it still looks great in-game.

HIGH QUALITY TWO FRAME ANIMATION!

As concentrating on game feel was a big part of this project I'm super glad with how it turned out. Putting the effort into making the camera movement feel smooth and adding an effective and variable screen-shake system (I can edit both how strong and how long I want the shake to last whenever I want) made a huge difference to the quality of the game. It's an especially good accomplishment as I've written the scripts in a way that I can easily use them again in later projects. Hell, I used the same camera script in my LDJAM entry, albeit with changes on the camera movement from following the players mouse to shifting between positions based on player input. I also made sure to follow other simpler game feel principles, big ol' bullets, bassy sound effects & hordes of enemies. It really made a big difference to the overall outcome of the game and it is something I'm going to keep in mind for future projects. I highly recommend anyone wanting to look into improving the 'feel' of their game to check out this video, as it's made a big difference for me!



Of course not everything goes great when making a game, in fact most of it goes wrong most of the time, but that's all part of the process! While I was able to solve most of the problems I wasn't able to solve them all. On top of that there are some other aspects of making game I struggled with during this project...

What went wrong (and how I learnt from it):

Let's start with game issues first, yeah. So while I covered a veritable multitude of techniques and mechanical methods and other stuff I still wasn't able to get everything I had originally planned into the game. Now this is common. There is a term in most development disciplines called scope. Scope is a definition of the boundaries of the project. It's a way of making sure that a small project doesn't keep having features added to it. In software this could be a list of features and functionality that the product should grant to a user. Perhaps your software can do X & Y but Z would be a step too far. Z might take more time to develop, rely on X & Y already being built and working near bug free, be too expensive or be otherwise not of interest to your target demographic. While XZ-03 had a big ol' list of things I'd personally like to add to it, adding these mechanics and features would've added too much time onto the project without additional help.

Trello list of ideas. Some fully implemented,
some half implemented. Co-op was off the books
as soon as it became a 1 man project.

All in all though, most of the important stuff was there. Bar any multiplayer functionality (which would've made the dev process & game much different) everything else was just increased complexity. It would've added to the games quality, if done well, but could've still been a mistake to add. We'll just never know.

So what of the stuff I did put in? Any issues there?

Short answer. Yes.

Long answer...

Even now, post final update, enemies will still occasionally botch their path-finding. I'm not one hundred percent what causes this, but enemies will just sometimes glitch out and get stuck in their current location. I've tried various things to no avail. It's nothing major though as it's an incredibly rare event (both when it appears and how many enemies it effects). It also doesn't affect more than 2 or so enemies at a time across the whole map (out of a max of 200 enemies) so it's also unlikely to be seen if it even does occur, but I know it's there and it bothers me. Apart from that the path-finding is actually really good. I actually went ahead and bought a 2D path-finding asset from the Unity store because at the time I was aiming for a 3 month deadline. Which I hit! The scripts and other assets can be found here, and despite the issue that I've had it is a fantastic tool and I still recommend it. It's simple to implement and works very, very well in simpler circumstances. Bear in mind I've got 200 enemies trying to path-find at the same time. I'm not surprised some issues occur.

Speaking of code. As this was a learning project a lot of my code started out, how should I put it, absolute garbage? While I can program well, ofttimes really well (I have a degree y'know!), but I am prone to taking shortcuts. While this isn't a massive problem in a really small game (like a game jam game) or as part of a prototype, I do pride myself on writing code that is robust and easily reusable. Not long nasty nests of if statements or code that works now and then but only if it's a blue moon and I've completed at least two different rituals for each of the elder gods. Buuut sometimes I'd get lazy. Well it's not just that. My inexperience with Unity led to writing single scripts for each object. This is not good. In an ideal world you'd probably have a script to handle the players movement, something simple that would take in players key presses for W,A,S,D or the arrow keys and apply the correct movement. A different script to handle the players health mechanics, increasing/decreasing as required and setting up anything important such as the player hitting 0 hit-points and triggering a game over screen. Another script to handle... you get the point. NOT IN XZ-03 THOUGH. Nah screw that, I'll just have 1 script for each object that handles EVERYTHING to do with it. This is bad for so many reasons, I'll just list them quick.

-It's harder to find bugs
-Scripts become less reusable
-You end up re-writing code between scripts because you don't have basic mechanics segmented
-It's harder to understand when you come back to it later (this is big if you're solo dev)
-It's harder for others to find where the working parts for certain elements are (this is big if you're not solo dev)
-Other issues probably

The code shown isn't what's important here, but it's far too many lines.
In larger projects I'm sure that 650 lines isn't much for a player character
but for a smaller project like this, it's too messy to deal with.
This script handles movement, health, inventory and too many other
elements.

Now. This isn't the worst crime ever and in some cases a larger script that handles a bunch o' stuff is better. I tend to create a handful of "controller" objects for a game this size that manage the user interfaces, enemy spawning & control at a higher level and higher level game mechanics (level transitions, object collection, etc.). But I went a bit overboard in places and that has to stop. It's made updating mechanics & bug fixing much more difficult than it needs to be, to the point that I've put off or ignored known issues (never anything too serious mind you) for the sake of my own sanity. I've learnt my lesson not to push it though, that's for certain.

So the GUI controller handles a lot yeah. That's a lot of UI elements to handle
in one place. I hate this script. Issues with it are the worst to find.

Boy did this game have some weird graphical issues. Chalk it up to inexperience working with particle effects, lighting & the like. To be fair most are rare & unnoticeable. Hell, a lot I've been able to fix pretty well, but it's really shown me how hard some aspects of game dev are for me. I'm good at designing and implementing gameplay mechanics for games but graphical effects can be really difficult. That said I did manage to get a decent day/night cycle working using Unity's lighting effects and some percentages, but there were many problems getting this set up.

The slightly convoluted day/night cycle. To sum it up, it splits up
a full 24 hour day into 4 parts. Morning -> Midday, Midday -> Evening,
Evening -> Midnight, Midnight -> Morning. Based on which part of the
day it is a different function sets the brightness based on how much time has passed.

As I mention above, while it is a little convoluted I wanted to build a system that could handle any maximum light intensity and length of time. For reference it uses a percentage of time remaining (1.0 to 0.0) and uses that percentage to calculate how bright the light should be out of the maximum. This actually went through many iterations to reach this point. Initially the max intensity was 1.0 meaning I could use the time remaining percentage DIRECTLY. While useful this had to be changed when the game felt too bright at that high an intensity and thus more complex functionality was born. It took far too long to implement though and other issues arose due to the time percentage being calculated after the daylight meaning that the first/second half of day switches wouldn't hit correctly and the game would light up like the Blackpool Illuminations. So pay attention to the run order of your scripts kiddos. It can save you a lot of pain in the long run!

Let's not forget about the music. While I did leave time to compose multiple songs (5 total + 1 variant) I really should've spent more time making sure they were just that little bit better. Out of the 6 I'm honestly only happy with 2, 3 at a push. The others were not far off though. If I had decided to spend more time on them the music would've been much better overall though. That said I did enjoy the challenge of trying to write music for a more atmospheric purpose and feel I did a good job at the day themes. The night themes feel, out of place? I dunno quite how to put it, but trying to balance an atmospheric tone with the intensity of EVERYTHING ON THE MAP wanting to eat your tasty flesh was difficult and I don't feel I nailed it quite right. In the update I do slightly alter the music to better fit this (mainly a slight BPM boost helped) but it's still not perfect. But hey nothing is, and it's not bad. Just not good enough damnit.

Maybe, just maybe, I should tell more people that I'm making a game. I've always been a bit resentful towards self-advertisement of projects I work on. Call it an anxiety related issue. The reality of the matter is that while I've yet to make anything groundbreaking I do good work and can share a lot of what I do know with other folk. At the very least I know there are people like me, who would like the games I make as I have, for the most part, always followed the rule: "Make what you'd like to play". I enjoy most of the games I've made, whether for one part of it or as a whole and I know others have too. It's more a case of I need to get the word out and find the market that would enjoy what I make and, at least in part, cater a little more towards them. It'd help with getting more people playing what I make, which in turn will help me in countless other ways, but most importantly I just want people to have fun with the stuff I make. I do sometimes have moments where on Twitter I'll post multiple times a day for a week or so but I'm quite inconsistent. I used to use this blog (almost) weekly as well but that fell by the wayside a while back. All in all I need to be a little more proactive with showing off what I've been making because it's a hugely important part of any sort of creative endeavour that I ignore too much.

Lastly, I somehow still managed to burnout on a 3 month learning project. I say somehow but the reality of the matter is that work of any length can be demanding if you let it be. As a bit of a perfectionist and someone who suffers, sometimes badly, from anxiety and depression any sort of work that requires deadline, especially personal creative work is a burden. It is difficult as f*ck to make something, and even harder to go ahead and share that with people. While it may not have been the healthiest choice for someone of my "disposition" to go ahead and stress the hell out of themselves to make a game using many concepts & techniques new to themselves I'm still bloody glad I did. I've learnt loads, improved my process and garnered valuable experience. I've just gotta get better at working effectively. 12+ hour development marathons day after day until exhaustion is not the way to do it. I know this now.

So what's next?

If you follow me on Twitter (and you should) you know that for the last month or so my main goal has been to study various other aspects of Unity development and to start a few small prototypes to give myself some "tools" to work with for future projects. I've covered the basics of generating meshes & grids, shaders and proper animation. I'm also gonna start work on a small game called One's Black Dog at some point, so y'know, keep an eye out for that! It'll be an extension of working on narrative stuff (as my LDJAM entry went so well) as well as trying, as always, to learn new stuff. I'm going to keep putting working into graphical polish as well, as I've been enjoying seeing my games go from low-end programmer art to mid-level programmer art. It is truly an accomplishment...

Also I'm looking for a job! Mainly looking for work in the Sheffield area but I'm fine with moving further afield if I have to. I'd love to get something in game development (in case you haven't worked that out yet) but I'm fine to keep it as a hobby and getting work in developing software in general. Either way I'll be happy to get an opportunity to work with other people. I work far better in groups than alone, and while the idea of a job is kinda terrifying to me it's kinda exciting too. I look forward to moving towards bigger and better things.

Lastly I just wanna show you something.

This is what XZ-03 looked like on the first day of development.

And here it is 4-ish months later.

So, no matter what anyone says, always be proud of what you've done. I am! Learn from your mistakes and criticisms & know that with time and effort you have the capacity to make anything you want. Have fun with it. It's yours, and you have a right to be proud of it.

-Beau

No comments:

Post a Comment