WEBVTT

00:06.820 --> 00:07.970
Welcome back.

00:07.990 --> 00:14.410
So now that we have all these secondary attributes, we need a way for them to be derived from other

00:14.410 --> 00:15.300
attributes.

00:15.310 --> 00:21.760
In other words, if armor is dependent on resilience, then every time resilience changes, I want my

00:21.760 --> 00:23.980
armor to change accordingly.

00:24.070 --> 00:30.280
Now, the way we can do this is by applying an infinite gameplay effect somewhere at the beginning of

00:30.280 --> 00:35.920
the game, perhaps when we apply all of our startup effects in our character class.

00:35.920 --> 00:37.780
So we're going to take care of that.

00:37.810 --> 00:43.990
We're going to make an infinite gameplay effect that will set all of our secondary attributes as soon

00:43.990 --> 00:46.000
as their base attributes change.

00:46.240 --> 00:49.710
We're going to add this to our character class.

00:49.720 --> 00:55.450
Let's go into the public folder, into character and in Aura Character Base.

00:55.480 --> 00:57.160
Let's see what we've got here.

00:57.160 --> 01:01.960
It looks like we have a gameplay effect class for the default primary attributes.

01:01.960 --> 01:05.740
We can just make one of these for the default secondary attributes.

01:05.770 --> 01:14.390
I'll go ahead and copy this line and paste a copy of it, but we'll change this to default secondary

01:14.390 --> 01:15.350
attributes.

01:17.290 --> 01:19.880
So now we have a class to apply here.

01:19.900 --> 01:25.750
Now it's important that we initialize these attributes after the primary attributes have already been

01:25.750 --> 01:26.620
initialized.

01:26.650 --> 01:27.160
Why?

01:27.190 --> 01:31.930
Because the secondary attributes depend on the primary attributes.

01:31.930 --> 01:35.320
So those attributes need to have their values set first.

01:35.500 --> 01:41.680
However, if this is going to be an infinite gameplay effect, then it will always be in effect.

01:41.680 --> 01:47.290
Whenever the primary attributes change, the secondary attributes should adjust accordingly.

01:47.410 --> 01:50.140
So we need to apply this effect.

01:50.230 --> 01:51.820
How do we do that?

01:51.850 --> 01:54.970
Well, we're handling it in a character.

01:55.000 --> 02:01.660
Let's go to the private section and the character folder and open our character and we see that in init

02:01.690 --> 02:05.960
ability actor info we're calling initialize primary attributes.

02:05.980 --> 02:08.470
Well, we don't have that defined here.

02:08.470 --> 02:10.540
It's defined in the base character class.

02:10.540 --> 02:13.890
So let's open a character base and here it is.

02:13.900 --> 02:16.600
Initialize primary attributes.

02:17.000 --> 02:20.600
Well, we can do something similar for the secondary attributes.

02:20.600 --> 02:23.530
We can have an initialize secondary attributes.

02:23.540 --> 02:25.110
Let's go ahead and do that.

02:25.190 --> 02:30.680
So back in our character base, I'm going to make another function for the secondary attributes.

02:30.680 --> 02:37.880
It's going to be void and it will be called initialize secondary attributes and it will be const.

02:37.910 --> 02:41.240
Let's go ahead and generate the definition for it.

02:42.400 --> 02:46.810
And it's going to be very similar to initialized primary attributes.

02:46.840 --> 02:49.300
We're going to check our ability system components.

02:49.330 --> 02:51.340
Let's copy that line and paste it.

02:51.370 --> 02:55.980
We're also going to check our class, the default secondary attributes.

02:55.990 --> 03:00.550
So let's go ahead and check that default secondary attributes.

03:00.640 --> 03:05.560
After that, we can make a context handle with make effect context.

03:05.590 --> 03:14.170
Let's copy that line and then we can make a spec handle, make outgoing spec passing in default secondary

03:14.170 --> 03:17.560
attributes and our context handle.

03:17.560 --> 03:19.210
So we'll copy this line.

03:19.780 --> 03:25.900
And at this point I'm realizing we're copying and pasting a lot of the same stuff, which is an indicator

03:25.900 --> 03:31.960
that we should probably refactor some things into a handy function so we're not repeating ourselves.

03:31.960 --> 03:33.460
So we'll keep that in mind.

03:33.490 --> 03:41.230
Now the last line is to apply the gameplay effect spec using to target, and we're passing in the ability

03:41.260 --> 03:42.530
system component.

03:42.560 --> 03:44.390
We'll go ahead and paste that in there.

03:44.390 --> 03:46.760
So this is a lot of almost the same stuff.

03:46.760 --> 03:51.530
The only difference is the actual gameplay effect class that we're using.

03:51.530 --> 03:53.210
Everything else is the same.

