WEBVTT

00:06.850 --> 00:07.880
Welcome back.

00:07.900 --> 00:15.280
Now I've got my exec calc damage open here, and we're performing a couple of calculations that involve

00:15.280 --> 00:22.630
some sort of magic numbers, some coefficients that scale these values, these attributes that we're

00:22.630 --> 00:27.400
capturing so that they make sense for the calculation.

00:27.400 --> 00:34.720
In other words, without them, the calculation may not be so natural or appropriate for RPG combat.

00:34.750 --> 00:40.810
We have our effective armor, which we're calculating using target armor times.

00:40.810 --> 00:47.950
This coefficient looks like I used times equals, which actually changes the target armor variable here

00:47.980 --> 00:49.120
our local variable.

00:49.120 --> 00:49.960
But that's okay.

00:49.960 --> 00:56.230
This still works because the result of this highlighted expression is going to be the result of this

00:56.230 --> 00:57.070
calculation.

00:57.070 --> 01:01.660
So target armor times this amount, it actually does return that.

01:01.660 --> 01:06.280
So this is the same as target armor times without the equals there.

01:06.280 --> 01:12.140
But if that confused you, it's totally fine to just have the star without times equals.

01:12.140 --> 01:12.980
Anyway.

01:12.980 --> 01:17.210
We have a 0.25 coefficient for source armor penetration.

01:17.210 --> 01:24.530
So for points of source armor penetration results in 1% of target armor ignored.

01:24.530 --> 01:27.320
That's what this equation means.

01:27.320 --> 01:32.030
But this coefficient may not make sense at all levels of combat.

01:32.060 --> 01:39.710
This may make sense at the beginning of the game when all of the participants in combat have relatively

01:39.710 --> 01:41.000
low stats.

01:41.000 --> 01:48.110
But perhaps later on in the game when all participants in combat are level ten, for example, this

01:48.110 --> 01:49.730
coefficient may need to change.

01:49.730 --> 01:51.940
It may need to go down, for example.

01:51.950 --> 02:00.560
So for that reason, these hard coded magic values are probably not the best way to do this in a serious

02:00.560 --> 02:01.790
RPG game.

02:01.910 --> 02:07.460
So for that reason, I'd like to explore a solution for this.

02:07.460 --> 02:13.010
Now, we know that if we want something to change based on level, then a curve table is nice.

02:13.010 --> 02:20.960
We can specify how those values change and I'd like to use a curve table for damage calculation coefficients

02:20.960 --> 02:27.470
because this is a great opportunity to do so and we can have a single source that we can access those

02:27.470 --> 02:28.040
from.

02:28.190 --> 02:30.740
Now, where should we put those coefficients?

02:30.740 --> 02:37.640
Well, I'd like character class info our data asset because it has our common class default values.

02:37.640 --> 02:45.170
So we could easily put a scalable float here or just a curve table that we could access values from.

02:45.170 --> 02:51.890
And that curve table could store curves for each of our coefficients that we need so far.

02:51.890 --> 02:58.430
We just need to we need a coefficient to multiply source armor penetration by and we need a coefficient

02:58.430 --> 03:00.050
for effective armor.

03:00.050 --> 03:02.720
So I'd like to make a curve table for those.

03:02.840 --> 03:06.410
So I'm going to browse to the folder that contains this.

03:06.410 --> 03:13.310
This is ability system data and I'm going to make a curve table for our damage calculation coefficients.

03:13.310 --> 03:17.870
So I'm going to right click, go to miscellaneous and choose curve table.

03:18.500 --> 03:20.360
Oops, I selected data table.

03:20.360 --> 03:21.200
Let's go back.

03:21.200 --> 03:29.960
What I want is a curve table and for this we have an opportunity to check out the constant curve.

03:29.960 --> 03:31.490
Interpolation type.

03:31.940 --> 03:39.110
Constant is great because we only need a certain value from one level to the next level.

03:39.110 --> 03:42.320
It doesn't need to smoothly change between levels.

03:42.530 --> 03:43.700
Let's see how this works.

