Wednesday, 21 February 2018

New GamePlay Modes, New Weapons, New Fonts, New Stuff

Whilst contemplating unlockables, the obvious ones being the powerups which have to be unlocked, I turned my attention to differing gameplay modes. These things are sometimes called modifiers or mutagens and change an aspect of how the gameplay works. I came up with five ideas which I considered to be a good balance. I thought I might name them along the lines of "Trial By Whatever", as each one is an additional form of  challenge. I also thought that it might be a good idea to add a bonus score modifier to each one in use, that way if the player unlocked and chose to enable all five challenges, their score would double - thus giving an added incentive for the player to actual use them. Cue bullet point list! Note, gameplay modifier names are works in progress.
  1. Trial By Fun: Everybody drops FunBalls on death. Previously only bosses and certain enemies would drop FunBalls, but with this modifier every deceased enemy does and the original enemies drop double the amount. Expect more dodging!
  2. Trial By Strength: All attacks, whether by the player or the enemy, do critical damage. This is basically a x3 modifier to damage which makes gameplay much faster and increases the player's own vulnerability.
  3. Trial By Chance: Swag parcels full of powerups no longer spawn, instead there is a small percentage chance (based on the actual game difficulty chosen by the player at the main menu) of an enemy dropping a powerup when they are directly attacked by the player. In the proposed multiplayer co-op mode, this could create a rather amusing situation when everyone suddenly dives in to try and grab the swag for themselves.
  4. Trial By Judgement. All enemies spawn as elites. This means that not only do they have a higher capacity to take damage (somewhat negated if Trial By Strength is also enabled) but also carry a special attack of some sort, which are: radiation attack, player seeking missiles, extra health and damage, speed bonus,  electical attack and slow player on touch attack.
  5. Trail By Ordeal. Every 9 minutes or so (not certain of the acutal timings yet) some sort of enemy champion or enemy horde teleport in to harrass the player.
As stated above, unlocking and then enabling each of these challenges adds 20% to the player's score. Enabling them also makes for a much faster and more hectic game as escaping the level becomes much more urgent.

 Collecting a swag powerup dropped by an enemy

Speaking of unlockables, characters came to mind. Characters will come with their own statistics and are auto-equipped with their own weapon and evasion ability. Currently I only have one character, running around as placeholder yellow cube with a pistol and fast but short sprint for their evasion ability. Their standard attack is a single light bullet (damage 10) which has a long range (20m+), and their heavy attack (which uses energy the same as their evasion does, so the player has to wait for the recharge before being able to use either again) is a burst of four heavy bullets (damage 20 x4). Whilst tidying the finite state machines which control weapon states up, I noticed an error which had been around since the time the dinosaurs ruled the earth. Heavy attacks use onAltFire as a function call, but I had them set to the standard stateFire rather than stateAlternateFire, which meant that they were inheriting data from the standard attack. This meant that heavy attack was using particles and audio set for light attack rather than their own. Now heavy attack has a deeper, bassier gunshot and a wider spray of gunbarrel particles. I should have noticed this error much sooner.

Creating a new character I decided on "shotgun" as the weapon. This has a standard attack of solid slug (damage 50) which is much slower than the pistol in firing as it has to be cocked with a nice pump-action sound and also has a shorter range (12m). To compensate the damage is much higher. The heavy attack is a close range (5m) scatter shot, which hits all targets within a 90 degree angle (damage 20). The special evade for Shotgun is what I have called a "Ghost Run" - the ability to run through enemies for a few seconds to escape.

"Ghost Run" took some doing, as I had never had cause to go hunting around the collision code which was spread through numerous files of the engine. So what I wanted was to find out where I could extract the collision object's type (eg: AI enemies are derived from Player Class so I only wanted playerObjects) and then make a test against the class on whether this object should be ignored.

Of course it was not that simple ...

A few days and according to Windows Event Viewer, 80 crashes later, I realized that the whole thing was a lot simpler than I had originally envisioned. I created a new customCollisionMask for the Player class which emitted PlayerObjects and then made the test under the Player class's own workingCollisionList. If "Ghost Run" was enabled via a bool flag, and the object was derived from Player class then it used the customCollisionMask to ignore new playerObjects. Another bool flag issued when the state of Ghost Run changed which then renewed the workingCollisionList to remove that playerObject if it had already been added to the list, or readd it to the list if it was the last collision ignored before Ghost Run was deactivated. I felt like a coding god, regardless of having spent the previous week looking in entirely the wrong files.

