WEBVTT

00:06.950 --> 00:08.090
Welcome back.

00:08.120 --> 00:14.990
So we have our aura projectile spell and this gameplay ability is not doing a whole lot.

00:15.020 --> 00:18.420
It's printing a string and it's activate ability function.

00:18.440 --> 00:23.510
We want to do more than that and we're going to start with spawning a projectile.

00:23.540 --> 00:31.040
So I'm going to close some of these files, but I'm going to leave some of them open.

00:31.220 --> 00:36.080
I have my aura projectile spell and I've opened gameplay ability H.

00:36.110 --> 00:42.080
I'm going to keep that open for now and my aura projectile that can stay as well.

00:42.110 --> 00:48.480
Now Aura projectile spell is going to require a class to spawn for the projectile.

00:48.500 --> 00:50.690
We need a projectile class.

00:51.140 --> 00:54.560
So I'm going to add a subclass of variable for that.

00:54.560 --> 01:03.080
So to subclass of and the class is going to be the aura projectile class.

01:03.110 --> 01:05.210
Now I'm going to forward declare that up here.

01:05.210 --> 01:08.330
So class a aura projectile.

01:09.380 --> 01:16.190
And the subclass of will have the same type and this will be projectile class.

01:17.030 --> 01:26.210
Now we'll give it a new property with edit anywhere and I'm going to make this blueprint read only and

01:26.210 --> 01:31.400
we'll keep it protected so that we can have that blueprint access as well.

01:31.430 --> 01:34.550
Now we want to spawn this, right?

01:34.550 --> 01:38.090
So how are we going to spawn it and where are we going to spawn it?

01:38.090 --> 01:40.070
Those are the questions at hand.

01:40.190 --> 01:47.150
So here in Aura Projectile Spell, we no longer need this message from Kismet System Library.

01:47.180 --> 01:49.340
We don't need that header either.

01:50.150 --> 01:52.790
So we want to spawn this projectile.

01:52.790 --> 01:54.170
Now, here's what I want to do.

01:54.170 --> 01:56.500
I want to spawn the projectile on the server.

01:56.510 --> 01:59.180
I don't want to spawn this locally.

01:59.240 --> 02:03.350
I want this projectile to be a replicated actor.

02:03.350 --> 02:09.690
And that way if the server spawns it, then the server will be in charge of moving it, handling its

02:09.690 --> 02:16.350
location and all that good stuff, and the clients will just see a replicated version of the projectile.

02:16.350 --> 02:22.950
So for that reason, I'm going to go up to Aura Projectile and just under primary actor tick we're going

02:22.950 --> 02:31.190
to set be replicates equal to true So we now have a replicated projectile class now back here in aura

02:31.200 --> 02:36.510
projectile spell, we're going to spawn a projectile, but only if we're on the server.

02:36.510 --> 02:38.640
So how do we know if we're on the server?

02:38.850 --> 02:45.630
Well, if you pause the video and look through gameplay ability, you may recall that gameplay ability

02:45.660 --> 02:49.160
has a has authority function.

02:49.170 --> 02:52.470
It says true if this is the server or single player.

02:52.470 --> 02:59.250
Now this returns a boolean, so this is a nice convenient function that we can call without having to

02:59.250 --> 03:02.160
go out of our way to find out if we're on the server.

03:02.160 --> 03:03.690
Because there are other ways.

03:03.690 --> 03:05.580
There are always other ways in gas.

03:05.580 --> 03:09.330
We have lots and lots of ways to do the same thing.

03:09.330 --> 03:16.170
We can get our owning ability system components and get the Avatar actor from that and see if that actor

03:16.170 --> 03:17.190
has authority.

03:17.190 --> 03:23.790
There's lots of ways, but we're going to call has authority now has authority, requires a gameplay

03:23.790 --> 03:28.590
ability activation info pointer called activation info.

03:28.980 --> 03:36.630
Well, we can pass one of those in because Activate ability has a gameplay ability activation info called

03:36.630 --> 03:37.890
activation info.

03:37.890 --> 03:44.490
Now it's passed in to activate ability not by pointer but has authority requires a pointer.

03:44.490 --> 03:48.930
So what we can do is pass in the address of activation info.

03:50.940 --> 03:53.100
Now has authority is going to return.

03:53.100 --> 03:55.270
True or false if we have authority?