03:53.210 --> 03:59.960
So I think this is a good opportunity to refactor this into a reusable function so that way we don't

03:59.960 --> 04:03.490
have to have two functions that basically do the same thing.

04:03.500 --> 04:09.830
They could be one function that just takes in an input parameter for the thing that's not constant,

04:09.830 --> 04:10.040
right?

04:10.070 --> 04:11.660
For the thing that doesn't change.

04:11.660 --> 04:13.340
So why don't we do that?

04:13.370 --> 04:19.370
Let's go to our character base and instead of initialize primary attributes and initialize secondary

04:19.370 --> 04:22.130
attributes, why don't we make a new function?

04:22.130 --> 04:28.370
And this can be general, It can be simply to apply an effect to self.

04:28.370 --> 04:37.850
So we can call this apply effect to self and this can take a subclass of you gameplay effect called

04:37.850 --> 04:46.940
gameplay effect class and we can make it versatile enough to take in a level so float level and other

04:46.940 --> 04:51.050
than that it's just going to do what we're already doing here.

04:51.050 --> 04:53.930
Basically apply an effect to self.

04:54.140 --> 04:58.340
So why don't we just go ahead and generate the definition for this?

04:58.340 --> 05:01.970
And it's going to be what these two functions down here are doing.

05:01.970 --> 05:05.330
So we can just copy one of them and paste it here.

05:05.330 --> 05:11.720
But instead of checking default primary attributes, we're checking the effect class we're passing in.

05:11.930 --> 05:14.150
We're making an effect context.

05:14.150 --> 05:21.050
We're making an outgoing spec only instead of a specific gameplay effect class, we're using the one

05:21.050 --> 05:27.710
passed in and instead of hard coding one for the level, we'll go ahead and use that level passed in

05:27.710 --> 05:30.170
and then we're applying the effect to the self.

05:30.170 --> 05:32.720
So that's really all we have to do here.

05:32.720 --> 05:38.090
And I think instead of having two separate functions that pretty much do the same thing, we can just

05:38.090 --> 05:41.800
have one function to initialize all of our attributes.

05:41.810 --> 05:46.070
Why don't we go ahead and just make that function and then we can replace these two?

05:46.070 --> 05:51.770
So I'm going to make a void function called initialize default attributes.

05:52.250 --> 06:00.200
And looks like I had a typo there and this will take no inputs and this will handle initializing all

06:00.200 --> 06:01.280
the attributes.

06:01.280 --> 06:04.700
So all it has to do is call apply effect to self.

06:04.700 --> 06:12.500
So we're going to call apply effect to self passing in the default primary attributes with one for the

06:12.500 --> 06:13.220
level.

06:14.980 --> 06:21.250
And then we can call apply effect to self passing in the default secondary attributes.

06:22.440 --> 06:23.490
Like so.

06:23.490 --> 06:28.530
And now we only need apply effect to self and initialize default attributes.

06:28.560 --> 06:35.850
We don't need a separate function for each, so I'm going to remove, initialize primary and initialize

06:35.850 --> 06:37.290
secondary attributes.

06:37.290 --> 06:41.550
And back in the header file I'm going to remove those function declarations.

06:41.580 --> 06:45.360
Now we just have to clean functions and apply effect to self.

06:45.360 --> 06:47.190
Could be a const function.

06:47.190 --> 06:52.860
So let's go ahead and make that const to maintain const correctness.

06:52.860 --> 06:56.850
And now we know that it doesn't change the values of member variables.

06:56.850 --> 07:02.520
And now we have initialized default attributes by the way, that could be const as well.

07:02.520 --> 07:04.590
Let's go ahead and make these both const.

07:07.650 --> 07:11.310
And now we only need to call initialize default attributes.

07:11.310 --> 07:14.100
So we're going to need to go back to Aura character.

07:14.100 --> 07:19.950
And instead of calling this function, which no longer exists, we're going to call initialize default

07:19.950 --> 07:22.530
attributes and that should take care of it.

07:22.530 --> 07:30.660
And now, as long as our default secondary attributes to subclass of has a value set, then this should

07:30.660 --> 07:31.230
work.

07:31.230 --> 07:36.420
And if it doesn't have a value set, well, we're going to get a crash because we're using a check assert

07:36.420 --> 07:36.930
here.

07:36.930 --> 07:41.670
So the next step is to create our gameplay effect.

07:41.670 --> 07:48.570
It's going to be an infinite gameplay effect that's going to set the values of our secondary attributes

07:48.570 --> 07:53.190
and they're going to be backed by the primary or other secondary attributes.

07:53.640 --> 07:54.210
Okay.

07:54.210 --> 08:00.060
And now that things are looking good in the editor, let's just clean up a couple things in the attributes

08:00.060 --> 08:00.660
set.

