Serial Link Commit 14: 16th March 2019

Line tracing for decal locations.

Continuing the work on making a component with a Single Responsibility, there has been some updates to the Bleeding Component. There is a link to the SOLID principles smart goal here.

So that this component is as portable as possible I have used variable types that are as high level as I can. Ultimately, I suppose that I would be able to pass the Bleeding Component a location vector only and that might be the way to go thinking about it. However, this is an Unreal BP and I would only be putting this on an Actor as its a Actor Component so I really don’t have much of a choice there! My point is that the only thing that I am passing to the events in that component that are specific in any way are Actors. Actors are defines in Unreal as ‘anything that can be represented in the world’. I think in this case that is high level enough. It makes the component very flexible and I’m happy that it would be able to be added to any type of character, robot, turret, vehicle or anything else, and work fine. The event prototypes are:

The ‘Projectile’ input is an Actor object reference and not an actual projectile blueprint class. That means that anything thats in the game world should be able to be used as the initial location for the trace.

Again, the Actor is just an Actor, but I think that’s a bit more obvious here! This event just traces straight down and find the first positive response to the Valid Blood Surface channel.

This one is a little more specific but I don’t think that its a problem. It needs a hit result to break inside the event and I am comfortable that a hit result is a standard UE4 data structure and would be valid in most situations. This could be changed to use the impact point and impact normal which now that I type this might be worth considering. Thats what I like about journaling, its that moment when I am thinking something like this through in order to explain and you spot some obvious improvement that could be made. However its worth mentioning that the Blood Spray is totally optional and if the user does not specify one, one will be chosen from the array that should be populated when the component is used.

This event is the one that would be called by the actor that was using it when that actor registered a hit event and determined in its own logic that a blood splat should be placed there. Again, this may be able to be slimmed down but to be fair, the hit event that would have triggered it in the first place would produce a Hit Result so it may as well just be passed right in, unless I find out that’s really expensive for some reason.

Commit

  • Drawing blood under the soldier when he is hit now happens from the bleeding component.
  • Drawing blood from projectile penetration from the bleeding component.
  • Enabled all of the physics bodies for the UE4 guy so that they generate hit events. I was only using the chest and head and then testing the velocity of the hit, but if he hit with his shoulder for instance, he would lose a lot of that force and not draw the blood when the chest did make contact with the surface.
  • Changed the penetration check to that if it does not draw blood, blood is drawn underneath the location of the projectile instead.
  • Added the suspended in the air effect to the weapons so that they can be plucked from the air. – Updated the weapon suspend in the air feature so that they can rotate a little, looks more natural

C++ Practice: Tic Tac Toe

Image from this fine location

This was another small(ish) task that Jamie suggested would be good exercise and yes, it was. This is related to my ‘Learn to code in C++’ SMART goal and supplements the course that I have been taking on Udemy. So the idea was that I would create a simple console version of noughts and crosses that could be played in two modes. Easy, in which the computer would choose a random square based on the ones that were empty and Hard, in which the computer would seek to actively block the player usually leading to a draw, just like in real life. I wont show all of the program, includes, menu display functions and such, just the main function and the more important functions so as to illustrate the structure I went for. I wont be posting code like this in the future unless someone finds it useful as I dont think that the journal is really about that. I think that in the future I will post about the things I am finding challenging and what I am doing about that. I’m posting this because, if I’m honest, I’m kinda proud of this one. It took a while to get it all straight in my mind and it was a really worthwhile thing for me to do.

This is what I can up with…

1 of 2
2 of 2

I enjoyed this task and I learned a lot. I think that the next task is the Unreal Battery collector tutorial as I think I am ready to start learning about Unreal’s flavour of C++.

Serial Link Commit 13: 16th March 2019

Those red ticks mean I need to commit. Pffft.

This is the problem. The Soldier actor is a crazy mess of tons of functionality, some of which is right, some of which is wrong and some of which just needs the plain ol’ delete key. But, I have a SMART goal regarding SOLID principles that is tackling this atrocity of a class. Ok, Blueprint. You know what I mean. I am applying what I am learning on the course and my own research to fixing as much of it as I can.