03:55.290 --> 03:57.720
I'm going to go ahead and just store that in a const.

03:57.720 --> 04:01.040
Bool called B is server.

04:01.050 --> 04:04.110
So we know if we're on the server, it's if this is true.

04:04.530 --> 04:11.880
Now for this video, I'm just concerned with spawning something, so I'm going to return from this function.

04:11.880 --> 04:13.860
If B is server is false.

04:13.890 --> 04:17.580
In other words, if not, B is server return.

04:18.120 --> 04:21.150
And then if we make it past this, we're on the server.

04:21.180 --> 04:25.200
Now we want to spawn a projectile right now.

04:25.200 --> 04:27.090
We can do that with Spawn actor.

04:27.090 --> 04:28.440
We get that from the world.

04:28.440 --> 04:31.440
So we call get world and call spawn.

04:31.440 --> 04:37.710
Actor and spawn actor can spawn something and we can set its location.

04:37.710 --> 04:40.500
We can pass the location in and all that good stuff.

04:40.500 --> 04:47.910
But I'm interested in spawning an actor that's going to fly through the air and hit something and apply

04:47.910 --> 04:48.990
a gameplay effect.

04:48.990 --> 04:55.030
In other words, we're going to set a gameplay effect or a gameplay effect spec on that actor.

04:55.030 --> 05:01.660
And if we're going to be setting variables and things on the actor, there's a way to handle this such

05:01.660 --> 05:07.780
that once the actor is finished spawning, all of those properties are already set and we can do that

05:07.780 --> 05:08.860
by using spawn.

05:08.860 --> 05:10.480
Actor deferred.

05:11.020 --> 05:16.720
Now spawn actor deferred is a template we can pass in the type we'd like to spawn.

05:16.720 --> 05:19.090
It's going to be a or a projectile.

05:19.090 --> 05:22.690
And there's that header, auto included for me.

05:22.690 --> 05:26.800
And this can take in a number of parameters, including the class.

05:26.830 --> 05:29.530
We have our projectile class for that.

05:31.000 --> 05:36.520
We also have a spawn transform that we're going to want to pass in.

05:36.520 --> 05:41.230
So if we make one here F transform called spawn.

05:41.230 --> 05:42.310
Transform.

05:42.870 --> 05:45.510
Then we can pass that in here as well.

05:45.990 --> 05:48.660
But we're going to want to set some properties on that spawn.

05:48.660 --> 05:49.950
Transform, aren't we?

05:50.730 --> 05:52.900
Now we can set an owner actor.

05:52.920 --> 05:59.070
Now, if we're going to set an owner for this projectile, I think it should be the owner of this gameplay

05:59.070 --> 06:02.240
ability and we can get that from the actor info.

06:02.250 --> 06:09.360
In fact, the ability has a function Get owning actor from actor info, so that's pretty easy.

06:09.390 --> 06:17.880
Now next is the instigator, and the instigator is just the pawn that instigated this thing that we're

06:17.880 --> 06:22.860
doing in our case, spawning a projectile that's going to fly through the air and burn someone.

06:22.860 --> 06:23.370
Right.

06:23.370 --> 06:25.710
So what is the instigator?

06:25.710 --> 06:30.570
Well, it's really just that owning actor, but it's got to be a pawn.

06:30.570 --> 06:39.150
So we could just cast it to a pawn cast, to a pawn here and we can cast the owning actor so we can

06:39.150 --> 06:41.190
just pass that right in there.

06:41.190 --> 06:43.240
And there's the pawn.

06:43.780 --> 06:52.210
Now, the next input parameter is a Spawn actor collision handling method, so we can specify that.

06:52.300 --> 06:59.500
Now I'd like it to always spawn regardless of collisions or overlaps, so I'm going to use E spawn actor

06:59.530 --> 07:02.620
collision handling method always spawn.

07:03.040 --> 07:09.550
And now I have this big long line and I'd like to put each of these arguments on their own line here.

07:09.550 --> 07:13.000
So let's just get these each on their own line.

07:14.120 --> 07:14.480
Like.

07:14.480 --> 07:18.500
So now this is going to spawn an actor at this transform.

07:18.500 --> 07:22.010
But this transform is not really defined.

07:22.040 --> 07:27.230
It doesn't have any location or rotation set for it or anything like that.

07:27.230 --> 07:30.620
So where do we want to spawn this projectile?