08:00.690 --> 08:05.940
Let's go up to our constructor where we're initializing Max Health and Max Mana.

08:05.940 --> 08:12.310
We now no longer need to do that as those will be driven by our infinite gameplay effect.

08:12.340 --> 08:18.880
We're just initializing health and mana and we're even going to get rid of these in the future as well.

08:18.880 --> 08:25.150
And then another thing we did in a previous video was we commented out the clamping that we did here

08:25.150 --> 08:31.840
in pre attribute change and the clamping we did in post gameplay effect execute, we're going to reinstate

08:31.840 --> 08:33.310
that enforcement.

08:33.310 --> 08:38.710
So the clamping is there and with that we can compile and save.

08:39.930 --> 08:44.390
And here in the editor we just need to make our infinite gameplay effect.

08:44.400 --> 08:49.890
So we'll go into content blueprints, ability system and gameplay effects.

08:49.890 --> 08:52.770
And here we have a folder for primary attributes.

08:52.800 --> 08:58.350
Now it only has a single effect in it and we can make another folder for secondary and have a single

08:58.350 --> 08:59.400
effect in that.

08:59.400 --> 09:00.870
But that's a little silly.

09:00.870 --> 09:03.780
We don't need one folder per gameplay effect.

09:03.780 --> 09:07.680
I'm going to rename this folder to default attributes.

09:09.780 --> 09:13.410
And then we'll have our default primary attributes.

09:13.410 --> 09:15.720
This is GE or primary attributes.

09:15.720 --> 09:18.210
We're going to have another gameplay effect.

09:19.620 --> 09:26.100
And this one can be GE or secondary attributes.

09:27.510 --> 09:30.750
Now let's open the aura, secondary attributes.

09:30.750 --> 09:33.450
And the first thing I'm going to do is set its duration.

09:33.600 --> 09:40.080
This one is going to be infinite because I want this to constantly be, in effect any anytime one of

09:40.080 --> 09:42.120
my backing attributes changes.

09:42.150 --> 09:46.440
I want to see the change reflected in the derived attributes.

09:46.890 --> 09:50.100
Now, this isn't going to check every frame or anything like that.

09:50.100 --> 09:54.960
It's just going to trigger and response to one of the backing attributes changing.

09:55.230 --> 10:00.750
And before we start adding modifiers, I'm going to make sure to add this aura secondary attributes

10:00.750 --> 10:02.340
to the aura character.

10:02.340 --> 10:07.260
So we'll go to blueprints, character, Aura, BP Aura, character.

10:07.440 --> 10:11.730
And we're going to want to add or a secondary attributes.

10:11.730 --> 10:15.490
So down here in attributes, here's the default secondary attributes.

10:15.510 --> 10:21.220
I'm going to choose GE Aura, secondary attributes, compile and save.

10:21.250 --> 10:26.320
So let's go to Aura, secondary attributes, and we're going to add a modifier.

10:26.810 --> 10:28.430
And expand it.

10:28.430 --> 10:37.010
And the attribute that I'd like to affect is going to be let's choose armor, and here's how derived

10:37.010 --> 10:38.210
attributes have to work.

10:38.210 --> 10:42.770
They have to be infinite and the modifier OP has to be override.

10:42.770 --> 10:50.870
If you want this armor value to be based on a calculation that involves the other attributes.

10:50.870 --> 10:57.290
And for the modifier magnitude, of course we're going to choose attribute based and then we can choose

10:57.290 --> 11:00.350
which attribute backs this attribute, right?

11:00.350 --> 11:05.900
So armor is going to be dependent on the backing attributes.

11:05.900 --> 11:11.210
I'm going to choose resilience and we have to not snapshot.

11:11.240 --> 11:14.390
We'll learn about Snapshotting later for derived attributes.

11:14.390 --> 11:18.020
We do not snapshot and the attribute source will be the target.

11:18.020 --> 11:21.440
In this case, the target and the source are the same, so it doesn't matter.

11:21.440 --> 11:27.660
But I'm going to choose Target and the mathematics involved is up to us.

11:27.660 --> 11:29.760
This is a game design decision.

11:29.760 --> 11:32.100
So what should the armor be?

11:32.130 --> 11:36.150
We know that our resilience starts off at I believe it's 12.

11:36.150 --> 11:37.560
I can double check.

11:39.640 --> 11:42.280
Armour's resilience starts off at 12.

11:42.310 --> 11:43.050
Yes.

11:43.060 --> 11:47.080
And by the way, because we have this applied effect now.

11:47.110 --> 11:55.090
Armour is 12 as well, because it's backed by the resilience attribute without any coefficients or anything.

11:55.090 --> 11:58.120
So it's just equal to resilience at this point.

11:58.150 --> 12:03.640
Notice the base value is zero, but the current value, because this is an infinite gameplay effect,