Single Responsibility Principle

This is the idea that each component, class, actor and so on is responsible for one, defined, activity. I understand this to mean that it should make common sense that a Weapon object could not reach into the Character object and make changes to the character directly, that sort of thing. If the weapon was heavy and needed to change the characters speed then there should be some other method by which that can happen without the Weapon being made to have a hard reference to the character or some logic that requires that the Weapon ‘cast’ to a very specific implementation of a character. Now, I may have some of this wrong at the moment and thats because I am still very much a beginner in thinking about these kind of design choices but I thought that I would start with something easily defined, not super complex but could be very portable if designed well.

The Bleeding Component

I decided to remove the following features from the Soldier actor and implement them in a component whose ‘single responsibility’ was producing gore in the world. Its a dark place to start I know, lets get on. So the functionality that existed was

  • Spray a blood particle from a location
  • Draw blood directly under a projectile hit location
  • Draw blood that would travel due to projectile penetration
  • Produce gore at a location, usually in response to a head shot or explosive going off.

Its not quite finished but now that majority of this is being handled in the Bleeding Component. This means that there is one place to edit the blood samples that are used for decals, one place to handle the tracing and other environment querying logic and so on. The other benefit of this is that is does not have to be just red, human like gore. It could just as easy be blue, dragon gore in another game and thats the point. I have really tried to take the Single Responsibility principle to heart and think in those terms now. I am very keen to start the course I have found on Pluralsight. I talk about that in the SOLID principles post.

Commit

  • Added logic to be able to track if the bullet casings are suspended in the air or not.
  • Added a new sound set of light metal taps that can interact with the weapon when it taps the casings when the casings are suspended in the air.
  • Used the velocity that the casing is travelling with to determine how loud the audio should play, this worked well and I would like to apply this to all the other sounds that are ‘hit’ based
  • Added a small delay to triggering the suspended in air effect so that the casing could leave the barrel a little further and it looks really cool, give the player much more of a chance the notice the feature
  • Came across a node called ‘get reflection vector’ and have used it on the kids bullets shield to properly deflect bullets and its better than the implementation I was using before.
  • Created a ‘BleedingComponent’ that I hope to use the centralise all the blood effects that are spread throughout the soldier actor. That way I could make anything ‘bleed’ like a robot that bleeds black oil and so on.
  • Have soldier’s body impact blood working from the new bleeding component – Have soldier’s blood spray from wounds working from the bleeding component

SMART: SOLID Principles

Yeah, I’m catching on that this is not the way… Image

Specific

I will learn about the SOLID programming principles so that I can write better software which will allow me to make better games and reusable components. I will do this by finding a beginner level course on a tutorial sight like Pluralsight and I will complete that course over the next 4 weeks.

Measurable

I will track my progress by making sure that once I have understood one or more of the principles I will use it in the design of my own code and logic. I will also know that this is complete when I can explain each of the principles to someone else.

Achievable

This is achievable because I have already created projects that are complex and show that I think in the right way. It could be argued that I have learned to create logic ‘the hard way’ and that the introduction of the combination or SOLID principles and design patterns will make writing code easier for me.

Relevant

This goal is relevant because I am actively pursuing a career in software development, primarily in games and I need to deeply understand the foundation of good design principles so that I can write better products.

Time bound

In reality, the study and practice of something like this will last for quite a long time and should be present in a lot of my design thinking, but I can say that I will complete a course and have a rudimentary understanding that will be a good jumping off point within 4 weeks.

Update – I have found a course that looks like its just the thing I need and you can get to it from here, there and everywhere.

A C++ Exercise: Rock, Paper, Scissors.

Image link

After speaking with Jamie a while back on how I might go forward with learning how to code, he told me about some simple exercises that he would give an aspiring student. So, here is it.

This ties into my SMART goal of learning to code with C++ which can be found here.

But why?

