WEBVTT

00:07.180 --> 00:08.290
Welcome back.

00:08.290 --> 00:15.010
So we've reached a point where we can't really test or develop any further until we start saving things.

00:15.460 --> 00:21.700
Well, yes, I can switch my widget to the enter name widget, but what happens when I enter the name

00:21.700 --> 00:23.680
Stephen and click new slot?

00:23.680 --> 00:25.270
Well, nothing happens, right?

00:25.420 --> 00:29.050
This is when we need to start saving things.

00:29.050 --> 00:36.040
We have to save that name and designate this slot now to be taken, and then switch this widget to the

00:36.040 --> 00:37.360
taken widget.

00:37.360 --> 00:39.100
Let's take a look at what that looks like.

00:39.100 --> 00:41.440
Here's the taken widget.

00:41.440 --> 00:45.580
It's going to switch now to this widget.

00:45.580 --> 00:53.350
And while it does have level and dungeon and we don't quite know what to put there yet, it has player

00:53.350 --> 00:55.810
name and that needs to be updated.

00:56.200 --> 01:04.630
So we need to start saving things and to save something to disk we have to create a save game object.

01:04.630 --> 01:06.820
So we're going to create a save game object.

01:06.820 --> 01:09.790
We're going to go to C plus plus classes Aura Public.

01:09.790 --> 01:14.020
And I'm going to stick this in the game folder next to our game mode.

01:14.020 --> 01:14.560
Why.

01:14.590 --> 01:18.130
Because I just feel like it's related enough to the game mode.

01:18.130 --> 01:23.020
And it's going to be closely intimate with the game mode in some ways.

01:23.020 --> 01:24.460
So we're going to create it here.

01:24.460 --> 01:30.070
Now I'm going to create a class of type save game.

01:30.280 --> 01:32.110
It's a save game object.

01:32.110 --> 01:35.050
This is how we can save data to disk.

01:35.050 --> 01:36.370
We're going to click next.

01:36.370 --> 01:38.650
And this goes right into game.

01:38.890 --> 01:43.300
And I'm going to call this load screen save game.

01:43.750 --> 01:49.420
So this is what we're going to use to save data from the load screen.

01:49.780 --> 01:53.920
And I'm going to click Create Class I'm going to click no and close the editor.

01:54.490 --> 01:59.080
And open up my new load screen save game object.

01:59.860 --> 02:04.870
Here it is now load screen save game needs a couple of variables.

02:05.420 --> 02:09.350
I'm going to make a public section and just have a couple public variables.

02:09.350 --> 02:17.150
And when we load and save data, we identify that saved data by name.

02:17.150 --> 02:18.920
We can use an F string.

02:19.610 --> 02:21.800
We can call this slot name.

02:22.610 --> 02:28.280
And we can initialize this to an empty f string and make this a uproperty.

02:28.280 --> 02:32.930
Now, a name is not the only thing we identify our save data with.

02:32.930 --> 02:36.890
We also identify our save data with an int 32.

02:36.890 --> 02:39.650
So we're going to have a slot index as well.

02:40.010 --> 02:42.110
And this will be zero by default.

02:43.130 --> 02:45.410
And we'll also get a uproperty.

02:45.500 --> 02:54.650
So whenever we save data we have to specify what we're saving by name and index two different values.

02:55.420 --> 03:01.750
And on top of that, our save game object can have variables for whatever it wants to save.

03:01.750 --> 03:06.670
And I'm going to save an F string called player name.

03:07.950 --> 03:12.540
And I'm going to set this to an F string with a default value.

03:12.570 --> 03:13.830
Default name.

03:13.860 --> 03:19.230
Now you might be wondering how come we can't just use player name instead of slot name and identify

03:19.230 --> 03:23.220
the slot by the name instead of having two strings?

03:23.250 --> 03:29.010
Well, what if you want to save one slot with your name, and then save another slot with the same name?

03:29.010 --> 03:34.290
You couldn't do that if you were using the name to identify your save slot.

03:34.290 --> 03:38.280
So we're going to have player name as a separate variable.

03:38.700 --> 03:40.440
Okay, so we have slot index.

03:40.440 --> 03:41.670
We have slot name.

03:41.670 --> 03:43.590
How do we save data to it.

