All right.
So things are looking pretty good in this video.
We're going to do a little bit of final polish and try to pinpoint any issues, any bugs, anything
that doesn't look right before we continue.
Now, one of the things that I want to fix right away, and I noticed when testing earlier was with
my shaman, it's launching its fireballs too high, and that's because of the pitch override.
See, it's going upward, right?
The pitch override is in our enemy ranged attack.
So if we go to ability system enemy abilities and open ranged attack where doing a pitch override here
in spawn projectile and that pitch override is 25.
Now our enemy Firebolt is based on that class.
If we go to class settings, we see that it's based on a ranged attack and it does everything the same
way.
Aside from any variables that we set here in our class defaults.
So what we need to do is take our ranged attack and promote these to two variables so we can choose
not to have an override for our pitch in firebolt for the enemy.
So I'm going to take that override pitch and promote it to a variable.
And we can call this should override pitch and I'm going to take pitch override and promote that to
a variable.
And that can be pitch override.
I'm going to expose both with the eye icon and come back to enemy firebolt and uncheck should override
pitch and that should fix the problem.
Let's just test and make sure.
And sure enough, that fireball is not going high.
I do want to show you something that is revealed about our system because they continue to attack.
This gives us a unique opportunity to catch an issue and to show you the issue.
I'm just going to drag in some of our ranged attacker demons.
So I'm going to go to character demon and bring in a demon ranger.
I'm going to delete the shaman and I'm going to duplicate this Ranger demon several times.
So I have one, two, three, four.
I'm going to highlight them all and duplicate it again.
Now, this depends on your machine and what it's capable of, but I'm going to show the four here and
take a look at the DPS as our demons are launching their rocks.
This is something I noticed in testing and we're going to see what happens.
Let's just press play.
And we die right away.
And of course, because we haven't prevented any attacks, once our character dies, the enemies continue
to attack.
But look right here.
I showed the and notice it's now down to 40 and steadily dropping very rapidly.
Now, when something like this happens, this is indicative of some kind of memory leak.
Look at that.
It's going down to sub 15 and it's really, really going to keep going down until we basically run out
of memory.
Right.
We're already down to ten and that is definitely not normal.
And the way you can tell that it's a memory leak as opposed to just bad performance, is that usually
with bad performance, you go down to a baseline and you stay there for whatever it is you're doing.
But if you're doing the same thing and that keeps going lower and lower and lower, see, right now
it's not too bad.
It's around 100.
If it keeps getting lower, then you know something's wrong.
Now, in addition to that, I'm noticing that those rocks, when they hit the ground, they appear to
be spawning too many particles as really our particle system should only be spawning about 20 and our
spawn burst.
So something isn't right, right?
Something is not happening as it should.
And I suspect that we're getting too many projectiles.
So first what I'm going to do is see how many projectiles we're actually spawning.
So I'm going to close the editor.
I'll go ahead and save it.
And I'm going to go into my aura projectile.
So let's go ahead and just close all tabs and open in the private folder.
Actor or a projectile.
And right here, I want to see how many of these were spawning.
So essentially, just before we use play sound at location and spawn system at location, I'm going
to use a log.
With log temp warning text, and I'm going to see what the name of the projectile is.
So I'm going to use percent s for a string and we'll just say spawned and just after the text we need
that string.
So I'm going to use an asterisk with get name and we'll print the name of the projectile we're spawning.
So let's run in debug mode.
All right.
So we can go ahead and open up those asset editors.
But really, I just want to open the output log docket in the layout and press play and see what happens
now.
Okay, We're seeing a lot of red.
So that's one issue.
I'm going to hit pause and we have an error here.
Gameplay ability spec get magnitude called for data when magnitude had not yet been set by caller.
So that's something we'll have to check out in a second.
But for now, let's see what's going on here.
Now, we're spawning an awful lot of rocks, right?
So what's going on with that?
Well, I'm going to delete all of these ranged attackers except for one.
And let's see just how many rocks a single one of these is spawning.
We're spawning.
Looks like multiple rocks, right?
Each time.
Yes, definitely more than one each time.
So that's an issue.
So we'll get back to this error.
We can fix that quite easily.
But we do want to fix the fact that we're spawning more than one rock.
So let's go to a ranged attack where we're spawning this rock.
Here is our spawn projectile.
And what I'm going to do is I'm going to place a print string before we call play montage and wait.
That way we can see each time we're playing a montage, I'm going to say playing montage.
And then after we receive the gameplay event, I'm going to print another string that says Event received,
event received and event received can be yellow.
We'll make it a different color there.
So let's see what happens with our single one Ranged Demon.
Okay.
Now I'm seeing multiple events received and after Aura dies, it seems like it gets even worse.
We're receiving lots and lots of events.
Well, that's something we can fix pretty easily.
Our wait gameplay event can be set to only trigger once.
If I check that then press play.
Now I see that I'm only receiving that event once and we're only spawning those particles once.
So that's going to fix that problem.
But let's just make sure that we don't have memory leaks by taking a whole bunch of copies of our ranged
demon and having them all throw lots of rocks and see what that baseline performance should be.
So I'm going to show.
Press play.
We're starting at 120.
Looks pretty good.
Now they're all throwing rocks and let's just let them all throw rocks for a while.
Okay, so we were around 120.
Now we're going down to about 110 and it's still going down and we should be at a baseline around right
now.
There we go.
We're below 100.
We'll give it a few more seconds.
A couple more minutes.
All right, We're down to 80.
We'll let it go just a little more.
But definitely we should be at some kind of baseline as nothing's really changing.
We're only spawning rocks at basically the same rate.
Pretty much.
We're down to 64, so something is not right and I'm suspecting it has to do with those particles.
So let's go to the particle system itself.
We'll go to assets effects, combat and slingshot impact.
Here it is.
So let's see what's going on here.
And one thing you should notice right away is for particle state.
We see these to infinity signs, right?
The infinity sign means that this is going to live forever.
And if we click on particle state and check the checkbox kill particles when Lifetime has elapsed,
well then that infinity sign is gone.
So that infinity sign should jump out to us if we have killed particles when Lifetime has elapsed set
to true for both of these emitters.
Well, with that, let's just see what happens to our my computer can handle a little bit more.
So I'm going to go ahead and do another row of these guys and press play.
And I should see that hit some kind of baseline and stay there.
Now I'm at around 120 FPS and it's fluctuating around there.
It's not really changing much.
It's about one 2119 and we're throwing an awful lot of rocks.
So those particles are going away.
They're actually getting killed when their lifetime has elapsed as opposed to before when they were
not being killed, they were just staying around.
And that would definitely be a form of memory leak.
So that's something we have to be aware of with all of our particles.
And now that we know that that's not an issue anymore, I'm going to go ahead and duplicate this row
a couple more times and just make sure that our phps stays stable.
So lots and lots of rocks and of course our PHP is lower, but that's not because of a memory leak,
that's because we have just a lot more things going on on the screen as we have about 90, maybe close
to 100, but fluctuating between 90 and 95 mostly, and it's staying constant, it's not going down.
Whereas if we had that memory leak, let's go ahead and put it back in there.
We'll go to particle state and uncheck kill particles with that memory leak.
Now we should see the SPS go down very quickly, so we'll give it a few seconds.
We're already down to 80.
We're in the 70s.
Down into the 60s you get the idea.
So we'll make sure that that checkbox is checked for both of these.
And that's going to fix the problem.
Okay, so we have way too many demons in the world.
That was kind of a stress test, but I'm going to take most of the demons and delete them.
We'll leave one and let's go to our next issue that popped up, which was when we press play and look
at the output log, we're getting some red text, so we're going to need to fix that and let's see what
it says.
It says F gameplay effects spec get magnitude called for data damage arcane on def default g damage
when magnitude had not yet been set by caller.
So it's getting a magnitude for a set by caller and it's doing it for arcane for lightning and for fire.
Notice we don't see physical here.
That's because those rocks are using physical damage.
So it is getting a set by color magnitude, but it's checking all the damage types and we're getting
an error printed to the output log when it attempts to get a set by color magnitude that isn't there.
Now let's go ahead and go back into Cplusplus.
I'm going to close the editor and or a projectile does not need this log anymore so I can remove that.
And let's go into where we're getting a set by caller magnitude.
Do you remember where?
It would be an exact calc damage if we go to exact calc damage here in execute implementation, we're
looping through each of our damage types and we're calling get set by caller magnitude here.
And this function has additional optional parameters.
One of them is a boolean for warn if not found.
Basically, if we don't find a set by caller magnitude that we're looking for with this gameplay tag,
then we need a warning.
That's what that boolean is for.
But in our case, attempting to get a set by caller magnitude that isn't there is a valid operation.
We're checking for all of our damage types, so it's valid if we don't find one.
We don't want to consider that an error or a warning.
So we're going to pass false in for that.
Now for default if not found.
Why do we actually get an error when we don't find something?
Well, if we right click on get set by caller magnitude and we go look at it, we'll see that error,
its ability log error, it says get magnitude called for data percent s on def percent s when magnitude
had not yet been set by caller.
That's if one if not found is true.
So that tells us what causes that error.
So default if not found, can be zero.
We don't have to pass anything in for that.
So now we should no longer get that error message.
We're suppressing that.
So let's test that out.
Okay, we're back in the editor.
We got our asset editors open.
Let's press play and open the output log.
And we're seeing things are looking pretty good.
We're not getting that error anymore.
We are still printing some strings, so we're going to go back to our range attack and remove those
print strings.
We don't want to spam the screen anymore if we don't have to.
That takes care of that.
All right.
Things are looking better.
Notice we're taking less damage now because we're not getting hit by 3 or 4 rocks at a time anymore.
That's looking good.
Now we can also get our shaman back in.
So we'll get our shaman and we can stress test the shaman as well by putting 3 or 4 of them in and seeing
how this looks when they spawn in lots and lots of enemies.
We can also eject so we can show the here.
And I've already died.
So no need to really worry about repossessing.
But notice that with this many enemies in doing all of their thing, we find a baseline of about 50
ish.
And that's kind of a lot of things going on on the screen.
So, you know, it's going to depend on, of course, what your specs are for your computer.
But we found a baseline and it's not continuously going down, so that is a good thing.
And we could just double check that fireball and make sure that it's not lingering around as well by
going to assets effects, projectiles, firebolt And we can just check each of these.
We'll just look at fire.
I don't see any infinity signs we can check fire to.
I don't see any infinity signs there.
Kill particles is checked for these.
We can go to fire three.
Same thing.
We're looking good there.
And we have a fireball.
Same thing.
Those look good.
And finally, let's go into fire.
Explosion.
And make sure there are no infinity signs.
The infinity signs make this a lot easier to detect at first glance, so that one looks good.
And of course, our second one looks good as well.
So everything looks great.
I'm going to close the slingshot impact.
We're done with enemy Firebolt and for now, we're done with Ranged Attack.
Things are looking good.
We're going to remove a couple of those enemies.
We're back up to 120.
We have a good number of enemies on the screen.
And we have a good idea of what the budget is for, how many things can go on at the same time on the
screen.
So at any given point in time, you want to try to limit how many things are going on at the same time
and kind of gauge how that's going to affect your ops.
But you should never have an ops drain steadily as that's indicative of a memory leak.
All right.
So great job.
We have some good enemies and some really cool enemy behavior, especially for our shaman, which has
the ability to attack and summon other creatures, which is really cool.
And things are starting to look like an actual game.
But we're not done by far.
We're going to definitely want to do a lot more.
For one, we need more abilities.
That's coming up later on.
But we also are going to want to get some kind of experience points when we kill enemies.
So basically, every time we kill an enemy, we should see some kind of experience bar racking up experience.
And when it fills up, we should level up, right?
We should be able to advance to the next level and then we can do things like earn attribute points
when we level up, use those attribute points to spend on our primary attributes with these plus buttons.
We still haven't implemented that yet.
We want to do that.
And on top of that, we also want a spell menu where we can assign and reassign our spells to inputs
and also gain spell points so we can level up our spells.
It Wouldn't it be nice if we could upgrade our fireball ability to launch perhaps multiple fireballs
depending on our firebolt ability level?
And we also have more abilities that we're going to create in this course as well.
So lots of great things coming up.
We're going to start by implementing a level up system in the next section.
So awesome, awesome job getting through our section on finishing up our enemies.
At least for now.
We're going to consider them pretty much done and I'll see you in the next section.