03:43.700 --> 03:52.310
I'm going to select Constant, create a curve table and call this c t underscore damage calculation

03:52.310 --> 03:53.750
coefficients.

03:54.590 --> 03:57.920
And we'll open this up and we'll have a new curve.

03:57.920 --> 04:04.910
I'm going to rename this default curve and we can call this first one armor penetration.

04:05.600 --> 04:07.430
And these are all coefficient curves.

04:07.430 --> 04:14.810
So this is really armor penetration coefficient, but rather than just sticking coefficient on the end

04:14.810 --> 04:19.010
of all the names of the curves, I'll just name it armor penetration.

04:19.160 --> 04:20.960
Now we need a key.

04:20.960 --> 04:25.310
And notice the symbol here is not a triangle anymore but a square.

04:25.310 --> 04:31.280
And if I click that, notice that it looks just like adding a key to a curve table.

04:31.280 --> 04:33.500
It doesn't look any different than before.

04:33.590 --> 04:40.500
But we'll see as soon as we add multiple curves and take a look at the curve view, how this differs.

04:40.520 --> 04:46.880
Now at level one, I'd like to use the value that we're using for armor penetration 0.25.

04:47.000 --> 04:48.830
So I'm going to stick that in here.

04:48.920 --> 04:50.000
0.25.

04:51.550 --> 04:59.140
And I'd like this to stay at 0.25 for a while, up to, say, level ten, for example.

04:59.170 --> 05:01.060
Now, how can I do that?

05:01.060 --> 05:07.930
Well, I can click on the square and click the three dots next to the two and select Retime keys.

05:07.930 --> 05:16.690
At two, we can choose ten and at ten, I want to change this value now with 0.25, Let's think about

05:16.690 --> 05:18.330
how the mathematics works.

05:18.340 --> 05:21.030
Let's say source armor penetration is 100.

05:21.040 --> 05:23.860
Well, this multiplies it by 0.25.

05:23.890 --> 05:31.960
So that would make this multiplication 25 100 -25 is 75 divided by 100 is 0.75.

05:31.960 --> 05:37.630
So we're taking off 25% for 100 source armor penetration points.

05:37.930 --> 05:41.800
Now, I'd like this to be more harsh as we level up.

05:41.800 --> 05:48.580
So at level ten, I want to multiply source armor penetration by an even smaller value.

05:48.580 --> 05:55.730
So it takes even more armor penetration points because as these characters level up, source armor penetration

05:55.730 --> 05:57.890
may get really, really high.

05:57.920 --> 06:03.620
So I'd like to stick this to a lower value, say 0.15.

06:03.620 --> 06:07.510
And in addition to that, I'd like to go up to level 20.

06:07.520 --> 06:09.410
So I'm going to add another point.

06:09.410 --> 06:14.600
It's set to 19, but I'm going to retime it at level 20 and at level 20.

06:14.600 --> 06:22.310
I'd like this to go down even more like 0.85 or I should say 0.085 and we can just go ahead and go up

06:22.310 --> 06:22.940
one more.

06:22.940 --> 06:24.230
We'll go up to 40.

06:24.230 --> 06:32.600
So let's retime this at 40 and at 40 we're going to make this pretty low, like 0.035, for example.

06:32.930 --> 06:37.730
Okay, so what does a constant curve interpolation type look like in Graph View?

06:37.760 --> 06:40.970
Well, let's go to Graph view and select armor penetration.

06:40.970 --> 06:42.290
And here's what it looks like.

06:42.290 --> 06:43.550
It looks like steps.

06:43.550 --> 06:49.910
This is sometimes known as a step graph and it basically just means that between level one and ten,

06:49.940 --> 06:52.460
we have one constant value 0.25.

06:52.460 --> 06:54.260
So it doesn't matter what the level is.

06:54.260 --> 06:59.360
If it's between 1 and 10, we'll always get 0.25 from that.

06:59.390 --> 07:09.500
If we pass in 11, then we get the value here 0.15 and any value between 10 and 20 we get that value.