03:43.620 --> 03:48.420
Well first of all we have to pick a class from which to do this.

03:48.420 --> 03:54.900
And I'm going to choose the game mode because I feel like it's a pretty appropriate class to do this

03:54.900 --> 03:55.560
kind of thing.

03:55.560 --> 03:59.130
Game modes typically have authority over the rules of the game.

03:59.130 --> 04:01.830
I think that's closely related to saving the game.

04:01.830 --> 04:08.280
So we're going to use the game mode for this, and the game mode needs a function that can save data.

04:08.400 --> 04:11.100
So I'm going to make a function that can save slot data.

04:11.100 --> 04:12.810
It's going to be a public function.

04:12.810 --> 04:14.670
So this function will be void.

04:14.670 --> 04:17.400
And I'm going to call it save slot data.

04:17.940 --> 04:23.550
Now save slot data is going to need to know what data to save.

04:23.880 --> 04:28.080
So what are we going to pass in to save slot data.

04:28.610 --> 04:32.540
Well, I'd like to pass in our mVVM load slot.

04:32.540 --> 04:34.250
That seems kind of strange, doesn't it?

04:34.250 --> 04:37.940
But really, our mVVM is going to have data.

04:37.940 --> 04:39.710
It's going to have values stored in it.

04:39.710 --> 04:45.800
Remember, mVVM stores state and it's closely related to the view.

04:45.830 --> 04:49.010
It's going to have its own player name.

04:49.010 --> 04:52.580
In fact, we can give it an F string called player Name.

04:53.000 --> 04:53.870
And we will.

04:53.870 --> 04:58.610
And it's going to be closely related to the player name in the widget.

04:58.610 --> 05:06.410
We'll get to that when we learn how to bind variables on an mVVM ViewModel to the widget, but until

05:06.410 --> 05:15.770
then, we're just going to take our save slot data, and we're going to pass in an mVVM load slot object

05:15.770 --> 05:18.530
whenever we want to save data.

05:19.040 --> 05:23.390
And then the game mode will harvest that data and save it to disk.

05:23.930 --> 05:29.240
In fact, let's go ahead and just add a F string called Player name to load slot.

05:30.790 --> 05:32.050
We'll say F string.

05:32.050 --> 05:33.100
Player name.

05:34.370 --> 05:36.290
And we'll give it a uproperty.

05:37.160 --> 05:45.890
And here in our game mode and save slot data, we're going to take in a um VM load slot.

05:45.890 --> 05:49.850
We're going to forward declare it here passing it in by pointer.

05:49.850 --> 05:51.800
And this will be the load slot.

05:53.090 --> 05:59.480
And we also want to pass in the slot index so we can generate this definition.

06:02.490 --> 06:03.630
So how do we do that?

06:03.630 --> 06:04.440
Well, we use you.

06:04.440 --> 06:05.910
Gameplay statics.

06:09.410 --> 06:16.340
So, including Kismet, gameplay, statics and we call Create Save GameObject.

06:16.700 --> 06:20.210
Now this requires a save game class.

06:20.210 --> 06:22.190
We need a subclass of.

06:22.460 --> 06:27.560
So our game mode is going to need to know what class to create for this.

06:27.980 --> 06:32.840
So in our Game Modes header file we're going to create a subclass of.

06:33.320 --> 06:35.090
It's going to be a u save game.

06:35.090 --> 06:37.040
It has to be U save game.

06:37.040 --> 06:44.870
We'll add a forward declaration and this will be load screen save game class.

06:45.730 --> 06:49.420
And we'll set this from the blueprint, so we'll give it a U property.

06:51.040 --> 06:59.920
And edit defaults only, and in the cpp file we'll call create save game object with load screen save

06:59.920 --> 07:00.970
game class.

07:00.970 --> 07:04.000
And we'll store this in a local you save game.

07:05.470 --> 07:09.910
So this function has to take a subclass of you save game.

07:10.760 --> 07:13.850
It can't be of a child class of that.

07:14.000 --> 07:16.220
We'll call this save game object.

07:17.720 --> 07:18.800
But here's the thing.

07:18.800 --> 07:22.400
We should check to see if this particular slot exists already.

07:22.400 --> 07:31.460
If a slot exists with the name and slot index associated with this load slot, which means our mVVM