I should probably read this, but to be honest my style is to make it up as I go ...

So now I had a working second character. Apart from obvious difference such as attacks and abilities I decided that characters should also have a unique strength attribute when colliding with enemies (or other players). This would be useful for barging their way past opponents. Strength should be relative to their own suited range, thus long range based characters would have a low value whilst short ranged, melee based characters would be high.

Shotgun is a medium ranged character so can push similar sized enemies around by banging into them. Pistol is a long range based character so now finds it difficult to physcially move enemies and is much more vulnerable to get swarmed at close range. However Pistol has a sprint evasion which quadruples speed and triples the force of pushing enemies, though this only lasts for a couple of seconds as energy drains away.

Shotgun in action, with Gradius Style Option/Follower trailing behind 
I also started thinking more about the overall look of the player's screen and HUD, and how to display information best with text. Thus began the GREAT FONT HUNT! If there is one thing which can be equated to slogging through an parched wasteland of spikey rocks, it's trying to find fonts for your game. I have a preference for condensed fonts, I think they look elegant, but elegant and easily readable with a quick glance are not always the same thing.

This looked great until I added it the actual HUD ...

 There's thin and difficult to read and then there is this ...

 Yeah, but no but really no ...

Argh my eyes ...

 One of the great problems with staring at millions of fonts is that they all end up looking the same. Currently I have this below, but found that the numbers are a little too close together. Using a font editor I managed to give them a little bit more spacing. Cue the first image in this blog being reused.

Hello it's the first image in this blog again

So that's progress. Next up are to make more characters with various abilities and give them a thorough testing for balance. After that come up with a definitive list of enemies and environments for levels, and then hopefully finally start on some model designs to chip away at all these placeholder cubes. Also somewhere on the horizon is ditching DirectX 9.0c and updating to Physical Based Rendering ... whatever the hell that is ...

Saturday, 27 January 2018

Welcome To Space Year 2018 - Now With More Catgirls And FunBalls

We are so into the future, and it is only another 2 years until the Tokyo Olympics. I can't wait.

Soon ... (ish)

And so to the New Year, which began with great productivity (once the hangover wore off) and "Dry January" commenced. More on that later.

First up was going back over some old ground and changing things ... which to be honest, appears to be 90% of what consumes my development time. I had used a small number of open source/creative commons/CC0/CC-BY images. I ended up stripping these out and replacing them with custom imagery. The most used one was of a cat, which was changed to be a tiger.

I dropped the sole icon I was using from (a really useful resource) and replaced it with my own custom one. This had been for the "Tough Skin" powerup, which during playtesting I had thought was underpowered for a rare item and so doubled the amount of damage it stopped from 10 to 20 percent.

"Tough Skin" Rare Powerup, Now With Less Gauntlet And More Catgirl 

The overall layout of the player's interface/HUD went through another iteration, and a skull was added to the kill/gore gauge which fills up and changes colour until it completes level 4 and a Momento Mori is triggered. Upon this the player becomes invincible for 60 seconds and scoring multiplies by 8  (that's the old 4/8, death/wealth for the Far East), and all attacks now deal critical damage to enemies.

 Object which mounts to the player to signify that the Momento Mori has been activated, and they are now Shinigami, God of Death.

Kinda like this guy but you have to make your own atatatatatatatata sound

I also altered the textures for the Gradius style followers which can be picked up and upgraded via powerups, giving them each a little sheen which passes over them. They are little weapon platforms which follow the player around and increase firepower. I spent a while in the depths of C++ changing their start/stop movement to make them move much smoother than they had before.

I am most proud about getting this gif to loop seamlessly :P

One thing I noticed about collecting offensive and defensive powerups is that there could be a disconnect between the information displayed to the player and what the actual effect is. This is because special attack and defend abilities are triggered using an RNG. The more abilities the player has, the greater chance of an activation. However this doesn't mean that the last powerup will trigger next, so I changed that so that it always triggers on the next attack or defence - thus giving the player a clear idea of the ability of the object which they just picked up.

Collect "Magic Bullet" offensive powerup, immediately see it used on your next attack

And so onto FUNBALLS. If the esoteric words "RoR, /v/, Git Gud and Host When?" mean anything to you, then this should give an inclining as to what comes next.

This is a FunBall. You can tell it's a FunBall due to the word "FUN" written on it and it's murderous grin 