07:09.500 --> 07:10.760
So it's a constant curve.

07:10.790 --> 07:16.160
That's how it's going to work and that gives us a curve for armor penetration.

07:16.160 --> 07:19.430
Let's add a curve for our effective armor.

07:19.430 --> 07:21.440
That's the next coefficient.

07:21.440 --> 07:23.450
We need effective armor.

07:23.600 --> 07:26.150
So we're going to go ahead and click plus curve.

07:26.150 --> 07:35.600
I'm going to rename the curve to Effective Armor, and we have the same time scale values in our case

07:35.600 --> 07:40.220
level scale values, and we're going to start off at 0.333.

07:41.500 --> 07:45.070
And this value can get lower as we move on.

07:45.070 --> 07:49.360
So at level ten, we're going to make this 0.25.

07:49.390 --> 07:55.690
At level 20, we're going to make it 0.15 and at level 40 we're going to make it 0.85.

07:56.020 --> 07:58.840
And if we look at the graph, this is what it looks like.

07:59.170 --> 08:02.730
Oh, I should have made this .085.

08:02.740 --> 08:03.280
Right?

08:03.280 --> 08:05.560
So 0.085.

08:05.560 --> 08:07.480
So it's actually getting smaller.

08:07.570 --> 08:09.400
So we don't have that big jump there.

08:09.400 --> 08:11.770
And here's what the step curve looks like.

08:11.800 --> 08:13.150
Pretty nice.

08:13.570 --> 08:14.230
Okay, cool.

08:14.230 --> 08:15.700
So we have two curves.

08:15.700 --> 08:22.480
We can add this curve table to our character class info and we're going to do that in C plus plus.

08:22.480 --> 08:26.590
So I'm going to save all and close and open my data asset.

08:26.590 --> 08:32.770
So in ability system, we're going to go to the public folder actually ability system data, character

08:32.770 --> 08:33.840
class info.

08:33.850 --> 08:37.870
We're going to add a pointer to a curve table.

08:38.020 --> 08:40.360
So let's add a T object pointer.

08:40.660 --> 08:48.560
You curve table and we'll call this damage calculation coefficients.

08:50.320 --> 08:54.910
And this can be you property Edit defaults only.

08:54.940 --> 08:56.940
Common class defaults.

08:56.950 --> 09:03.940
We could even put this in a subcategory of damage and we can set this in the editor.

09:03.940 --> 09:06.160
So let's go ahead and launch.

09:09.440 --> 09:10.970
And back in the editor.

09:11.000 --> 09:17.990
Let's open up that data asset and here's our damage subcategory and damage calculation coefficients

09:17.990 --> 09:23.840
is here and we can get that damage calculation coefficients curve table and set it there.

09:24.050 --> 09:30.590
So now if we have access to the data asset, we have access to those curve values and we can get those

09:30.590 --> 09:32.090
in our calculations.

09:32.270 --> 09:36.740
So closing and saving again and we're done with character class info.

09:36.770 --> 09:37.640
I'm going to close that.

09:37.640 --> 09:42.500
We're back into exit calc damage, and I'd like to access those values here.

09:43.010 --> 09:44.840
So how are we going to do that?

09:44.960 --> 09:51.050
Well, we know that that data asset exists on the game mode, and if we can access the game mode, we

09:51.050 --> 09:52.760
can access the data asset.

09:52.970 --> 10:00.080
Now, I don't want to have to get the game mode every time I need some kind of value on that data asset.

10:00.110 --> 10:04.000
It'd be nice if I had just some easy way to get that data asset.

10:04.010 --> 10:08.660
So my ability system blueprint function library comes to mind.

10:08.810 --> 10:15.090
I'm going to open up my aura ability system library and make a static function that can return that

10:15.090 --> 10:16.110
data asset.

10:16.290 --> 10:23.340
This will make things easy for me, so I'm going to do a static function that returns a you character

10:23.340 --> 10:27.840
class info pointer and scrolling up.