Well, its a simple concept and the rules are very clear. The menu driven nature of the game makes use of loops with checking the win condition makes use of selection methods. The program is small enough that I should have been able to hold most of it in my head but large enough so that I would need to (or should at least) use functions to break up the common logic. Its a lightweight program to test the basics, perfect.

The program, well some of it.

I included all the headers I would need for basic stuff like input and output and I declared that I would be using objects from the ‘std’ namespace although I have already been taught to only declare the things here that you are actually going to use and not the entire namespace.

Then I created and enum for the choices so and created the function prototypes

This is the main function, simple stuff really. I like to break things up as much as I can so having all the menu choices lead to function call’s was good.

This is the first part of the play game function

And it finishes checking the win state

This is how the AI (if you could really call it that) made its choice:

And if the game was over, this was called:

what did I find difficult

The thing that I found difficult was the temptation to consider really slick ways (that I don’t know really) to find out if the win condition had been met. I was convinced for a while that there was some magical one of two lines of code that would be ‘the way’ to do this. Its a common problem from what I read about people who are learning to code like me. I like the way that Ben Tristem (Udemy Instructor) talks about it. Red, green, refactor. Although on closer inspection that appears to be a whole approach to software development. Mr. Tristem talked about it like this: When the code is red, its not working, do what you have to do in order to make it work. When it works, its green. Now its working, go refactor it into something elegant and efficient. I keep reminding myself that I have to write bad programs in order to write better ones and then when I have written enough of those, my code might be ‘good’. I get the feeling though that ‘good’ means different things to different coders…

Serial Link Commit 12: 15th March 2019

Hanging in the air…

Looks like everything is falling but it isn’t!

I am very, very happy with this session. There are two reasons to that. The first is that the feature, which I will talk about in a second is just really cool. The second is that its a solid example of the learning that I have doing about programming patterns at play. I have a SMART goal about learning about design patterns that you can see here.

The observer pattern

One of the most useful patterns that I have learned about is this observer pattern. When I first started learning Unreal and the blueprint scripting system I could not get my head around event dispatchers (or interfaces for that matter, both I am using prolifically now though I’m pleased to say). Well, it turns out that event dispatchers enabled me to use the observer pattern before I knew that was what it was called. So in short this pattern is based on one object registering with another so that upon some being evaluated or some event being triggered, that actor can let the registered actor know ‘something’ has gone on. That something could be anything, a boss has been defeated, the player is at a certain location or, and in my case, the game is in coming out of slow motion. Anyone not familiar with event dispatchers, read on and I will tell you how I am using them in the logic too.

How I have implemented it

I have implemented this feature on a few things now, although I think in this commit its only the Soldiers, but I am catching up a touch with the journal. Soldiers, weapons, the explosive mine and bullet casings. I am going to talk about and show how I did the bullet cases. The first problem is that every single time a bullet case is spawned (sorry Jamie, I will pool them I promise) it, as the bullet case actor, needs to know if it should hang in the air or just fall as normal. Here is the logic from the shell casing actor that happens as soon as the little blighter is born:

The first part of making that happen to ask the game state if slow motion is active. This is a bool that I keep updated from the Slow Motion component that I created a while back to handle all of the time dilation. If the game is in normal time, nothing happens. However, if it is in slow motion, then the first thing (and this is the observer pattern at play) is that the shell casing registers itself with an event dispatcher in the Serial Link Game State using that Bind Event To node. From there I created a custom event that would fire when the event dispatcher fires. You can see I called it Drop Shell Casings.

This is the event dispatcher set up in the game state:

The one that we are registered with is the one that will be called when the game comes out of slow motion. Each actor that has been ‘bound’ to that event will get a call from the game state at the right time to say ‘hey, that thing you were listening for? Its just happened’. So, when its fired, my custom event will fire and the shell casing will be updated. When that happens, I am unbinding from the event as that particular shell casing never needs to know about the state of the slow motion again.

What I am using it for