07:30.890 --> 07:36.260
Well, to just get things working, we could spawn it at the owning actor's location.

07:36.260 --> 07:39.410
But ultimately I'd like to spawn this at the tip of the staff.

07:39.410 --> 07:41.510
That's Aura's weapon, right?

07:41.510 --> 07:43.400
That's where I'd like to spawn it.

07:43.640 --> 07:50.570
However, if that's going to be the case, I don't really want to have to cast to or a character because

07:50.570 --> 07:53.090
this is aura projectile spell.

07:53.120 --> 07:57.080
I don't want it to be dependent specifically on the Aura character class.

07:57.080 --> 08:04.160
I want to be able to get a socket location from the weapon of whoever owns this.

08:04.400 --> 08:08.990
So for that reason, I'd like some kind of interface function, right?

08:08.990 --> 08:14.070
And we know that we have a combat interface over here in our interaction folder.

08:14.070 --> 08:20.490
And this is for functionality shared by both the Aura character and the aura enemy.

08:20.490 --> 08:26.700
So really quick, I'm going to open Aura Character base to show you that Aura character base inherits

08:26.700 --> 08:28.170
from I combat interface.

08:28.170 --> 08:36.060
That interface that the character base class has, that means Aura, character and Aura Enemy both implement

08:36.060 --> 08:42.720
this interface so we can have a function that returns a socket or at least a socket location if we need

08:42.720 --> 08:43.350
that.

08:43.350 --> 08:49.860
And then anything that implements combat interface can implement that function that returns a socket

08:49.860 --> 08:50.760
location.

08:50.760 --> 08:55.770
So why don't we create a function for returning that socket location?

08:55.770 --> 09:00.360
I'm going to close our character base and I'm going to open that interface class.

09:00.360 --> 09:09.240
So combat interface dot H, and I'm going to create a virtual function that will return the socket location.

09:09.240 --> 09:17.460
So this will be virtual F vector and it'll be called get combat socket location.

09:18.150 --> 09:22.680
I'll go ahead and create a definition here that just returns an empty F vector.

09:24.410 --> 09:25.520
Like so.

09:25.520 --> 09:31.850
And now that this function exists in the interface, we can override this now on a character base.

09:31.880 --> 09:33.380
We have a weapon.

09:33.620 --> 09:40.190
So the weapon is going to have some kind of socket on it, presumably, and that socket should have

09:40.190 --> 09:41.270
its own name.

09:41.600 --> 09:50.180
So provided that we have a socket on our weapon and that socket has some kind of socket name, then

09:50.180 --> 09:55.430
as long as we set that in our character blueprint for the character and enemies that have a weapon,

09:55.430 --> 10:01.580
that have a socket on it, then or a character base could easily implement that function from our combat

10:01.580 --> 10:02.540
interface.

10:02.630 --> 10:10.970
So just under weapon, I'm going to make an F name called weapon type socket name.

10:10.970 --> 10:13.640
This will be the name for the tip of the weapon.

10:14.830 --> 10:18.770
This is just to distinguish it from any other sockets that might be on the weapon.

10:18.790 --> 10:23.910
This is the tip socket usually for casting spells or things like that.

10:23.920 --> 10:29.260
So I'm going to make this a uproperty I'm going to make it edit anywhere category combat, just like

10:29.260 --> 10:32.710
the weapon, and then we can implement that interface function.

10:32.980 --> 10:38.530
So I'm going to implement that and we can just put it right here under weapon tip socket name.

10:38.890 --> 10:46.150
So it's a virtual vector function called and what's it called?

10:46.740 --> 10:48.990
Get combat socket location.

10:49.560 --> 10:51.300
Get combat socket.

10:51.300 --> 10:51.930
Location.

10:51.930 --> 10:53.130
That's an override.

10:53.960 --> 10:57.540
Will generate the definition and what is it going to return?

10:57.560 --> 11:00.380
It's going to return the weapon socket.

11:00.380 --> 11:04.820
So we're going to get our weapon and call get socket location.

11:05.000 --> 11:06.800
And this requires an F name.

11:06.800 --> 11:09.890
We're going to use that weapon type socket name.

11:09.890 --> 11:16.520
So now it's up to us to set that weapon socket on the weapon and make sure that we set weapon tip socket

11:16.550 --> 11:18.680
name to the name of that socket.

11:18.680 --> 11:23.600
And then we choose where that socket goes on the weapon and then we can use it for whatever we want,