10:27.840 --> 10:34.290
I see that the header file for character class info is already included, so no need to forward declare

10:34.440 --> 10:39.750
and I'm going to call this get character class info.

10:41.010 --> 10:48.480
Now this will require a world context object, so I'm going to add that as a required input and we'll

10:48.480 --> 10:55.920
go ahead and give this a new function macro blueprint callable or a ability system, library slash character

10:55.920 --> 10:59.940
class defaults and we can define the function.

11:01.510 --> 11:03.970
And this is going to be quite simple, actually.

11:04.000 --> 11:07.900
We're going to get the game mode just like we're doing in give startup abilities.

11:07.990 --> 11:13.630
And from that game mode we're going to access character class info and we can simply return it.

11:13.630 --> 11:19.600
So I'm going to copy these lines and paste them down here and simply return our game mode Character

11:19.600 --> 11:20.680
class info.

11:20.680 --> 11:22.630
So we'll have a return statement there.

11:22.630 --> 11:24.250
And that's all we need to do.

11:24.280 --> 11:30.430
Now this return statement here has to return something, so we'll return null pointer in the case that

11:30.430 --> 11:31.720
the game mode is null.

11:31.900 --> 11:37.420
So if we call this on a client where the game mode is a null pointer, well we'll get a null pointer

11:37.420 --> 11:38.170
then.

11:38.650 --> 11:41.890
So get character class info is handy.

11:41.890 --> 11:47.770
In fact, we can replace some lines of code and give startup abilities if we want to just use get character

11:47.770 --> 11:52.180
class info instead of going through the same process.

11:52.270 --> 11:59.170
So right here where we're saying character class info, we can just call get character class info passing

11:59.170 --> 12:01.640
in world context object.

12:03.470 --> 12:06.770
And then we don't have to get the game mode right there.

12:07.550 --> 12:13.520
We can do the same thing here in initialize default attributes where we're getting the character class

12:13.520 --> 12:14.150
info.

12:14.180 --> 12:21.560
We don't have to get the game mode anymore so we can remove those lines and replace this line here with

12:21.560 --> 12:25.460
get character class info passing in world context Object.

12:26.900 --> 12:33.650
And we have the character class info and of course Avatar actor could be const class default info could

12:33.650 --> 12:34.250
be const.

12:34.250 --> 12:40.550
But for now, let's stick to what we're doing and that is to get character class info here.

12:40.580 --> 12:43.920
This makes it easy to access character class info.

12:43.940 --> 12:48.020
Now character class info has the curve table.

12:48.020 --> 12:49.160
Let's go back and look at it.

12:49.160 --> 12:51.850
It's called damage calculation coefficients.

12:51.860 --> 12:56.030
We can access that if we can access character class info.

12:56.240 --> 13:01.940
So closing that, I'm going to go back to exec calc damage and see if we can access character class

13:01.940 --> 13:08.630
info and then we can get that curve table and get our coefficients that we need.

13:09.080 --> 13:14.900
So right here I can say you character class info.

13:14.930 --> 13:18.860
That's a pointer called character class info.

13:20.600 --> 13:31.010
And I can go ahead and alt enter to include the header file for it and I can use you ora ability system

13:31.010 --> 13:35.270
library or just added the include for that.

13:35.270 --> 13:42.530
And we can use get character class info and we can pass in a world context object and we have access

13:42.530 --> 13:44.210
to a couple of them.

13:44.210 --> 13:46.790
We can pass in source Avatar for example.

13:47.210 --> 13:51.320
So I'm going to go ahead and use the source avatar for the world context object there.

13:51.710 --> 13:58.010
Once I have character class info, then I can access the data table from it, which is called damage

13:58.010 --> 13:59.900
calculation coefficients.

13:59.900 --> 14:02.630
So taking character class info.

14:05.300 --> 14:11.250
We can get damage calculation coefficients and we can get values from the two curves.

14:11.270 --> 14:14.990
So how do we get values from a curve table?

14:15.020 --> 14:20.570
Well, we could take this curve table, use the arrow operator to see what kind of.