12:03.640 --> 12:08.800
is 12 and that's the value that will be used in the game if we query the armour.

12:08.890 --> 12:11.230
Now that's a 1 to 1 relationship.

12:11.230 --> 12:16.120
If resilience is 12, armour is 12, but that doesn't have to be the case.

12:16.150 --> 12:20.380
Armour could be a base value of, say, six.

12:20.410 --> 12:28.060
If we want a base value, we would say six should be the post-multiply additive value and then our coefficient

12:28.090 --> 12:32.890
can be some fraction or it could be greater than one if we want that.

12:32.890 --> 12:36.790
And that's going to be multiplied by resilience, right?

12:36.790 --> 12:44.090
So if resilience is 12, let's say that we want our armour to be half the resilience plus six, that

12:44.090 --> 12:47.060
would be really it would just be 12 again, right?

12:47.060 --> 12:50.420
If we go back and press play and we do the math.

12:50.630 --> 12:53.870
Armour is 12, but that's because it's half the resilience.

12:53.870 --> 12:54.920
Resilience is 12.

12:54.950 --> 12:57.980
Half of that is six plus a base value of six.

12:57.980 --> 13:04.520
So it's 12 anyway, but we could have the coefficient be 0.25, for example.

13:04.520 --> 13:09.410
And then we have a base value of six plus a quarter of the resilience.

13:09.410 --> 13:15.410
If resilience is 12, then a quarter of that is three, and then our armour will come out to nine.

13:15.410 --> 13:17.900
So if we press play show debug.

13:18.640 --> 13:19.780
Armor is nine.

13:19.810 --> 13:26.510
See how this works So we can choose a very basic mathematical calculation using these coefficients.

13:26.530 --> 13:32.710
We could even add a pre multiply additive value if we want a little bit higher of an armor rating for

13:32.710 --> 13:33.910
a resilience of 12.

13:33.940 --> 13:40.810
Let's say we add one to it first and that way we'll have resilience plus one.

13:40.840 --> 13:44.380
Actually, to make the math easier, let's do resilience plus two.

13:44.410 --> 13:46.060
That gives us 12.

13:46.060 --> 13:48.220
Plus two is 14, right?

13:48.220 --> 13:51.220
And then our coefficient is 25.

13:51.250 --> 13:54.460
That's three and a half and then plus six.

13:54.460 --> 13:55.780
So six plus three and a half.

13:55.780 --> 13:56.980
That's nine and a half.

13:56.980 --> 14:06.790
And if we go ahead and see it, 9.5 is the armor C, So based on whatever values we do here, then we're

14:06.790 --> 14:09.010
going to get a different result.

14:09.010 --> 14:14.770
And as the resilience changes, our armor is going to change accordingly.

14:14.770 --> 14:16.000
And we can test that.

14:16.030 --> 14:25.310
We can test with our test actor here because our test actor is using a test effect and we can use that

14:25.310 --> 14:31.850
test effect to change the resilience and see the change in armor, for example, so we can go to blueprints,

14:31.880 --> 14:37.700
actor, test actor and go to test attribute based.

14:37.700 --> 14:40.640
And here we're testing out things, right?

14:40.670 --> 14:43.430
We can change these modifiers.

14:43.430 --> 14:45.290
It doesn't really matter which ones we change.

14:45.290 --> 14:50.210
Let's just leave those and we'll add a modifier to change resilience.

14:50.210 --> 14:52.610
So we're going to choose resilience.

14:52.610 --> 14:58.340
We're going to use Add and we're going to add a value of two to the resilience.

14:58.830 --> 15:04.570
So now we can check out how our armor changes once the resilience goes up by two.

15:04.590 --> 15:06.570
So our armor is 9.5.

15:06.570 --> 15:08.020
Ah, resilience is 12.

15:08.040 --> 15:11.130
We enter the volume, resilience goes up to 14.

15:11.130 --> 15:13.230
And look at this, armor goes up to ten.

15:14.640 --> 15:15.420
Pretty cool.

15:15.420 --> 15:18.450
Now this is what RPG games are all about.

15:18.480 --> 15:21.450
We change things and other things change.

15:21.450 --> 15:25.050
Everything is related by mathematical equations.

15:25.050 --> 15:33.150
And rather than just pulling numbers out of the air and plugging them in and saying, Well, I'd like

15:33.150 --> 15:36.060
this to be 0.25 and this to be two and this to be six.

15:36.150 --> 15:41.010
Ideally, a game development team is going to test these things out.

15:41.010 --> 15:48.930
In fact, it's not uncommon for an RPG game to be prototyped as a board game first before being made

15:48.930 --> 15:50.040
into a video game.

15:50.040 --> 15:56.730
And then these types of mathematical relationships can be fleshed out at the board game stage before