11:23.630 --> 11:26.960
such as spawning a projectile at that location.

11:26.960 --> 11:35.030
So now we don't have to have our projectile spell ability dependent on a character or even or a character

11:35.030 --> 11:37.040
base or an enemy.

11:37.070 --> 11:41.180
We're just going to cast to the eye combat interface.

11:41.180 --> 11:43.430
So let's get that interface.

11:43.520 --> 11:51.860
We're going to say eye combat interface that's going to result in the combat interface header included.

11:51.860 --> 11:54.060
We're going to call this combat interface.

11:56.250 --> 12:00.800
And set it equal to the result of a cast to eye combat interface.

12:00.810 --> 12:02.400
And what are we casting?

12:02.400 --> 12:06.210
We're going to cast the Avatar actor and we can get that.

12:06.210 --> 12:10.410
We can use get Avatar actor from actor info.

12:10.440 --> 12:15.210
That's a function that we have access to here on the ability class.

12:15.360 --> 12:21.600
And as long as the Avatar actor associated with the ability system component that owns this ability,

12:21.600 --> 12:28.290
then as long as it implements the combat interface, then we can get that weapon socket.

12:28.440 --> 12:35.790
So I'm going to check if combat interface and then we're going to get that socket location by taking

12:35.790 --> 12:42.540
the combat interface and calling get combat socket location that returns an F vector.

12:42.540 --> 12:48.900
We'll store that in a const local F vector, and we'll call this socket location.

12:49.140 --> 12:50.310
And there we go.

12:50.310 --> 12:55.840
So now that we have a location, I'm going to move this call to spawn actor deferred along with that

12:55.840 --> 13:04.360
transform, I'm going to cut and move that up into here and my spawn transform now can have its location

13:04.360 --> 13:04.630
set.

13:04.630 --> 13:12.940
I'm going to take spawn, transform dot location actually dot set, location and pass in socket location.

13:12.940 --> 13:17.200
So now that Transform has its location set to the socket location.

13:17.200 --> 13:18.250
Pretty nice.

13:18.580 --> 13:23.410
Now we don't have really any meaningful way to set its rotation just yet.

13:23.410 --> 13:30.730
There needs to be some kind of way for us to access where we're aiming at, right where we're clicking

13:30.730 --> 13:31.840
in the world.

13:31.840 --> 13:36.190
But as it stands, there's no easy way to do that just yet.

13:36.220 --> 13:42.640
I'm sure you can think of ways to do it, you know, access the Avatar actor, perhaps get its controller

13:42.640 --> 13:46.960
and cast that to an aura player controller and then access that hit result.

13:46.960 --> 13:51.160
And but there are better ways and worse ways to do it right.

13:51.160 --> 13:56.350
We went through all this trouble to make an interface function so we don't have to be dependent on the

13:56.350 --> 13:58.810
Aura character class here.

13:58.810 --> 14:04.650
We're depending on abstractions rather than specifics, and I'd like to keep it that way.

14:04.660 --> 14:10.090
So one step at a time, we'll deal with the rotation of our projectile later.

14:10.090 --> 14:14.170
For now, we just want to spawn it and we want to spawn it at our socket location.

14:14.170 --> 14:15.250
So a couple things.

14:15.250 --> 14:21.910
When we launch the editor, we have to make sure to set that weapon tip socket name on our character

14:22.030 --> 14:26.950
and we have to make sure that auras weapon has a socket with that name.

14:26.950 --> 14:33.460
Because here in Aura Character Base, we are implementing our new interface function get combat socket

14:33.460 --> 14:40.420
location by getting the weapon, getting that socket location on it and passing in weapon tip socket

14:40.450 --> 14:41.140
name.

14:41.140 --> 14:48.190
We're not checking the pointer here, which means that the weapon should always be set on our aura character.

14:48.190 --> 14:56.350
Now we can do a check here, check weapon if we want to do that, but I'd rather not check the pointer

14:56.350 --> 14:59.620
and only return this if it's a valid pointer.

14:59.650 --> 15:05.770
Because in the case where there's not a valid pointer, I'm considering that a problem, an error.

15:05.770 --> 15:07.990
So we'll leave the check there.

15:08.380 --> 15:09.130
Okay.

15:09.130 --> 15:10.180
So great.