14:21.800 --> 14:24.020
Functions we have now.

14:24.020 --> 14:25.910
One of them is fine curve.

14:25.910 --> 14:30.900
And if we find a curve, we have to specify the row name for the curve.

14:30.920 --> 14:38.300
Now we named these after our attributes that the coefficients are supposed to affect, so we have to

14:38.300 --> 14:42.350
pass in an F name specifying the name of that curve.

14:42.380 --> 14:44.660
For example, we have the armor penetration.

14:44.660 --> 14:46.820
We can use armor penetration.

14:48.410 --> 14:50.600
This requires a context string.

14:50.600 --> 14:56.270
We can just pass in an empty F string and warn if not found is true by default.

14:56.360 --> 15:01.200
So once we find the curve, we can evaluate the curve at a given level.

15:01.220 --> 15:07.460
So this find curve returns an F real curve and that's a pointer.

15:07.460 --> 15:09.560
So we have F real curve.

15:10.520 --> 15:15.140
And we'll call this armor penetration curve.

15:15.620 --> 15:18.080
That's a real curve pointer.

15:18.080 --> 15:20.870
And we can take armor penetration curve.

15:21.830 --> 15:24.410
And from this curve we can evaluate.

15:24.410 --> 15:31.700
So eval is just a way to get a value on the curve at a given input for a given level.

15:32.510 --> 15:38.390
So if we call eval, we have to pass in a level, and for that reason we're going to need the level

15:38.390 --> 15:41.120
of our source character, right?

15:41.150 --> 15:45.300
We need a way to know what level that character is.

15:45.320 --> 15:46.990
So how can we get the level?

15:47.000 --> 15:49.040
Well, we have an interface, don't we?

15:49.070 --> 15:51.050
We have our interaction folder.

15:51.050 --> 15:56.000
Here's our combat interface, which has the function get player level.

15:56.120 --> 16:02.300
So if we can get the combat interface for both our source and target, we can know what their levels

16:02.300 --> 16:02.670
are.

16:02.690 --> 16:07.640
I'd like to get those way up here at the top where we're getting our source and target avatars.

16:07.640 --> 16:12.630
So we'll just store an eye combat interface pointer for each of these.

16:12.650 --> 16:22.370
First, I'll make a source combat interface and I'll just cast to it Eye combat interface cast Source,

16:22.400 --> 16:23.300
Avatar.

16:24.020 --> 16:25.340
Now, here's the thing.

16:25.370 --> 16:30.980
Source Combat interface has to be const because source avatar is const.

16:30.980 --> 16:35.270
But that's a problem because we want to call get player level.

16:35.300 --> 16:37.460
That's not a const function.

16:37.460 --> 16:38.870
So there's an issue here.

16:38.870 --> 16:45.230
If we make source combat interface const, we get rid of the error there, but then we can't call source

16:45.230 --> 16:48.170
combat interface get player level.

16:50.330 --> 16:52.630
Because that's not a const function.

16:52.640 --> 16:57.760
As you can see, the error says the function is missing the const qualifier.

16:57.770 --> 17:05.210
So in order to call get player level source, combat interface can't be const, which means source avatar

17:05.240 --> 17:06.380
can't be const.

17:06.380 --> 17:12.140
So we're not going to make this const anymore and Target Avatar will no longer be const and then we'll

17:12.140 --> 17:16.040
have to non-const eye combat interface pointers.

17:16.070 --> 17:22.520
We'll make this other one for target combat interface, which is going to cast Target Avatar.

17:23.060 --> 17:27.080
So now that we have these two interfaces, we can get the player level.

17:27.080 --> 17:34.940
So back down here in our eval call, we're going to get the source combat interface and call get player

17:34.940 --> 17:36.880
level and pass that in.

17:36.890 --> 17:41.090
Now Eval is going to give us the armor penetration coefficient.

17:41.120 --> 17:47.060
This can be a const float called armor penetration coefficient.

17:47.690 --> 17:54.240
And now that we're evaluating armor penetration coefficient at the source character's level, we can