15:56.730 --> 15:58.070
the video game stage.

15:58.080 --> 15:59.910
That's a pretty common thing to do.

15:59.940 --> 16:05.460
The point is that these values are not just random, they all affect the game.

16:05.460 --> 16:11.580
And for the game to be balanced, they all have to be balanced well, which means playtesting testing

16:11.610 --> 16:15.100
the game out, seeing how things feel and so on.

16:15.100 --> 16:23.260
So it helps to have these values mapped out, at least have some initial values decided upon, Right?

16:23.260 --> 16:29.710
And then as the game gets tested and you sort of get a feel for how things work, then you can hone

16:29.710 --> 16:32.350
in on the sweet spot for these values.

16:32.350 --> 16:35.680
And keep in mind that the values are probably going to change.

16:35.680 --> 16:42.370
Sometimes you might have these coefficients and values different depending on, say, the level of the

16:42.370 --> 16:45.370
gameplay effect, which may depend on the level of the character.

16:45.640 --> 16:47.320
It gets complicated, right?

16:47.320 --> 16:53.980
And that's why each of these can be tied to a curve table and those curve tables can adjust these values

16:53.980 --> 16:56.380
as the gameplay effect changes.

16:56.530 --> 17:01.420
So for this though, we're going to just choose some values if you like.

17:01.450 --> 17:07.030
You can choose the same coefficient and pre and post multiply values for all of the secondary attributes

17:07.030 --> 17:08.020
if you want.

17:08.050 --> 17:12.580
If you don't want to sit down and start thinking about values, you can do that.

17:12.670 --> 17:19.900
But what you're going to do is you're going to add a modifier here for all of your secondary attributes

17:19.900 --> 17:27.790
and you're going to base them on primary or other secondary attributes, according to the plan laid

17:27.790 --> 17:34.480
out, either by you yourself, if you're designing your own attributes or in the previous slide.

17:34.870 --> 17:36.570
So remember this slide.

17:36.580 --> 17:43.450
Now, if you want to copy these, which are pretty common, I mean, this is inspired by some of my

17:43.450 --> 17:44.860
favorite RPG games.

17:44.860 --> 17:48.700
So a lot of games use relationships similar to these, right?

17:48.700 --> 17:55.420
So you can't really go wrong if you use these, but you could also choose to design this game the way

17:55.420 --> 17:56.140
you want to.

17:56.140 --> 18:03.190
But if you want to use these, then go ahead and take some notes or take a screenshot of this and save

18:03.190 --> 18:05.110
it or just write it down.

18:05.110 --> 18:12.070
And as you're adding your modifiers to our infinite gameplay effect, take a look at each of these secondary

18:12.070 --> 18:17.950
attributes and their backing attribute, which is the gray little tag to the left of each attribute

18:17.950 --> 18:24.700
and choose coefficients and pre and post multiply values for each of them.

18:24.700 --> 18:27.970
That's going to be your quest.

18:28.060 --> 18:34.270
So your quest is to add the modifiers for each of your secondary attributes.

18:34.300 --> 18:39.880
These are going to be attribute based, and this means you're going to do a little bit of planning and

18:39.880 --> 18:41.650
designing, right?

18:41.650 --> 18:45.340
So figure out the relationships that these attributes should have.

18:45.340 --> 18:52.210
And then I'd like you to change a primary attribute value using our test actor with our test actor's

18:52.210 --> 18:58.030
gameplay effect so that we can change a primary attribute value and see one of those derived attribute

18:58.030 --> 19:00.250
values change in response.

19:00.250 --> 19:04.330
So this is going to probably take a little bit of time.

19:04.330 --> 19:11.530
I recommend you take a piece of paper, maybe you have a notebook of notes for this course and map out

19:11.530 --> 19:14.830
your relationships for each of these attribute values.

19:15.040 --> 19:22.840
Map out the coefficients pre and post multiply constants and decide how you'd like your secondary attributes

19:22.840 --> 19:25.300
to change based on the primaries.

19:25.360 --> 19:28.420
So a little bit of game design going on here.

19:28.420 --> 19:31.990
So pause the video and conquer this quest now.

19:34.890 --> 19:35.340
Okay.

19:35.340 --> 19:37.290
So we're ready to tackle this quest.

19:37.290 --> 19:44.730
And before we do, I'd kind of like to share with you a little bit of my design process.

19:44.850 --> 19:52.260
So here's a page from some notes that I've jotted down during the design stages for this project.

19:52.260 --> 19:56.130
And as you can see, this looks very much like brainstorming.

19:56.130 --> 20:03.960
It's messy, and you'll notice that it's filled with a lot of estimations right back of the envelope

20:03.960 --> 20:11.040
calculations or equations, just ballpark figures that I felt might be appropriate in gameplay.