15:10.210 --> 15:17.050
Now if we go back to Aura projectile spell, we know that we're going to have a good socket location

15:17.050 --> 15:22.630
provided that we set that weapon tip socket name but we're calling spawn actor deferred.

15:22.630 --> 15:27.430
This is different than calling Spawn actor to actually get that actor spawned.

15:27.460 --> 15:35.680
We have to finish spawning now spawn actor deferred returns a t star, which is of course the type passed

15:35.680 --> 15:37.420
in that's or a projectile.

15:37.540 --> 15:42.310
We're going to take that return value and store it in a local variable.

15:42.310 --> 15:45.820
We'll call it projectile with an E at the end.

15:45.820 --> 15:50.050
And to finish spawning the projectile, we have to take it.

15:50.050 --> 15:54.940
So we take that projectile and call, finish spawning.

15:54.940 --> 15:57.820
And this takes in a transform.

15:57.820 --> 16:00.520
So we'll just once again pass in spawn.

16:00.520 --> 16:01.600
Transform.

16:02.920 --> 16:06.430
So finish spawning is what's going to finish the spawning.

16:06.430 --> 16:08.900
Now, why would we do this in two steps like this?

16:08.920 --> 16:14.140
Well, that's so that we can set things here and we're going to make a big fat to do.

16:14.260 --> 16:16.120
So to do here.

16:16.120 --> 16:27.550
And that's going to be to give the projectile a gameplay effect spec for causing damage.

16:27.790 --> 16:30.850
That's why we're going to do this in two steps.

16:30.850 --> 16:36.130
We want to set this gameplay effect spec for the projectile before we finish spawning it.

16:36.370 --> 16:40.840
For now, we're not going to do that yet, so we have quite a few things left to do.

16:40.840 --> 16:42.490
Let's put another to do up here.

16:42.490 --> 16:51.100
We'll say slash, slash to do, set the projectile rotation.

16:51.100 --> 16:53.470
So we're not doing that yet either.

16:53.620 --> 17:00.940
A couple things to do, but now we can test this out and see if we get a projectile spawned and spawned

17:00.940 --> 17:09.020
at the tip of the staff to boot and combat interface could be moved inside the if statement as writer

17:09.020 --> 17:09.830
is telling me.

17:09.860 --> 17:11.570
Go ahead and do that if you like.

17:11.570 --> 17:13.000
I'm going to keep it like this.

17:13.010 --> 17:16.610
Let's go ahead and launch the editor and see if this works.

17:18.930 --> 17:19.320
All right.

17:19.320 --> 17:22.830
So back in the editor, I have my aura character.

17:22.980 --> 17:30.120
I'm going to take my weapon and browse to it to its skeletal mesh and open that up.

17:30.120 --> 17:32.640
And sure enough, it has a couple sockets on it.

17:32.640 --> 17:37.350
It has a tail socket down there and it has a tip socket up here at the tip.

17:37.560 --> 17:40.800
Looks like it's right here where that little stone is.

17:40.800 --> 17:44.040
If I press w, I can see exactly where it is right there.

17:44.340 --> 17:50.970
So it's called tip socket, which means I have to go back to our character select or a character self

17:50.970 --> 17:56.310
and search for weapon tip socket name and set that name its tip socket.

17:56.910 --> 18:04.710
So now that that's set, we can see if we can get a fireball launched at the tip of the staff.

18:04.710 --> 18:09.990
So save all, let's press play and click on an enemy.

18:10.170 --> 18:13.410
So looks like we got an exception.

18:13.410 --> 18:19.840
Now, when we get an exception like this, we can look at the call stack and see what function calls

18:19.840 --> 18:20.830
led up to it.

18:21.100 --> 18:24.100
So we have ability input tag held.

18:24.100 --> 18:31.480
We have try activate ability right here and we get all the way up to activate ability where we're at

18:31.480 --> 18:38.740
projectile finish spawning here and now I'm seeing exactly what happened because we reached right here

18:38.740 --> 18:46.300
projectile finished spawning and it would crash here if this projectile pointer was null.

18:46.300 --> 18:47.470
And why would that be?

18:47.470 --> 18:47.830
Null?

18:47.830 --> 18:51.310
Well, we're not passing in a valid projectile class here.

18:51.310 --> 18:54.100
And if I hover over it, it just says null.

18:54.460 --> 18:57.630
So that's something that I forgot.