This is quite simple really. I am only using this set up to determine what the values for linear and angular damping should be at the time that the shell casing is created and then I am using the observer pattern so that the shell casing can be updated with the normal values for those fields if needed. Very high numbers for those two properties lead to the effect of the air feeling like tar to those actors.

What I intend to do with it

I think that one of the best ideas I have had with this but have not had the chance to try out is linking it up with the combat teleport feature for the player. I would really like a simple way to have the player just hang in the air when teleporting so that should he teleport over a group of enemies, its not gravity that brings him down but choice or running out of power for that ability. I think that being able to hover in the air like that would lead to some really cool and satisfying combat scenes in which the player could teleport up, take out some guys, teleport back to the floor and carry on. I think that I would start with playing around with the player capsule as I am not sure that the updating the damping settings on the mesh would work because the mesh is under the hand of the animation system at that point. I would also try disabling gravity for some period of time if it if confirmed that the player is in the air although that could lead to the character being affected by other forces like radial explosions…

Commit

  • Used the logic that controls whether the ‘body hitting the floor’ foley gets played to limit how many times the blood decal can draw. Its hacky but its works well enough for now
  • Updated the damping on the gore pieces so that they dont roll around so much.
  • Stumbled across something very cool. Its a work around for having physics bodies look like they are in slow motion when they are not.
  • Updated Ragdoll character event with the ability to set the linear damping and the angular damping to a very high value, this makes the air feel like tar to the skeletal mesh.
  • Bound to an event dispatcher in the slow motion component so that the ‘ragdoll character’ event can be notified when the player is out of slow motion, then, the normal values for the damping are re-instated. This makes the characters who were trapped in the tar effect, fall to the ground as normal.
  • Updated the explosive mine so that if it goes off when slow motion is being used, the victims hang in the air.
  • Updated the Inferno-mine so that if it goes of when time dilation is active, the victims hang in the air.
  • Updated the Fling ability so that if slow motion is enabled when the body hits the wall, the victim goes into ‘tar mode’ so that it hangs there until the slow motion. They are returned to normal when the time dilation goes back to normal
  • Casings for the SMG now hang in the air in slow mo!!! When time comes back to normal they all drop to the floor at the same time and it looks epic.
  • Also noticed that the bullets casings can be moved in the air with the gun, as that has physics enabled. So the player can tap the shell casings as they hang in the air!

Learning C++

This is the fine course that I have been following. More on that here

This is a very sensible post containing very sensible information about a very sensible topic. But, and this the fun bit, that sensible skill of coding in a language like C++ can be high-jacked and used to create monstrous abominations of grown up games! A bit like the one I have been banging on about on the journal for a while now…

The problem that I face at the moment is that I’m not a real live boy. I am the Pinocchio of game development, wooden, due to the fact that the only tool I know how to use in any depth is Unreal’s Blueprint visual scripting system. A fantastic and very elegant, powerful way to make complex stuff, but, ultimately too specific to the Unreal engine and therefor by definition, not transferable. There is also the other problem of Epic’s code hobbit running off down the narrow, dank and dim dungeon corridor clutching a whole host of advanced engine features in its grubby, slimy little digits. His little raspy voice can be heard echoing back toward this wooden boy and it says ‘You’ll never get these extra features, like the adventurers before you, you will perish as the hand of the Compiler!’. First off, who is this Compiler and second, I’m ready! You hear me you little slippery hermit? I’m ready!

On a more serious note, one of my SMART goals is to learn C++ and so I thought I would talk a little about how I am going about that and how I am finding it.

The Course and the teacher

This is Frank. He’s a real good teacher.

The course is laid out in a real ‘lets start at the beginning’ format. Perfect for someone like me that knows a bit, but could really do with starting again and filling in all those little things that I kinda know, but don’t really. That turned out to be a LOT of things. The course covers:

  • Introduction
  • Installation and Setup
  • Curriculum Overview
  • Getting Started
  • Structure of a C++ Program
  • Variables and Constants
  • Arrays and Vectors
  • Statements and Operators
  • Controlling Program Flow
  • Characters and Strings
  • Functions
  • Pointer and References
  • OOP – Classes and Objects
  • Operator Overloading
  • Inheritance
  • Polymorphism
  • Smart Pointers
  • Exception Handling
  • I/O and Streams
  • The Standard Template Library (STL)
  • Bonus Material and Source Code