07:31.460 --> 07:36.800
should also have a load slot name and a slot index as well.

07:36.800 --> 07:45.590
So in mVVM load slot, not only should we have a player name, we should also have a load slot name

07:47.360 --> 07:50.840
and we should also have a slot index.

07:51.440 --> 07:58.940
That way, our mVVM is going to be associated with the slot name and the slot index, and our game mode

07:58.940 --> 08:01.040
can check to see if it exists already.

08:01.040 --> 08:02.390
So how do we do that?

08:02.690 --> 08:14.540
Well, we say if you gameplay statics does save game exist and we take our load slot, the mVVM passed

08:14.540 --> 08:15.110
in.

08:15.720 --> 08:22.680
And get the load slot name and pass that in and get its slot index, which we have the slot index here.

08:24.780 --> 08:26.190
If it already exists.

08:26.190 --> 08:31.860
We want to delete it because we're trying to save to this slot and we want it to be gone.

08:31.860 --> 08:39.810
So we're going to take you gameplay statics delete game and slot using load slot.

08:41.100 --> 08:44.610
Load slot name and the slot index.

08:45.240 --> 08:51.270
So we'll delete it if it already exists, since we're trying to save to that slot, and then we'll create

08:51.270 --> 08:51.600
one.

08:51.600 --> 08:56.040
Now after we've created one, we cast to load screen save game.

08:56.040 --> 09:04.110
So we're going to say you load screen save game load screen save game equals.

09:04.440 --> 09:08.520
And we're going to cast to you load screen save game.

09:10.120 --> 09:11.740
Save game object.

09:14.740 --> 09:17.110
And then we can take load screen save game.

09:20.350 --> 09:25.120
And take its player name and set it to the player name and load slot.

09:28.990 --> 09:29.410
Right.

09:29.410 --> 09:36.700
So we're calling save slot data passing in load slot checking to see if this slot already exists with

09:36.700 --> 09:38.140
this name and index.

09:38.140 --> 09:46.000
If not, we create a save game object and then we cast it to load screen save game and set its player

09:46.000 --> 09:46.600
name.

09:46.600 --> 09:52.480
Now at this point we have a save game object of this type with its player name set.

09:52.480 --> 09:56.140
So now is the time to actually save the game.

09:56.140 --> 10:00.370
So we use you gameplay statics for that and we use save game to slot.

10:02.880 --> 10:08.760
And this takes that load screen save game object load screen save game.

10:08.760 --> 10:12.810
And then we need to specify the slot name and the slot index.

10:12.810 --> 10:15.150
And that is in our load slot.

10:15.150 --> 10:18.810
We just gave it slot name load slot name.

10:18.810 --> 10:21.600
And we have our slot index.

10:22.050 --> 10:25.620
So save slot data is going to save that data.

10:25.620 --> 10:33.120
So now that the game mode has the capability of saving slot data using save slot data, we can go now

10:33.120 --> 10:36.810
into our load screen view model.

10:36.810 --> 10:37.680
Here it is.

10:38.600 --> 10:43.370
Because we have a blueprint callable function for when new slot button has been pressed.

10:44.030 --> 10:45.080
This has the slot.

10:45.080 --> 10:46.400
It has the entered name.

10:46.400 --> 10:47.960
We can save that.

10:47.960 --> 10:52.370
So we just need to get the game mode with a Ora game mode base.

10:53.060 --> 10:55.040
We'll call it Ora game mode.

10:55.940 --> 10:57.800
We need to get game mode from you.

10:57.800 --> 10:58.250
Gameplay.

10:58.250 --> 10:59.360
Statics.

11:01.480 --> 11:03.610
So we'll get that include there.

11:03.610 --> 11:05.440
We can call get game mode.

11:05.470 --> 11:12.370
Now this requires a world context object, but this returns a a game mode base.

11:12.370 --> 11:15.130
We need to cast a or a game mode base.

11:15.130 --> 11:16.540
So let's cast it.

11:24.670 --> 11:28.210
And once we have it, we can now save data.

11:28.210 --> 11:30.370
But we need to know which slot.

11:30.370 --> 11:32.710
Well, we have our load slots map.

11:32.710 --> 11:35.740
We can index it with slot.