18:57.640 --> 19:05.020
So what I can do is go ahead and launch again and make sure to set that projectile class because of

19:05.020 --> 19:10.120
course, that is something we're going to need to set on the projectile spell gameplay ability.

19:10.660 --> 19:14.970
So another useful example of those debug symbols, right?

19:14.980 --> 19:24.580
So first I'm just going to verify on my aura character that weapon tip socket is still set and it is

19:24.580 --> 19:25.680
it's set to tip socket.

19:25.690 --> 19:26.830
That looks good.

19:26.980 --> 19:35.560
Now I'm going to go to blueprints ability system, gameplay abilities, fire Firebolt and Firebolt and

19:35.560 --> 19:37.780
make sure projectile class is set.

19:37.780 --> 19:40.720
And I'm going to set that to BP Firebolt.

19:41.050 --> 19:43.000
Now I'm going to try this out.

19:43.000 --> 19:48.430
And there's the Firebolt Now it looks like it's working as expected.

19:48.520 --> 19:53.050
Like I'm aiming at the enemy and I shoot a fireball at the enemy.

19:53.140 --> 19:57.480
That's just coincidence that it's going over there to the enemy.

19:57.490 --> 20:04.270
If I come over here next to the enemy and click on the enemy, it still goes that way because our rotation

20:04.270 --> 20:08.080
for this projectile is not defined.

20:08.350 --> 20:10.430
It's the zero rotator, right?

20:10.430 --> 20:11.780
We're not setting it.

20:11.780 --> 20:16.820
And of course, I can only click once because we're never ending the ability, so we can't activate

20:16.820 --> 20:17.660
it again.

20:17.660 --> 20:21.890
And the blueprint isn't doing anything except print a string.

20:21.890 --> 20:24.320
I'm going to go ahead and remove that.

20:24.350 --> 20:31.100
Now, the blueprint event graph is completely empty, but we see that we're able to spawn the projectile

20:31.100 --> 20:37.070
and it's spawning, it looks like, at the tip of the staff, which is where I wanted it to spawn.

20:37.070 --> 20:38.500
So that's perfect.

20:38.510 --> 20:41.660
So everything that we've tried to do so far is working.

20:41.780 --> 20:43.460
We do have a couple to do's.

20:43.460 --> 20:46.190
We need to make sure to set the rotation.

20:46.190 --> 20:48.590
We need to be able to aim this fireball.

20:48.590 --> 20:51.530
We can't just shoot it in that same direction every time.

20:51.530 --> 20:57.560
And of course, later we're going to implement damage with a gameplay effect.

20:57.560 --> 20:58.610
We want to do that too.

20:58.610 --> 21:01.280
So there are a few things to take care of.

21:02.170 --> 21:07.450
But it's a great milestone to know that our gameplay ability can spawn something.

21:07.540 --> 21:15.760
Now, we also mentioned earlier on that we wanted to play a montage and just to remind you, if we go

21:15.760 --> 21:23.300
to assets, characters, aura animations, abilities, there's an animation called Cast Firebolt.

21:23.320 --> 21:24.550
It looks like this.

21:24.580 --> 21:32.880
Now, it would be a lot cooler if we were playing this animation and spawning the fireball like that.

21:32.890 --> 21:39.520
If we were letting her play this animation and perhaps spawning the fireball right there, right at

21:39.520 --> 21:40.660
the tip of the staff.

21:40.690 --> 21:42.490
That would look great.

21:42.670 --> 21:45.430
So that's something that we want to do as well.

21:45.430 --> 21:53.410
And implementing these more complicated things and fleshing out this ability even more is going to require

21:53.410 --> 21:58.180
that we learn more about gas, more about what we can do in abilities.

21:58.180 --> 22:01.970
And we're going to need to learn about ability tasks.

22:01.970 --> 22:06.590
And those are going to be things that we're going to learn about in the videos to come.

22:06.590 --> 22:09.860
So for now, this is a great milestone.

22:09.890 --> 22:15.370
Congratulations on making it this far, but we are not done.

22:15.380 --> 22:22.190
We have some work to do and we're going to get this fireball looking really nice and feeling really

22:22.190 --> 22:24.080
nice when playtesting.

22:24.080 --> 22:25.550
So stick around.

22:25.550 --> 22:32.600
We're going to start our next section on ability tasks and start making our gameplay abilities much

22:32.600 --> 22:33.890
more interesting.