You can see from the list above that it is structured well and covers all of the topics that I would need to learn about in order to take my learning further and make a career writing this stuff. I can also say that Frank is a very good presenter, calm, knows the material well (I know thats expected but not all Udemy courses can boast this), and above all, he is available to the students. I have reached out a couple of times now and got the help that I needed.

So where am I?

I have been following the course for a while now and I can write basic programs and use functions, classes and statics. I have been using the STL a little, and I understand vectors and the benefit of using them over arrays. I am comfortable writing slightly larger programs, that I already know are actually very small programs! I can make little games and have completed many of the challenges that the course has set. I also have a good understanding of classes and the various constructors including the copy and move variety. I do need to refresh myself of some things as I go along but for the main() (little joke there…) I am doing fine and progressing well.

What I struggle with

I have found pointers a little difficult to use. Use, not understand. I think that once you understand the whole memory allocation thing in enough detail to at least know that memory is divided into addressable cells and that you can access and otherwise use that address just like the information that is stored at a location, then you get it. But, sometimes, its just a bit painful to try to visualise exactly what you want to do with the bloody thing and getting the syntax to match that.

Are you done yet?

Short answer? Ha! Like I ever give those! No, I’m not finished. I have got to the section about operator overloading and I am really enjoying learned about that as it feels kind of ‘advanced’ and for me, it is. I like to feel that I always just a little outside my comfort zone and that I am learning something that is just a touch out of reach. Then, suddenly, it clicks and I have grabbed it! Time for something new… I think that I will have this course completed in the next 3 or 4 weeks considering the other commitments that I have at the moment.

And after this?

Well, ‘after this’ is not really the way I would say it because the answer to that is C++ in Unreal but I am already looking at that now. So I think that what will happen is that I finish this course so that I learn enough just about C++ and then the time that is allocated to that (about 7 hours per week) will then be rolled up in the time that I spend currently on the Unreal flavour of C++ (also about 7 hours a week) bringing the total to 15 hours per week. Love a good ‘off by one’ error. Little array joke there to end on.

if(PostFinished)

break;

Serial Link Commit 11: 15th March 2018

Lets talk about blood, baby, lets talk about you and me…

Trace channels

This commit was a good one. I learned a ton and I was also able to notice that I think about this stuff more clearly now. I really enjoy recognising that my skill level has moved on, its very satisfying. I talk about it because its one of the pleasures of being involved in something like game development, where the pit of available skills to learn is so deep that you could just go on forever. Sometimes, I think its very rewarding and motivating to tackle some problem that you tackled a while ago and find that your tool kit has grown in the mean time. Thats what happened to me in this development session. The main issue that I was solving was that the line traces that were being used to work out where the blood decals should go were returning hits from and ever increasing array of things that I had to declare as ‘actors to ignore’. Weapons, gore pieces, other soldiers, it was a right mess really. Then, upon coming back to this issue for the first time in a while my first thought was ‘I should set up a custom trace channel that everything blocks be default called something like ‘Valid Blood Surface’ then I could just go round the project setting what should not return anything in that trace to ignore’.

Well, thats what I did.

Yep, custom trace channel. Hardcore.
Tracing for the brand new trace channel. Can I get a ‘Hell Yeah’!?

Now, there were quite a lot of actors to go through an set that they and some of their components ignore this channel but thats only because its late to the party. From here on, when I create something new, I can set it to what ever I need. Very pleased with that.

Tracking the head location

Tracking the head…

The next issue that I had was that because I had been using the ‘head’ bone as the starting location of a 360 degree ‘what should I draw blood on’ test, if the poor fella that the test was coming from found that his head had been smashed into a wall in that frame, the return from that process was less than desirable. It looked as if all the decals had been draw at various rotation from exactly the location in the world that the head had been at the time. Then, there was a kind of ‘slicing’ effect that was happening and I needed to sort it out.