11:36.340 --> 11:37.480
It's called load slots.

11:37.480 --> 11:39.160
We can index it with slot.

11:39.490 --> 11:43.060
And we have a player name that we can set.

11:44.060 --> 11:49.670
And we can set that to the entered name that was passed in to the blueprint callable function.

11:49.670 --> 11:53.960
Once we've set its name, we can save that slot data.

11:53.960 --> 11:55.910
We can take our A game mode.

11:57.070 --> 12:02.710
And call save slot data using this view model and load slots.

12:02.740 --> 12:07.150
Load slots of slot and pass in that slot.

12:07.960 --> 12:09.280
But here's the thing.

12:09.280 --> 12:15.520
We're identifying these slots by a slot name now, which means we need to be setting those.

12:15.970 --> 12:20.680
And we should set them as soon as we create them and initialize load slots.

12:20.680 --> 12:27.340
So as soon as I create load slot zero I'm going to take that slot load slot zero.

12:27.340 --> 12:31.390
And I'm going to set its slot load slot name.

12:32.020 --> 12:35.170
I'm going to set it to an F string.

12:36.220 --> 12:39.220
And we'll just give these each unique names.

12:39.220 --> 12:41.170
I'll just call it load slot zero.

12:41.200 --> 12:43.630
This is just a way to identify it.

12:43.990 --> 12:45.820
And I'm going to do it for one and two.

12:45.850 --> 12:47.050
So load slot one.

12:47.050 --> 12:50.440
We'll set load slot name on it to load slot one.

12:50.860 --> 12:56.080
And for two we'll take that one and set its load slot name.

12:56.350 --> 12:58.720
So now these each have unique names.

12:58.720 --> 13:03.310
And when we save our slot data we'll save with a unique name.

13:04.010 --> 13:05.930
Okay, so now we're saving data.

13:05.930 --> 13:12.140
Now we don't really have an easy way to test this until we start loading data.

13:12.680 --> 13:16.970
So we still have a few steps to go, but now at least we're saving data.

13:16.970 --> 13:21.140
At least we can check to see if we get a successful compile.

13:22.410 --> 13:22.830
All right.

13:22.830 --> 13:23.310
We do.

13:23.310 --> 13:29.850
And actually, there's one thing we can check when we click on new slot button pressed, we can tell

13:29.850 --> 13:33.930
that load slot to broadcast a new widget switcher index.

13:33.930 --> 13:37.230
We can broadcast a value of say two.

13:37.260 --> 13:40.950
We'll just make it hard coded to until we code this completely.

13:40.950 --> 13:46.260
But we'll just call initialize slot here and we can at least test that part.

13:46.260 --> 13:52.920
So right here under new slot button pressed we'll take that load slots of slot.

13:56.780 --> 14:01.640
We'll call its initialized slot function, and at least we'll see that change.

14:01.760 --> 14:04.250
So let's compile and go back into the editor.

14:06.120 --> 14:07.590
And back in the editor.

14:07.590 --> 14:11.670
We're going to go ahead and make a save game Object Blueprint.

14:11.670 --> 14:13.920
We'll go into the game folder and do it.

14:13.950 --> 14:18.780
New blueprint class load screen save game.

14:19.440 --> 14:27.390
We'll make a blueprint version of this BP load screen save game, and we'll go into load screen game

14:27.390 --> 14:28.980
mode and set this.

14:28.980 --> 14:33.060
We'll go ahead and find load screen save game class.

14:33.060 --> 14:34.410
We'll set that there.

14:37.860 --> 14:39.030
Save all.

14:39.870 --> 14:42.270
And go to our load menu and press play.

14:42.270 --> 14:49.530
And at least we know that if we click on Enter Name and enter some text and click New Slot, then we

14:49.530 --> 14:51.960
switch to this widget.

14:51.990 --> 14:55.410
Now we're not showing the player name that we entered in.

14:55.410 --> 14:56.910
We still need to do that.

14:56.910 --> 15:03.570
And that's going to require actually binding variables on the widget to variables in their view model.

15:03.570 --> 15:06.960
And we'll get to see how that is closely related.

15:06.960 --> 15:08.640
We'll do that next.

15:08.670 --> 15:09.720
I'll see you soon.