20:11.040 --> 20:17.880
And these are of course things that can be adjusted as we continue to test out gameplay in the project.

20:17.910 --> 20:21.060
Now this is very commonly what my notes look like.

20:21.060 --> 20:24.210
I very much like to write notes by hand.

20:24.240 --> 20:31.860
I also use tools on the computer, but when I'm brainstorming I like to sit down and kind of just play

20:31.860 --> 20:32.760
around with ideas.

20:32.760 --> 20:39.070
And you'll notice that this page contains things that made it into the final project and things that

20:39.070 --> 20:39.580
didn't.

20:39.610 --> 20:45.640
You'll see that I have speculation, ideas I think out loud when I'm taking my notes.

20:45.640 --> 20:50.470
I think about possibilities, things that may or may not be a good idea.

20:50.470 --> 20:55.330
I just jot them down and then later pick and choose which things I'd like to keep.

20:55.330 --> 20:57.220
So this was my thought process.

20:57.220 --> 21:05.500
And with these values, let's go ahead and implement our modifiers for the derived attributes gameplay

21:05.500 --> 21:06.220
effect.

21:06.280 --> 21:13.990
So I have my coefficient pre and post multiply values and this is all for my armor attributes and it's

21:13.990 --> 21:16.720
backed by resilience and I think it's looking good.

21:16.720 --> 21:22.870
So I'm going to go ahead and minimize that index in my modifiers array and add the next one and the

21:22.870 --> 21:27.130
next one is going to be for armor penetration.

21:27.340 --> 21:29.940
So I'm going to go ahead and add that one.

21:29.950 --> 21:35.650
Now, each of these is backed by a single attribute, but we've seen that we can have multiple modifiers

21:35.650 --> 21:38.830
offers for any given attribute that we'd like to change.

21:38.830 --> 21:40.110
So keep that in mind.

21:40.120 --> 21:44.320
One attribute can be backed by multiple other attributes if we want.

21:44.350 --> 21:49.780
Now, recall that our first modifier was set to override for the modifier OP.

21:49.810 --> 21:55.210
These are all going to need to be override, so I'm going to set this next one for armor penetration

21:55.210 --> 22:02.140
to override modifier magnitude will be set to attribute based and the backing attribute for this one

22:02.140 --> 22:04.990
I'm going to expand that is also resilience.

22:05.020 --> 22:12.760
Now, the values I've chosen for this one are a pre multiply additive value of one, a coefficient of

22:12.760 --> 22:18.400
0.15 and a post multiply additive value of three.

22:18.430 --> 22:23.890
We're going to set the attribute source to target and we're not going to snapshot and there's armor

22:23.890 --> 22:24.820
penetration.

22:24.850 --> 22:26.140
Let's move on.

22:26.350 --> 22:29.620
Our third is going to be block chance.

22:29.770 --> 22:34.600
So the attribute will be block chance, it'll be override.

22:34.600 --> 22:37.230
We're setting this to attribute based.

22:37.270 --> 22:41.280
The backing attribute is going to be in this case armor.

22:41.290 --> 22:44.830
So attribute to capture will be armor.

22:45.010 --> 22:52.660
And I want this to have a post multiply additive value of four and a coefficient of 0.25.

22:53.610 --> 22:56.460
With no pre-multiply additive value.

22:56.490 --> 23:00.210
We're going to have our attribute source set to target and we're done.

23:00.240 --> 23:04.980
Let's add our next modifier and this will be for critical hit chance.

23:05.070 --> 23:07.570
So we'll choose critical hit chance.

23:07.590 --> 23:09.480
It's going to be override.

23:09.480 --> 23:10.770
And let me just make sure.

23:10.770 --> 23:14.040
Yes, my block chance was set to override.

23:14.070 --> 23:19.410
It's very important to keep double checking these things as one incorrect setting could make things

23:19.410 --> 23:20.010
not work.

23:20.010 --> 23:20.610
Right.

23:20.850 --> 23:26.700
So for critical hit Chance, we're going to have our modifier attribute based.

23:26.700 --> 23:32.000
Our backing attribute in this case is going to be armor penetration.

23:32.010 --> 23:38.730
So we'll set our backing attribute to armor penetration and attribute source to target.

23:39.000 --> 23:47.130
And I'd like to have a post-multiply additive value of to a coefficient of 0.25 without a pre-multiply

23:47.130 --> 23:48.330
additive value.

23:48.480 --> 23:49.440
And that's it.

23:49.440 --> 23:51.110
That's critical hit chance.

23:51.120 --> 23:55.960
Now for the next one and this will be critical hit resistance.

23:56.200 --> 24:00.790
So selecting that one, making this override, just going to double check.

24:00.790 --> 24:02.830
I did that for the last one and I did.

24:03.100 --> 24:05.260
This will be attribute based.