So, I decided to track the heads position every so often so that I could use it as a location delta (I hope that my terminology is right there). Then I could decide whether or not to carry out the scan from the head location or the location delta I had tracked. I decided to always use the delta (I think, I am writing the retrospectively). This worked the vast majority of the time. I was using the last know head location and the current head location to create a unit vector that could be used as the direction that the trace would go. This lead to the blood always being in about the right place. But…

… It turned out that I could have saved my self all of that work as I decided to play with doing things a different way instead and that worked out much better.

Setting up gore to work with hit events

So, having thrown all that work away (thats not quite how it happened but I like a little drama), I did this instead…

I know that Jamie’s toes just curled a little at the sight of the ‘Spawn Decal At Location’ node and he’s right. I shall refactor sir, I promise.

Well this lovely bit of logic caused this mess…

This looked much more natural and the gore seemed like it was in the right place although a touch over the top

I am tracking the gore pieces velocity when the hit event is thrown as in earlier testing they just painted the scene red, leaving decal’s at every single location that they came into contact with regardless of how brief that contact was. Tracking the velocity really helped with that. I also intend to link the size of the decal to the velocity, seeing as that value is already being tracked for the gating side of things.

There are some other things that need to change with this though. I am only using one sample of blood and I would also like to be able to turn the blood and think about some ways that I could make it fall in a more realistic pattern. Anyway, for now that takes care of the gore pieces and stops most of the slicing effect that I was getting. Onto the bodies them selves.

Soldiers causing blood on hit event

I tried to implement this approach immediately on the soldiers but had a bit of a problem. I didn’t know that hit event had to be enabled from the physics asset and so spent plenty of time trying to get ‘I’ve been hit’ printing out from the hit event on the skeletal mesh from the soldier actor, silly boy. Anyway, this was the problem…

Can you see the little checkbox…
… and this is the logic it runs on at the moment. Pretend that the ‘Bleeding Component’ isn’t there though, that came in a later commit! This is this like the time line in Pulp Fiction.

In an effort to not have a million decals in the level thanks to all the hit events and the fact that testing only for the velocity would still put blood on top of blood, I needed another way to control the ‘flow’ a little more. I can up with the idea of tracking the last location that there was blood drawn and then not allowing anymore unless the requested location of the new blood was at least x amount of units away. That worked quite well and was not too jarring, but I think there might be a better way that I will talk about when I try it out.

Commit

  • Added a custom trace channel called ValidBloodSurface. Now when the line traces go out to find places to draw blood, they are only looking for this. That has stopped most of the blood decal slicing effects we were getting. Changed multiple actors and component responses to allow this to work.
  • Have solved the blood decal slicing issue by tracking the head bone location every so often, line tracing from that to the actual head location while looking for surfaces that block the ‘valid blood surface’ channel set up earlier. Then, step back 50 units from the surface normal and start the actual blood splatter tracing event. Seems to have solved all the slicing problems.
  • Changed how the head position is tracked so that we are not polling for it. When the player uses the push attack, the current head location is passed to the victim soldiers for use in the blood events.
  • Updated the blood events so that it can still be triggered using the head bone without first having provided its snapshot location so that the line trace can run.
  • Changed all the components collision settings in the Base Mine class so that they ignore the ‘blood surfaces’ channel too.
  • Made a separate event for spawning gore and blood for the explosive mine as there was a problem with deciding whether or not to track the current head location.
  • Fixed a problem with the math for the blood gen location vector. Works properly now.
  • Added functionality so that the gore that is generated can leave its own blood impact decals. Need to balance this, as its too easy to just paint the whole level red!
  • Added functionality to allow the soldier to draw blood when he hits a surface hard enough.
  • Work is still needed in the new approach to blood and gore but I think that general approach of creating decals on hit events looks more natural.