Welcome back.
So we've reached a point where we can't really test or develop any further until we start saving things.
Well, yes, I can switch my widget to the enter name widget, but what happens when I enter the name
Stephen and click new slot?
Well, nothing happens, right?
This is when we need to start saving things.
We have to save that name and designate this slot now to be taken, and then switch this widget to the
taken widget.
Let's take a look at what that looks like.
Here's the taken widget.
It's going to switch now to this widget.
And while it does have level and dungeon and we don't quite know what to put there yet, it has player
name and that needs to be updated.
So we need to start saving things and to save something to disk we have to create a save game object.
So we're going to create a save game object.
We're going to go to C plus plus classes Aura Public.
And I'm going to stick this in the game folder next to our game mode.
Why.
Because I just feel like it's related enough to the game mode.
And it's going to be closely intimate with the game mode in some ways.
So we're going to create it here.
Now I'm going to create a class of type save game.
It's a save game object.
This is how we can save data to disk.
We're going to click next.
And this goes right into game.
And I'm going to call this load screen save game.
So this is what we're going to use to save data from the load screen.
And I'm going to click Create Class I'm going to click no and close the editor.
And open up my new load screen save game object.
Here it is now load screen save game needs a couple of variables.
I'm going to make a public section and just have a couple public variables.
And when we load and save data, we identify that saved data by name.
We can use an F string.
We can call this slot name.
And we can initialize this to an empty f string and make this a uproperty.
Now, a name is not the only thing we identify our save data with.
We also identify our save data with an int 32.
So we're going to have a slot index as well.
And this will be zero by default.
And we'll also get a uproperty.
So whenever we save data we have to specify what we're saving by name and index two different values.
And on top of that, our save game object can have variables for whatever it wants to save.
And I'm going to save an F string called player name.
And I'm going to set this to an F string with a default value.
Default name.
Now you might be wondering how come we can't just use player name instead of slot name and identify
the slot by the name instead of having two strings?
Well, what if you want to save one slot with your name, and then save another slot with the same name?
You couldn't do that if you were using the name to identify your save slot.
So we're going to have player name as a separate variable.
Okay, so we have slot index.
We have slot name.
How do we save data to it.
Well first of all we have to pick a class from which to do this.
And I'm going to choose the game mode because I feel like it's a pretty appropriate class to do this
kind of thing.
Game modes typically have authority over the rules of the game.
I think that's closely related to saving the game.
So we're going to use the game mode for this, and the game mode needs a function that can save data.
So I'm going to make a function that can save slot data.
It's going to be a public function.
So this function will be void.
And I'm going to call it save slot data.
Now save slot data is going to need to know what data to save.
So what are we going to pass in to save slot data.
Well, I'd like to pass in our mVVM load slot.
That seems kind of strange, doesn't it?
But really, our mVVM is going to have data.
It's going to have values stored in it.
Remember, mVVM stores state and it's closely related to the view.
It's going to have its own player name.
In fact, we can give it an F string called player Name.
And we will.
And it's going to be closely related to the player name in the widget.
We'll get to that when we learn how to bind variables on an mVVM ViewModel to the widget, but until
then, we're just going to take our save slot data, and we're going to pass in an mVVM load slot object
whenever we want to save data.
And then the game mode will harvest that data and save it to disk.
In fact, let's go ahead and just add a F string called Player name to load slot.
We'll say F string.
Player name.
And we'll give it a uproperty.
And here in our game mode and save slot data, we're going to take in a um VM load slot.
We're going to forward declare it here passing it in by pointer.
And this will be the load slot.
And we also want to pass in the slot index so we can generate this definition.
So how do we do that?
Well, we use you.
Gameplay statics.
So, including Kismet, gameplay, statics and we call Create Save GameObject.
Now this requires a save game class.
We need a subclass of.
So our game mode is going to need to know what class to create for this.
So in our Game Modes header file we're going to create a subclass of.
It's going to be a u save game.
It has to be U save game.
We'll add a forward declaration and this will be load screen save game class.
And we'll set this from the blueprint, so we'll give it a U property.
And edit defaults only, and in the cpp file we'll call create save game object with load screen save
game class.
And we'll store this in a local you save game.
So this function has to take a subclass of you save game.
It can't be of a child class of that.
We'll call this save game object.
But here's the thing.
We should check to see if this particular slot exists already.
If a slot exists with the name and slot index associated with this load slot, which means our mVVM
should also have a load slot name and a slot index as well.
So in mVVM load slot, not only should we have a player name, we should also have a load slot name
and we should also have a slot index.
That way, our mVVM is going to be associated with the slot name and the slot index, and our game mode
can check to see if it exists already.
So how do we do that?
Well, we say if you gameplay statics does save game exist and we take our load slot, the mVVM passed
in.
And get the load slot name and pass that in and get its slot index, which we have the slot index here.
If it already exists.
We want to delete it because we're trying to save to this slot and we want it to be gone.
So we're going to take you gameplay statics delete game and slot using load slot.
Load slot name and the slot index.
So we'll delete it if it already exists, since we're trying to save to that slot, and then we'll create
one.
Now after we've created one, we cast to load screen save game.
So we're going to say you load screen save game load screen save game equals.
And we're going to cast to you load screen save game.
Save game object.
And then we can take load screen save game.
And take its player name and set it to the player name and load slot.
Right.
So we're calling save slot data passing in load slot checking to see if this slot already exists with
this name and index.
If not, we create a save game object and then we cast it to load screen save game and set its player
name.
Now at this point we have a save game object of this type with its player name set.
So now is the time to actually save the game.
So we use you gameplay statics for that and we use save game to slot.
And this takes that load screen save game object load screen save game.
And then we need to specify the slot name and the slot index.
And that is in our load slot.
We just gave it slot name load slot name.
And we have our slot index.
So save slot data is going to save that data.
So now that the game mode has the capability of saving slot data using save slot data, we can go now
into our load screen view model.
Here it is.
Because we have a blueprint callable function for when new slot button has been pressed.
This has the slot.
It has the entered name.
We can save that.
So we just need to get the game mode with a Ora game mode base.
We'll call it Ora game mode.
We need to get game mode from you.
Gameplay.
Statics.
So we'll get that include there.
We can call get game mode.
Now this requires a world context object, but this returns a a game mode base.
We need to cast a or a game mode base.
So let's cast it.
And once we have it, we can now save data.
But we need to know which slot.
Well, we have our load slots map.
We can index it with slot.
It's called load slots.
We can index it with slot.
And we have a player name that we can set.
And we can set that to the entered name that was passed in to the blueprint callable function.
Once we've set its name, we can save that slot data.
We can take our A game mode.
And call save slot data using this view model and load slots.
Load slots of slot and pass in that slot.
But here's the thing.
We're identifying these slots by a slot name now, which means we need to be setting those.
And we should set them as soon as we create them and initialize load slots.
So as soon as I create load slot zero I'm going to take that slot load slot zero.
And I'm going to set its slot load slot name.
I'm going to set it to an F string.
And we'll just give these each unique names.
I'll just call it load slot zero.
This is just a way to identify it.
And I'm going to do it for one and two.
So load slot one.
We'll set load slot name on it to load slot one.
And for two we'll take that one and set its load slot name.
So now these each have unique names.
And when we save our slot data we'll save with a unique name.
Okay, so now we're saving data.
Now we don't really have an easy way to test this until we start loading data.
So we still have a few steps to go, but now at least we're saving data.
At least we can check to see if we get a successful compile.
All right.
We do.
And actually, there's one thing we can check when we click on new slot button pressed, we can tell
that load slot to broadcast a new widget switcher index.
We can broadcast a value of say two.
We'll just make it hard coded to until we code this completely.
But we'll just call initialize slot here and we can at least test that part.
So right here under new slot button pressed we'll take that load slots of slot.
We'll call its initialized slot function, and at least we'll see that change.
So let's compile and go back into the editor.
And back in the editor.
We're going to go ahead and make a save game Object Blueprint.
We'll go into the game folder and do it.
New blueprint class load screen save game.
We'll make a blueprint version of this BP load screen save game, and we'll go into load screen game
mode and set this.
We'll go ahead and find load screen save game class.
We'll set that there.
Save all.
And go to our load menu and press play.
And at least we know that if we click on Enter Name and enter some text and click New Slot, then we
switch to this widget.
Now we're not showing the player name that we entered in.
We still need to do that.
And that's going to require actually binding variables on the widget to variables in their view model.
And we'll get to see how that is closely related.
We'll do that next.
I'll see you soon.