17:54.240 --> 18:01.440
use that in our calculation here instead of the magic number 0.25 and we can do the same thing for our

18:01.440 --> 18:03.330
effective armor coefficient.

18:03.330 --> 18:07.860
So down here, just before we do that calculation, we can do that too.

18:07.860 --> 18:10.470
So we're going to say f real curve.

18:11.450 --> 18:16.880
Pointer effective armor curve equals.

18:17.330 --> 18:19.220
Character Class info.

18:19.790 --> 18:22.220
Damage Calculation Coefficients.

18:22.490 --> 18:23.810
Find curve.

18:24.860 --> 18:30.230
F name and the curve Rho is called effective armor.

18:31.050 --> 18:35.220
The context string is going to be just an empty string.

18:37.170 --> 18:45.480
And once we have that curve, we'll make a const float called Effective Armor Coefficient.

18:47.450 --> 18:54.530
And set that equal to effective armor curve eval.

18:55.280 --> 18:58.940
Passing in and this is the effective armor of the target.

18:58.940 --> 19:08.870
So this has to be target combat interface, get player level and we can take effective armor coefficient

19:08.870 --> 19:11.150
and use that instead of the magic value.

19:11.150 --> 19:12.560
0.333.

19:12.890 --> 19:21.350
Now these curves can be const pointers, so we'll make these f real curves both const and character

19:21.350 --> 19:26.270
class info can also be const, so we'll make that const as well.

19:26.270 --> 19:28.580
So now we can simply test this out.

19:28.610 --> 19:31.580
Now we know what those values should be at level one.

19:31.580 --> 19:36.590
And so far all of our characters and enemies are level one.

19:36.590 --> 19:43.310
So we just need to test this out and make sure that we get those values that we set in the curve tables

19:43.310 --> 19:44.120
curves.

19:44.120 --> 19:48.840
So let's test this out and we'll just use breakpoints to check those values.

19:50.320 --> 19:54.350
And we'll see if we have any problematic situations that cause crashes.

19:54.370 --> 19:56.170
Let's go ahead and press play.

19:56.800 --> 19:58.600
And I forgot to add breakpoints.

19:58.600 --> 20:06.010
So let's go ahead and add a breakpoint just at the end of the execution calculation and we'll press

20:06.010 --> 20:07.960
play and cause some damage.

20:09.050 --> 20:10.310
There we go.

20:10.310 --> 20:11.810
And no crashes.

20:11.810 --> 20:14.570
We got our break point and we can check these values.

20:14.570 --> 20:17.480
Let's take a look at armor penetration coefficient.

20:17.930 --> 20:22.640
I'm expecting 0.25, giving it a second to evaluate it.

20:22.640 --> 20:24.320
And there it is 0.25.

20:24.320 --> 20:32.150
And for effective armor coefficient I'm expecting 0.333 and there it is Now yes, there's a bunch of

20:32.150 --> 20:33.860
zeros and a four at the end.

20:33.860 --> 20:40.850
In your case it might be a different value that is due to floating point precision or as I like to call

20:40.850 --> 20:44.810
it, floating point imprecision, because it's imprecise.

20:44.810 --> 20:49.400
It's not going to be precise to this many digits, which is totally fine.

20:49.430 --> 20:53.810
This many digits out is a very, very small level of inaccuracy.

20:53.810 --> 20:59.600
But this is a good reminder that floating point values are rarely equal to each other, which is why

20:59.600 --> 21:06.590
I almost always use a less than or equal or a greater than or equal when comparing two floats.

21:06.590 --> 21:09.450
So that's just kind of a side tangent there.

21:09.450 --> 21:12.480
But I'm seeing that these values are correct.

21:12.480 --> 21:19.470
And another really good way to test this out is to change the level of the thing that we're hitting.

21:19.470 --> 21:23.700
For example, this here is a BP goblin, Spear two.

21:23.700 --> 21:25.200
It has its own level.

21:25.200 --> 21:28.590
It's set to level one, but I'm going to set it to level 11.