FunBalls are fun - okay, they're not really, they're bombs which some enemies will drop. I also intend to create an unlockable challenge mode when everything will drop FunBalls upon death.

I am using a slightly basic collision and physics system (hello rigidBody) for speed and convenience. FunBalls didn't look very good as standard objects due to sudden rotation changes when they bounced. To combat this I made the object a billboard so that it always faces the camera and used a scrolling texture to give the illusion of smooth, spinning movement. I then created four variations, leaving one central and rotating the others (off-left, off-right and upside down) so that when a number of FunBalls burst from a deceased enemy, they have plenty of variation but the player can always see the grin at some angle.

FunBalls in action! Audio has since been changed.

And upon all of this, there have been numerous little tweaks and changes to how things work, as well as much planning on the data of enemy types as the levels progress (though everyone is still a placeholder cube right now).

Did I mention "Dry January"? My performance at darts really suffered so halfway through the month this kinda happened ... 

Next up, more sorting out data and attack types for enemies, and some considerable reading up on this new fangled thing called PBR.

Friday, 29 December 2017

Tests, Checks And Gameplay Balancing

It's that time of year again folks, when you feel like this ...

And end up looking like this ...

Of course some of us are still working hard on "muh gaem dev" - and this month it's been mostly playtesting to try and create game balance, and hunt down a few elusive bugs. And when I say "elusive", I of course mean badly/drunk coded.

Like the Rocketrix offensive smart bomb attack. It picks the most dangerous group of enemies so it can do the most damage, swoops in and ... blows the player to smithereens. Yep, pretty sure that is not supposed to happen. Turns out I was calling the attack from the enemy target instead of through the player. Simple mistake by passing the opposite variable, possibly explained by the following image:

One thing that extended playtesting has shown is that stacking powerups - repeatedly collecting the same swag - does not happen as often as I thought it would. Even with 15+ items available each level, there are a total of 108 seperate bonuses (including upgrades to weapon drones). Whilst this does not really effect offensive or defensive events (which are added to an array list for chance of activation during attacss/damage), it does mean that permanent bonuses (health, speed, energy, etc) to attributes do not happen as often as originally planned, and individual bonuses confer too little benefit to the player.

Boosting the effect of permanent bonuses is the obvious way to balance this unforeseen lack of reward. For instance increases to player health are now percentage driven rather than a stock value, and speed is now hiked much higher as the original gain was meaningless beyond the first few game levels.

Another event that did not quite live up to it's predictions is the "Momento Mori". This is a sort of "rage gauge" which fills each time the player kills an enemy, but reduces each second. Enemies killed by heavy attacks fill the gauge faster than light attacks, and all other attacks (drones, swag events, etc) even less. The bar can fill multiple times, changing colour and conferring a multiplication bonus to the player's scoring.

"Gore Gauge" - Orange Bar and x3 Text, top right

Originally the player would fill the "rage gauge/kill bar" three times - now forever to be known as the "Gore Gauge" ;) - at which point the player would be healed and for the next thirty seconds the Gauge would stick at 4, multiplying the player's scoring.

To make this more of an actual event for the player to aim for, I increased the fill trigger level to 4, at which point it leaps to score multiplication x8 (4 = death, 8 = wealth), the player is healed 100% and for the next 30 seconds whilst the Momento Mori lasts is also invulnerable to all damage, which is a really big help in crowded and frantic later game levels.

Momento Mori event triggered. Red bar and x8 text top right (GUI still needs some work)

The GUI incorporating the Gore Gauge needs a bit more work, such as an icon to show what it represents like the XP/LevelUp, health and energy bars top left (a small skull would probably be a good fit here).

Momento Mori in action from ~02:02. Gore Gauge starts at x3.

Of course, what was missing from the above video is an indicator for the player that the Momento Mori event is still on-going and not yet ended. After a quick bit of modeling, texuting and scripting, I created what I felt would be a suitable aura type object to mount on the player to signify that the event was active.

Behold, one visual indicator, brought to you in the format of GIF

There have also been numerous other bugfixes and tweaking of code and gameplay - it's not all been eat, drink and be merry this Decemeber. ;)

So, next up is more gameplay balancing, but I am at the stage of development that this requires creating the actual data for the enemies which the player will be encountering in the game worlds, and their unique attributes and characteristics for attack and movement. This also requires drawing up a list of boss types rather than the singular one which I have at the moment.

Roll on 2018 ...