24:05.290 --> 24:12.850
We'll get our backing attribute and for critical hit resistance looks like I skipped critical hit damage

24:12.850 --> 24:19.480
that's okay we'll get that next critical hit resistance is going to be backed by armor so attribute

24:19.480 --> 24:26.320
to capture will be armor capture from the target and critical hit resistance is going to be equal to

24:26.320 --> 24:28.420
a post-multiply additive value of ten.

24:28.420 --> 24:35.920
That's a base value of ten plus 0.25 times the armor.

24:36.190 --> 24:37.330
Okay, so that's critical.

24:37.330 --> 24:37.990
Hit resistance.

24:37.990 --> 24:39.580
It looks like I missed.

24:39.610 --> 24:47.050
These don't have to be in any particular order necessarily, but in my slide I had critical hit damage

24:47.050 --> 24:48.820
in between chance and resistance.

24:48.820 --> 24:49.300
That's okay.

24:49.300 --> 24:51.340
We'll do critical hit damage next.

24:51.430 --> 24:54.010
So for this one, we'll choose critical hit damage.

24:54.010 --> 24:55.360
It's going to be override.

24:55.360 --> 25:00.460
And again, I'm just going to double check, make sure that I set that for the last one.

25:00.460 --> 25:02.230
That's something that I tend to forget.

25:02.230 --> 25:04.150
That's one of the ones I commonly forget.

25:04.240 --> 25:11.710
It's going to be attribute based backing attribute for critical hit damage is going to be armor penetration.

25:11.980 --> 25:19.690
So attribute to capture is armor penetration capturing from the target and for critical hit damage,

25:19.780 --> 25:26.800
this is going to be equal to five plus 1.5 times armor penetration.

25:28.370 --> 25:30.560
So we have these base values, right?

25:30.560 --> 25:35.420
And you would think that the base values should go up as the game progresses.

25:35.420 --> 25:37.430
And that's why we have curve tables.

25:37.430 --> 25:39.560
And so that's something to think about.

25:39.590 --> 25:43.430
How are these values going to scale up with the game?

25:43.430 --> 25:50.900
Right now, they are scaling up in the sense that as the backing attribute gets larger, so does the

25:50.900 --> 25:52.370
secondary attribute.

25:52.370 --> 25:57.170
But of course the proportions can be scaled by these curve tables.

25:57.170 --> 25:58.670
So something to keep in mind.

25:58.820 --> 25:59.240
All right.

25:59.240 --> 26:00.920
So that's critical hit damage.

26:00.920 --> 26:02.750
Let's get our next one.

26:02.780 --> 26:05.180
This will be health regeneration.

26:05.450 --> 26:07.370
So let's get health regeneration.

26:07.370 --> 26:08.900
It's going to be override.

26:08.930 --> 26:12.830
We're going to set this to attribute based.

26:12.860 --> 26:17.510
Our backing attribute for health regeneration is going to be vigor.

26:17.990 --> 26:19.910
We're going to capture from the target.

26:19.910 --> 26:25.910
And for health regeneration, it's going to be set to a base value of one.

26:25.910 --> 26:31.980
This is how much we're going to regenerate per second plus 0.1 times vigor.

26:32.010 --> 26:33.360
That's how it's going to work.

26:33.360 --> 26:35.160
That's how the equation looks.

26:35.160 --> 26:40.020
Health regeneration equals one plus 0.1 times vigor.

26:40.020 --> 26:41.940
And there's our health regeneration.

26:41.940 --> 26:44.550
Next is going to be mana regeneration.

26:44.550 --> 26:48.180
So the attribute will be mana regeneration.

26:48.180 --> 26:50.160
It's going to be override.

26:50.160 --> 26:52.260
It will be attribute based.

26:52.260 --> 26:58.380
The backing attribute for mana regeneration, though, is going to be intelligence captured from the

26:58.380 --> 26:59.040
target.

26:59.040 --> 27:05.460
And this will be it'll be similar to health regeneration post multiply will be one coefficient will

27:05.460 --> 27:06.420
be 0.1.

27:07.080 --> 27:12.630
So basically every second we're going to gain one man up plus 10% of our intelligence.

27:12.630 --> 27:15.180
And there's our mana regeneration.

27:15.180 --> 27:18.180
Next we have our max health and Max Mana.

27:18.180 --> 27:20.160
So let's add those two.

27:20.190 --> 27:25.080
I'm going to first add Max health and this will be override.

27:25.380 --> 27:27.690
It's going to be attribute based.

27:27.720 --> 27:29.490
We'll set our backing attribute.

27:29.490 --> 27:31.770
And for max health, that's going to be vigor.

27:31.860 --> 27:36.330
So we're going to choose vigor capturing from the target and max health.

27:36.330 --> 27:42.360
I'd like to have a base value of 80, but we're going to add 2.5 times the vigor.