21:28.590 --> 21:29.040
Why?

21:29.070 --> 21:31.680
Because that's when it's effective.

21:31.680 --> 21:33.300
Armor coefficient should go up.

21:33.300 --> 21:40.290
So now I'm going to go ahead and hit it with a fireball and take a look at the effective armor coefficient.

21:40.290 --> 21:42.930
And it was 0.333.

21:42.960 --> 21:44.970
Now it's 0.25.

21:45.090 --> 21:47.820
Armor penetration coefficient is also 0.25.

21:48.030 --> 21:49.020
Excellent.

21:49.020 --> 21:55.530
And we know that it should have an even different value if we set that level to, oh, let's say 40

21:55.530 --> 22:01.380
or 39, I'm going to set it to 39 and damage it.

22:02.020 --> 22:12.100
And now the effective armor coefficient is 0.15 and just double checking in our damage calculation curve

22:12.130 --> 22:13.060
table.

22:13.240 --> 22:21.490
Effective armor at level 39 should be 0.15 and as soon as we hit 40 it'll go to 0.085.

22:21.490 --> 22:22.330
And why not?

22:22.360 --> 22:25.360
Why don't we just test out level 40?

22:27.240 --> 22:34.380
We should see 0.085 and we see 0.085 with some floating point in precision.

22:35.770 --> 22:36.490
Excellent.

22:36.490 --> 22:37.780
This is great.

22:37.810 --> 22:45.400
Now, our magic numbers have been replaced by data driven values, and now they can change based on

22:45.400 --> 22:46.230
level.

22:46.240 --> 22:54.400
And that gives us a way to have even more control As the player progresses gets higher in level, the

22:54.400 --> 23:00.010
enemies get higher in level, and as things start to get out of whack a little bit, we can scale these

23:00.010 --> 23:07.390
values according to our curves and have a little bit more precise control over how the mechanics work.

23:07.390 --> 23:09.250
And what values should these be?

23:09.250 --> 23:15.010
Well, that's going to depend on the game and is going to require a lot of playtesting.

23:15.160 --> 23:22.750
But this is great because now as we add more calculations, we have access to that curve table and we

23:22.750 --> 23:24.910
can scale things based on player level.

23:24.910 --> 23:26.380
So things are looking great.

23:26.410 --> 23:32.260
Now, if you're wondering why I'm creating all these local pointers and not checking to see if they're

23:32.290 --> 23:40.100
a null pointer, that's because I don't expect to run this function in any situation where these pointers

23:40.100 --> 23:41.000
should be null.

23:41.000 --> 23:45.890
I'm considering it an error or a mistake if those pointers become null.

23:45.890 --> 23:51.410
So accessing those pointers when they're null is going to crash the program and the crash will point

23:51.410 --> 23:55.790
to here, which means that something is wrong and needs to be fixed.

23:55.790 --> 24:03.200
So rather than having it fail silently and not crash the program, I'd rather just leave it here and

24:03.200 --> 24:04.370
crash the program.

24:04.370 --> 24:11.300
And if I wanted the crash log to be more descriptive, I could use assertions here and check these values

24:11.300 --> 24:18.110
and put a specific message to the output log in the case that these are null and attempted to be accessed.

24:18.110 --> 24:24.500
But in this case, if the game crashes and points to one of these lines here, I'm going to know why

24:24.530 --> 24:26.600
and address it then.

24:26.600 --> 24:35.150
But as we saw, the game should not crash because these curves are going to be valid because we've set

24:35.150 --> 24:37.570
the curve table in the data asset.

24:37.580 --> 24:42.560
So really the only reason it would be null is if we had forgotten to do that, Right?

24:42.560 --> 24:44.420
So this is looking great.

24:44.420 --> 24:45.800
Combat's looking good.

24:45.800 --> 24:52.640
I'm going to set this character back down to level one and we can continue with our damage execution

24:52.640 --> 24:55.730
calculation and we'll do that in the videos to come.

24:55.730 --> 24:56.810
I'll see you soon.