27:42.360 --> 27:45.090
So coefficient is going to be 2.5.

27:45.120 --> 27:51.300
So in other words, our max health is going to be 80 plus vigor times 2.5.

27:51.300 --> 27:57.660
So let's just say for math sake, vigor is ten, then ten times 2.5 is 25.

27:57.690 --> 28:01.140
25 plus 80 is going to be 105.

28:01.140 --> 28:05.580
So if vigor is ten health max, value will be 105.

28:05.610 --> 28:06.960
That's how it's going to work.

28:06.960 --> 28:10.170
And I'd like to do something similar for Max Mana.

28:10.170 --> 28:13.260
So let's add our ninth element here.

28:13.290 --> 28:15.000
That's going to be Max Mana.

28:15.000 --> 28:19.080
It's going to be override and it'll be attribute based.

28:19.080 --> 28:23.460
The backing attribute for Max Mana is going to be intelligence.

28:24.140 --> 28:26.690
We'll capture from the target and intelligence.

28:26.690 --> 28:31.640
I'd like to have a base value of 50 and we'll have a coefficient of two.

28:31.730 --> 28:35.480
So Max Mana is 50 plus two times intelligence.

28:35.480 --> 28:43.050
So if intelligence is 15, then we'll have a max mana of 50 plus two times 15.

28:43.070 --> 28:44.420
In other words, 80.

28:44.450 --> 28:45.680
That's how it would work.

28:46.160 --> 28:47.840
And that's our max mana.

28:47.990 --> 28:49.250
Okay, perfect.

28:49.250 --> 28:52.010
So let's go ahead and compile and save.

28:52.010 --> 28:54.560
We have quite a few changes, so I'm going to hit save all.

28:54.560 --> 28:59.180
So we save this test attribute and now we can simply test it out.

28:59.210 --> 29:01.220
I can show debug.

29:01.220 --> 29:03.110
And here's the thing.

29:03.110 --> 29:10.340
Once we start having lots and lots of attributes, well, our screen is kind of too crowded to show

29:10.340 --> 29:10.970
them all.

29:10.970 --> 29:17.780
We have too many secondary attributes all being affected by these modifiers on an infinite gameplay

29:17.780 --> 29:25.500
effect, so it's kind of hard to see, but we can see our armor is 9.5, our armor penetration 4.95

29:25.500 --> 29:27.720
critical hit resistance critical hit chance.

29:27.720 --> 29:30.420
We can see these numbers for some of them.

29:30.420 --> 29:38.400
We see our max health is 102.5 and this is cool but we're quickly seeing the limitations of show debug

29:38.400 --> 29:39.690
ability system, aren't we?

29:39.720 --> 29:45.930
We're seeing these limitations because in a serious game where we have these types of mechanics, it's

29:45.930 --> 29:48.840
going to be hard to show them all in a debug setting.

29:48.840 --> 29:56.130
And that's why like most RPG games, we're going to want a menu that shows us the values of our attributes.

29:56.130 --> 30:03.570
We're going to want an attribute menu now that's going to be a widget that we can show to the screen,

30:03.570 --> 30:08.250
which means we'll probably want a button that we can click to show that attribute menu.

30:08.250 --> 30:16.530
So those are going to be the next steps for us is a nice way to visualize our attributes primary and

30:16.530 --> 30:24.990
secondary in a nice menu that will be responsive and also have some options that will allow us to maybe

30:24.990 --> 30:28.440
adjust our attributes as or a levels up.

30:28.440 --> 30:35.790
She is going to gain some attribute points that she can spend on various attributes and then customize

30:35.790 --> 30:38.640
the build for this specific character.

30:38.640 --> 30:44.130
So these are common to most RPG games and that's what our project is going to have.

30:44.160 --> 30:47.130
So those will be the things we'll handle next.

30:47.130 --> 30:48.900
For now, excellent job.

30:48.900 --> 30:55.320
We now have derived attributes, attributes that are derived from other attributes and those relationships

30:55.320 --> 31:04.590
are mapped out here in our modifiers based on our attribute based modifier coefficient and other parameters.

31:05.040 --> 31:12.690
Now sometimes you might want an arbitrarily complex calculation and also your calculation may be dependent

31:12.690 --> 31:18.690
on other factors, not just other attributes, but other variables associated with the character.

31:18.690 --> 31:24.330
And for that we need to use something a bit more sophisticated than an attribute based modifier.

31:24.330 --> 31:28.140
So we'll have to use something like a custom calculation class.

31:28.140 --> 31:32.040
And that's another thing that we're going to get into in the videos to come.

31:32.040 --> 31:35.700
So just a few things to look forward to for now.

31:35.700 --> 31:38.850
Excellent job and I'll see you in the next video.
