WEBVTT

00:06.930 --> 00:08.100
Welcome back.

00:08.100 --> 00:15.630
Now I'm here in gameplay effect types dot CP taking a look at the gameplay effect context net serialize

00:15.630 --> 00:19.620
function which takes three inputs now be out.

00:19.620 --> 00:22.740
Success is probably the most self-explanatory.

00:23.040 --> 00:26.490
It returns true if serialization was a success.

00:26.490 --> 00:31.020
Let's keep working from right to left and take a look at package map.

00:31.020 --> 00:31.470
The U.

00:31.470 --> 00:32.940
Package Map class.

00:32.940 --> 00:40.830
If we right click and go to declaration or usages, we see that it's a U object and it says maps, objects

00:40.830 --> 00:45.060
and names to and from indices for network communication.

00:45.060 --> 00:50.280
So this is just a tool used to help map objects to indices.

00:50.280 --> 00:50.910
Why?

00:50.940 --> 00:58.350
Because when serializing all the objects, all the variables of a struct are converted into strings

00:58.350 --> 00:59.940
of zeros and ones.

00:59.940 --> 01:08.140
And you can think of this as a bit array, an array of bits, zeros and ones and when you serialize

01:08.170 --> 01:14.890
a whole bunch of things next to each other, it helps to know what's the index for when one object starts

01:14.890 --> 01:16.330
and another begins.

01:16.420 --> 01:19.140
So u package map is used for that.

01:19.150 --> 01:25.930
Now the leftmost or first input parameter is the archive called R.

01:25.930 --> 01:28.420
Now let's take a look at the archive.

01:28.420 --> 01:34.750
We'll go to declaration or usages and the comment says base class for archives that can be used for

01:34.750 --> 01:39.340
loading, saving and garbage collecting in a byte order neutral way.

01:39.340 --> 01:46.690
Byte order Neutral is kind of networking lingo for the way that the bytes are handled.

01:46.690 --> 01:53.890
In a word, a word is a unit of data that contains bytes and byte order.

01:53.890 --> 01:59.770
Neutral is sometimes referred to as big endian endian with an E, not with an eye.

01:59.800 --> 02:08.740
And it's just a way that bytes are ordered in each word or each fundamental unit of data for a processor.

02:08.740 --> 02:10.360
Now it doesn't really matter.

02:10.360 --> 02:13.180
We don't have to know too deeply how that works.

02:13.180 --> 02:20.920
We just have to know that F archive is capable of storing serialized data and it also has the ability

02:20.920 --> 02:22.030
to serialize things.

02:22.030 --> 02:28.330
Notice it has the operator left shift overloaded for lots of types.

02:28.330 --> 02:35.080
When you see this operator with an operator here and parentheses, this is an operator overload.

02:35.080 --> 02:41.080
And this right here says that we can use the left shift operator with an F archive on the left hand

02:41.110 --> 02:44.260
side and an F text on the right hand side.

02:44.260 --> 02:49.810
And look, the comment says serializes an F text value from or into an archive.

02:49.810 --> 02:56.830
Now there are lots of these for lots of different types, so the F archive is capable of serializing

02:56.830 --> 02:58.270
lots of different types.

02:58.270 --> 03:05.860
But the key words I want you to see that I don't want you to overlook are from or into.

03:05.890 --> 03:14.470
Now that's kind of interesting from or into seems to imply that we can take an F text and use the left

03:14.470 --> 03:18.130
shift operator and serialize it into the archive.

03:18.160 --> 03:28.210
Or we can take that f text and the archive can take the serialized data and unserialize it and store

03:28.210 --> 03:29.710
it in that F text.

03:29.800 --> 03:37.480
So the left shift operator yes, it looks like it's pointed to the left, but think of it as both ways.

03:37.480 --> 03:41.170
It works to and from the archive.

03:41.200 --> 03:42.700
Let's talk about this.

03:43.150 --> 03:51.040
So we know that there's this archive struct and its type is F archive and we know that it's good for

03:51.040 --> 03:53.310
saving loading and storing data.

03:53.320 --> 04:02.290
Now it stores this data serialized as a series of bits and it overloads this left shift operator for

04:02.290 --> 04:08.620
lots of different types and we know that it works both ways depending on the context, if we're saving

04:08.620 --> 04:09.730
or loading.

04:09.910 --> 04:11.910
And that's exactly how it works.

04:11.920 --> 04:18.730
If we have an F archive and we're using the left shift operator and on the right hand side we have some

04:18.730 --> 04:25.840
Boolean variable, for example, Well, if we're saving, then that left shift operator is going to

04:25.840 --> 04:30.070
take that boolean value and serialize it and store it in the archive.

04:30.280 --> 04:36.820
However, on the other hand, if the context is different, if we're in the process of loading, then

04:36.820 --> 04:38.980
we're going in the reverse direction.

04:38.980 --> 04:46.520
That series of bits is deserialized and then stored in that boolean that exists on the right hand side

04:46.520 --> 04:47.720
of the left shift.

04:47.750 --> 04:48.650
Operator.

04:48.650 --> 04:55.370
So just be aware of the versatility of the F archives overloads for this operator.

04:55.890 --> 05:01.110
So now that we know about that, let's go back to gameplay effect types.

05:01.110 --> 05:08.760
And I'd actually like to go back to the CPP file gameplay effect types dot CPP because we need to understand

05:08.760 --> 05:10.020
what's going on here.

05:10.020 --> 05:15.330
We know about the input parameters and what they do for us, but now let's talk about the logistics

05:15.330 --> 05:16.620
of how this happens.

05:16.650 --> 05:25.050
Now the first line here is a Uint8 declaration, a local variable called rep bits, and this unsigned

05:25.080 --> 05:28.020
eight bit integer is set to zero.

05:28.020 --> 05:35.340
Now we have an if statement taking the R this F archive and checking to see if it's saving.

05:35.340 --> 05:41.850
So the archive seems to know if we're saving or loading data and if we're saving it performs some kind

05:41.850 --> 05:46.260
of check, some validation, checking the member variables.

05:46.260 --> 05:51.120
It's checking be replicate, instigator and instigator is valid.

05:51.270 --> 05:56.340
What it's doing is trying to decide should we serialize that instigator here?

05:56.350 --> 06:03.610
If the answer is yes, then that means we want that instigator in our gameplay effect context struct

06:03.640 --> 06:07.720
to be replicated whenever this struct gets replicated.

06:07.750 --> 06:12.850
Now, if instigator is not valid, well then why bother serializing it?

06:12.850 --> 06:13.480
Right?

06:13.480 --> 06:15.610
So that's why we're checking.

06:15.730 --> 06:18.520
But what is this business here?

06:18.670 --> 06:25.750
Rep bits pipe symbol equal sign one left shift zero.

06:25.750 --> 06:27.190
How do you even read this?

06:27.190 --> 06:34.750
Well, it's read as rep bits bitwise or equals one left shift zero.

06:35.050 --> 06:39.880
In order to understand this line, we have to kind of break it down piece by piece.

06:40.210 --> 06:42.730
So let's analyze this a little closer.

06:43.400 --> 06:51.050
We know that Net Serialize is creating a local variable called bits and rep bits is an unsigned eight

06:51.050 --> 06:52.220
bit integer.

06:52.280 --> 06:59.540
What that means is in binary this is all zeros with eight binary digits.

06:59.570 --> 07:06.680
Eight bits a u and eight is one byte, which is eight bits in size and we're initializing it to zero.

07:06.680 --> 07:09.740
So all eight bits are zero in this variable.

07:10.040 --> 07:18.570
Now the line that we're confused about is this one rep bits bitwise or equals one left shift zero.

07:18.590 --> 07:23.990
Now bitwise or equals is just like plus equals or times equals.

07:24.020 --> 07:28.820
It's equivalent to taking rep bits and setting it equal to itself.

07:29.590 --> 07:32.770
Bitwise or one left shift zero.

07:32.920 --> 07:34.900
So these two lines are equivalent.

07:34.930 --> 07:41.310
Now this here is the bitwise or it's half of the or symbol that we're all familiar with.

07:41.320 --> 07:44.920
And this is the left shift or shift left.

07:44.950 --> 07:49.390
Operator So what exactly are these operators doing?

07:49.630 --> 07:53.920
Well, I'd like to take a look at the bitwise or just by itself.

07:54.220 --> 08:01.690
Let's say we have a variable called oh, it's a Uint eight and let's say that its value is zero, which

08:01.690 --> 08:07.510
means in binary it's eight bits, eight digits, all of which are zero.

08:07.600 --> 08:10.610
Now let's say we have another integer called one.

08:10.630 --> 08:18.550
This is also a uint eight and in binary this is what it looks like eight digits, all zeros except for

08:18.550 --> 08:20.800
the rightmost digit, which is a one.

08:20.830 --> 08:24.400
Now let's say we'd like to perform a bitwise operation on it.

08:24.400 --> 08:26.080
The bitwise or.

08:26.260 --> 08:28.660
So how does the bitwise or work?

08:29.270 --> 08:37.400
Well, the result is an unsigned eight bit integer, eight digits long, and each digit is the result

08:37.400 --> 08:44.370
of an or of one bit in one of the integers and one bit in the other integer.

08:44.390 --> 08:46.970
So let's take the leftmost digit.

08:46.970 --> 08:50.090
In each one we perform an Or.

08:50.120 --> 08:56.090
Now how does an or work with Booleans If both the left and right hand side are false, then the result

08:56.090 --> 08:56.950
is false.

08:56.960 --> 09:00.170
If either one of them is true, then the result is true.

09:00.200 --> 09:01.640
That's how ors work.

09:01.640 --> 09:05.170
Well, they work the same with ones and zeros as well.

09:05.180 --> 09:10.580
If both digits are zeros, then the result is a zero.

09:10.940 --> 09:13.370
That means for the next digit over.

09:13.370 --> 09:19.490
And each one we compare them, they're both zero and that means the result is zero.

09:19.520 --> 09:21.830
The same goes for the rest of these.

09:21.860 --> 09:23.480
We have all zeros.

09:23.480 --> 09:27.110
So for the rest of those digits in the result, we get zero.

09:27.140 --> 09:34.100
The only place where they're different is this very rightmost digit In each of these integers in O it's

09:34.100 --> 09:36.560
a zero and in one it's a one.

09:36.590 --> 09:45.170
Now, zero bitwise or one is going to result in one If either one of them are a one, the result is

09:45.170 --> 09:45.830
a one.

09:45.830 --> 09:48.980
So if they're both zero, the result is a zero.

09:48.980 --> 09:53.720
So the result of a bitwise or of O and one is this.

09:54.020 --> 09:56.240
All zeros with a one at the end.

09:56.270 --> 09:58.670
That's just the number one.

09:58.850 --> 10:00.860
Now that was a pretty easy example.

10:00.860 --> 10:02.060
Let's try another one.

10:02.060 --> 10:04.790
Let's say that O is this number.

10:04.790 --> 10:11.330
Here we have a one in a digit that's two away from the end at the left there.

10:11.330 --> 10:14.180
And we have one which is this number.

10:14.210 --> 10:24.290
Now the bitwise or results in a you int eight and we check bitwise each digit performing the Or.

10:24.320 --> 10:31.100
Now these pairs of digits are all zeros, so that means there's zero in the result.

10:31.100 --> 10:37.100
And these pairs of digits all have at least a 1 in 1 or the other of the two variables.

10:37.100 --> 10:40.850
And that means that the results for these digits are all ones.

10:40.850 --> 10:45.920
So the result of the bitwise or of these two numbers is this number.

10:46.220 --> 10:52.010
So now that we know about the bitwise or the thing we need to talk about next is the shift left.

10:52.040 --> 10:53.050
Operator.

10:53.060 --> 10:59.390
Now, when used like this with an integer to the left and an integer to the right, we need to think

10:59.390 --> 11:01.850
about the result in terms of bits.

11:01.880 --> 11:06.710
Now, in most modern compilers, integers are 32 bits.

11:07.810 --> 11:13.600
But we're going to treat these like they're eight bit integers, just for simplicity's sake, for now.

11:13.780 --> 11:18.760
So the left hand side of the left shift operator is one.

11:18.940 --> 11:23.290
If it were an unsigned eight bit integer, it would be this value.

11:23.320 --> 11:32.500
Now what this expression one left shift zero means is to shift all the digits to the left by zero.

11:32.650 --> 11:34.680
In other words, don't shift them at all.

11:34.690 --> 11:35.980
So that's pretty easy.

11:36.010 --> 11:37.600
Let's take another example.

11:37.600 --> 11:40.180
One left shift one.

11:40.390 --> 11:46.540
Now, again, assuming that these integers are eight bit, we would take the left side of the shift

11:46.540 --> 11:51.250
left operator, which is this number and we shift left by one.

11:51.280 --> 11:55.810
Now that means we shift all the digits to the left by one.

11:55.810 --> 12:00.550
And so this one here is going to end up one digit over.

12:00.550 --> 12:04.480
And any digits coming in from the right hand side will be zero.

12:04.480 --> 12:11.390
So the one at the very end will be replaced by a zero and the digit next to it will now be a one.

12:11.420 --> 12:14.690
Now, what about this digit all the way over here to the left?

12:14.720 --> 12:16.070
It's getting pushed out.

12:16.100 --> 12:17.660
We completely lose that.

12:17.660 --> 12:20.420
So if it was a one, it would be gone.

12:20.420 --> 12:25.040
And whatever was to the right of that endmost digit is now going to replace it.

12:25.220 --> 12:33.530
So one left shift, one is going to result in this value all zeros, but that one has shifted over.

12:33.980 --> 12:38.330
Now, all those other zeros to the left of the one have shifted over as well.

12:38.570 --> 12:42.500
So if they were ones instead, those would also be shifted over.

12:42.500 --> 12:43.910
So keep that in mind.

12:44.120 --> 12:45.950
Let's do another simple example.

12:45.950 --> 12:47.570
One left shift two.

12:47.600 --> 12:49.010
Here's one.

12:49.220 --> 12:53.600
And we need to shift all the digits to the left by two.

12:53.600 --> 12:58.790
So the one all the way there at the right is going to shift over once and twice.

12:58.790 --> 13:04.490
And those two zeros all the way at the end are going to be pushed out and they'll be lost.

13:04.490 --> 13:07.700
So the result of this is this value here.

13:07.820 --> 13:09.980
That is how left shift works.

13:10.660 --> 13:14.800
And just to drive the point home, let's try one left shift three.

13:14.830 --> 13:15.970
Here's one.

13:15.970 --> 13:23.470
And we have to shift to the left by three, which means the one will travel 1 to 3 digits over these

13:23.470 --> 13:28.240
three digits at the end will be lost and the result will be this number.

13:28.690 --> 13:32.320
Now rep bits is a UNT eight, but it doesn't have to be.

13:32.320 --> 13:36.790
Let's say for example sake that we create one in our net serialize.

13:36.820 --> 13:38.500
That's a UN 32.

13:39.120 --> 13:41.430
That would be 32 bits.

13:41.820 --> 13:44.710
And if we initialize it to zero, it would be all zeros.

13:44.730 --> 13:46.440
Here's what the bits would look like.

13:47.200 --> 13:55.090
Now if we take rep bits and we use say this operation on it, rep bits bitwise or equals one left shift

13:55.090 --> 14:00.630
zero, that would be equivalent to taking rep bits and setting it equal to itself.

14:00.640 --> 14:04.540
Bitwise or the expression one left shift zero.

14:04.570 --> 14:07.070
Let's see what result we would get from this.

14:07.090 --> 14:09.550
Here is one left shift zero.

14:09.550 --> 14:17.410
As we've seen, one left shift zero is going to take the value one and shift all the digits to the left

14:17.410 --> 14:18.270
by zero.

14:18.280 --> 14:19.690
In other words, it's just one.

14:19.690 --> 14:26.620
So since we know one left shift zero, we can take rep bits which starts off at zero, do a bitwise

14:26.650 --> 14:32.830
or with one left shift zero, which we know is one and the result is going to be rep bits.

14:32.830 --> 14:39.430
Here's all the zeros bitwise or and here's one left shift zero, which is just one.

14:39.460 --> 14:43.180
What do we get when we take the bitwise or of these two numbers?

14:43.330 --> 14:51.950
Well, we get one as all the digits are zero except for that one at the very right and the bitwise or

14:51.950 --> 14:53.750
between 0 and 1 gives us one.

14:53.750 --> 14:55.250
So the result is one.

14:55.430 --> 14:56.960
Okay, simple example.

14:56.960 --> 15:00.050
But the thing is, rep bits has changed.

15:00.080 --> 15:04.700
It started off with all zeros and now it has a one right there at the end.

15:05.270 --> 15:12.410
So this expression that we've done this rep bits bitwise or equals one left shift zero has changed rep

15:12.410 --> 15:18.380
bits in a way, and we refer to that change as flipping that bit at the end there.

15:18.500 --> 15:24.860
Now if we count bits from right to left and the very first digit there, we consider to be the zeroth

15:24.860 --> 15:28.700
digit, then we say we flipped the zeroth bit.

15:30.420 --> 15:36.240
Now after we've flipped the zeroth bit on rep bits, we know that its value is now equal to this.

15:36.240 --> 15:39.150
All zeros with a one at the end.

15:39.660 --> 15:46.450
Now let's say we take rep bits and do this again only we use one left shift one this time.

15:46.470 --> 15:47.940
How does this work?

15:48.150 --> 15:52.550
Well, we know that one left shift one is this value.

15:52.560 --> 15:54.270
It's the value one.

15:54.270 --> 15:58.080
But all the digits have been shifted to the left by one digit.

15:58.080 --> 16:00.480
So it's now no longer just one.

16:00.480 --> 16:01.980
It's this number.

16:02.710 --> 16:09.070
So if we were to take rep bits and do the bitwise or with one left shift one, we would have rep bits,

16:09.070 --> 16:10.360
which is one.

16:11.090 --> 16:15.170
Or and then one left shift, one which is this value.

16:15.200 --> 16:18.920
Now, what's the result of the bitwise or between these two?

16:18.920 --> 16:20.960
Well, it would be this.

16:20.990 --> 16:27.770
All the digits are zero, except one of the numbers has a one at the end and the other has a one.

16:27.770 --> 16:28.100
Right.

16:28.100 --> 16:30.220
They're one away from the end.

16:30.230 --> 16:34.340
So the result is a bunch of zeros with two ones at the end.

16:34.760 --> 16:41.270
In other words, we've flipped the first bit if we're counting from right to left starting at zero.

16:41.300 --> 16:47.510
So one left shift, one is going to flip the first bit and notice that we kept the bit all the way at

16:47.510 --> 16:48.460
the end there.

16:48.680 --> 16:51.620
Rep bits started off with that bit set to one.

16:51.620 --> 16:57.170
All the others were zero, but this line has now flipped that second bit, so they're both one.

16:57.530 --> 17:04.070
Now let's say that we take our 32 bit and rep bits and we've already flipped the two end most bits on

17:04.070 --> 17:04.610
it.

17:04.610 --> 17:12.090
And let's say that we take rep bits and we do this operation on it, rep bits, bitwise or equals one

17:12.090 --> 17:15.000
left shift two What does this do?

17:15.090 --> 17:17.070
Well, what is one left shift?

17:17.070 --> 17:22.860
Two it's this number, it's the number one with the one digit shifted over by two.

17:22.890 --> 17:25.470
So it's right there, two away from the end.

17:25.470 --> 17:32.250
And if we want to calculate rep bits or one left shift two, then we would take rep bits which is now

17:32.250 --> 17:34.680
this number or.

17:35.280 --> 17:38.820
And then we would take one left shift to which is this number.

17:38.910 --> 17:42.060
Now, what's the result of the bitwise or.

17:42.180 --> 17:43.500
Well, here it is.

17:43.530 --> 17:48.420
We took rep bits which had two ones at the end and we flipped the second bit.

17:48.450 --> 17:50.500
Now it has three ones at the end.

17:50.520 --> 17:52.470
So we're starting to see a pattern here.

17:52.740 --> 17:57.390
Now let's go back into the code and find out just what this means for us.

17:57.420 --> 18:00.840
We're only doing this if the archive is in saving mode.

18:00.870 --> 18:04.920
So look at what each of these if statements is checking first.

18:04.950 --> 18:10.020
We saw that it's checking if the instigator is valid and if we should replicate the instigator.

18:10.020 --> 18:12.210
If B replicate instigator is true.

18:12.240 --> 18:19.440
If those are both true, then we flip that zeroth bit and rep bits has all zeros, but it now has actually

18:19.440 --> 18:22.200
a one at the rightmost digit.

18:22.350 --> 18:27.150
This is a very compact way of storing a bunch of boolean values.

18:27.150 --> 18:33.990
Basically we're designating the instigator to be represented by the rightmost digit in this rep bits

18:33.990 --> 18:34.990
bit array.

18:35.200 --> 18:40.390
The effect causer just happens to be represented by the next one because we're checking to see if it's

18:40.390 --> 18:42.040
valid and if we should replicate it.

18:42.040 --> 18:45.130
And if so, we flip that next bit.

18:45.160 --> 18:49.420
On rep bits we then check the ability variable.

18:49.420 --> 18:51.670
If that's valid, we flip the next bit.

18:51.760 --> 18:59.890
So assuming these are all valid then rep bits is changing by having its zeros replaced by ones in each

18:59.890 --> 19:02.410
subsequent bit going from right to left.

19:02.410 --> 19:09.850
And if one of these fails, say source object is not valid, for example, then we will not flip that

19:09.850 --> 19:12.170
bit and then we'll continue.

19:12.190 --> 19:18.490
If actor's num is not greater than zero, we don't flip that fourth bit, right?

19:18.490 --> 19:24.550
So by the end of this, this eight bit integer has zeros and ones that represent whether or not we should

19:24.550 --> 19:29.470
replicate or whether or not we should serialize these variables.

19:29.500 --> 19:33.400
Now after that are calls serialized bits.

19:33.860 --> 19:42.350
And it takes rep bits passes that in it actually passes it in by address this is the address of operator

19:42.350 --> 19:45.590
and then it receives the length in bits.

19:45.620 --> 19:46.990
Now let's count these.

19:47.000 --> 19:55.880
We have one, two, three, four, five, six, seven times that we've flipped bits.

19:56.210 --> 20:01.490
So serialized bits wants to know if we've used all those bits or not.

20:01.520 --> 20:02.120
We didn't.

20:02.150 --> 20:03.980
We only flipped seven of them.

20:03.980 --> 20:05.930
That last bit wasn't used.

20:05.960 --> 20:12.800
So we're telling serialized bits we only care about the first seven and serialized bits is going to

20:12.800 --> 20:21.200
do some really cryptic looking serialization by taking those seven bits, however many we pass in here

20:21.200 --> 20:24.010
and serializing those into the archive.

20:24.020 --> 20:28.220
So it's going to know it's going to remember in the archive.

20:28.250 --> 20:36.210
The archive is just a string of bits and it's going to remember that these seven bits are representative

20:36.210 --> 20:40.320
of whether or not we should serialize these variables.

20:40.470 --> 20:42.600
Now after that, look at this.

20:42.630 --> 20:43.920
We're checking rep bits.

20:43.950 --> 20:48.810
Now we're doing something else with rep bits that looks probably equally confusing.

20:48.840 --> 20:56.640
Now keep in mind this first set of bit flipping steps here is done inside the if check if R is saving.

20:56.640 --> 21:00.050
But after that this stuff is in no such if check.

21:00.060 --> 21:02.730
So all of this only happens if saving.

21:02.730 --> 21:06.090
But all of this happens regardless of saving or not.

21:06.090 --> 21:08.760
And remember, this operator works both ways.

21:08.760 --> 21:14.460
If we're saving, we're going from right to left and we're serializing what's on the right into the

21:14.460 --> 21:15.260
archive.

21:15.270 --> 21:18.930
But if we're not saving, then it goes from left to right.

21:18.940 --> 21:26.130
Whatever is serialized becomes serialized and stuck right into the variable on the right.

21:26.370 --> 21:30.990
Now the question is what are these conditionals doing right?

21:31.020 --> 21:33.660
This might make you sort of scratch your head a bit.

21:33.660 --> 21:35.430
So let's talk about this part.

21:35.460 --> 21:46.050
Now we have rep bits and then this is the bitwise and similar to the bitwise or only it's the and version.

21:46.050 --> 21:49.330
And then we have some left shifting going on.

21:49.350 --> 21:54.410
This first one is rep bits, bitwise and one left shift zero.

21:54.420 --> 21:56.250
So let's analyze this one.

21:56.730 --> 22:00.150
So in these if statements we have rep bits.

22:00.270 --> 22:03.090
Now, in this example, let's just say it's a UN 32.

22:03.120 --> 22:06.000
We know it's a UN eight, but it doesn't really matter.

22:06.030 --> 22:10.550
Continuing with our example though, let's say that rep bits is this number right?

22:10.560 --> 22:13.200
We've already flipped the first three bits.

22:13.860 --> 22:20.880
Now in our if statement, we're checking if rep bits bitwise and one left shift zero.

22:21.210 --> 22:23.930
So let's look at this one piece at a time.

22:23.940 --> 22:25.260
One left shift zero.

22:25.290 --> 22:27.240
We know that that's this number.

22:27.540 --> 22:28.560
So what is this?

22:28.560 --> 22:29.570
Rep bits.

22:29.970 --> 22:32.950
Bitwise and one left shift zero.

22:32.970 --> 22:35.070
Well, rep bits is this number.

22:35.100 --> 22:39.330
Bitwise And this number, which is one left shift zero.

22:39.360 --> 22:40.440
What does this produce?

22:40.440 --> 22:41.880
Well, with a bitwise.

22:41.880 --> 22:49.020
And it's just like a bitwise or it's happened bitwise bit by bit comparing one digit on one variable

22:49.020 --> 22:50.760
with one digit on the other.

22:50.760 --> 22:53.650
And if they're both zero, the result is a zero.

22:53.670 --> 22:57.360
If only one of them is a zero, the result is a zero.

22:57.360 --> 22:58.680
Just like an and.

22:58.710 --> 23:00.780
True and false returns.

23:00.780 --> 23:01.530
False.

23:01.560 --> 23:06.630
The only way we'd get a one is if both digits are ones.

23:06.660 --> 23:09.240
That's only that rightmost digit there.

23:09.360 --> 23:14.020
So rep bits and one left shift zero is this value.

23:14.030 --> 23:17.800
So now this is all inside of an if statement, isn't it?

23:17.830 --> 23:19.520
Let's take a look at this again.

23:19.540 --> 23:20.580
Here it is.

23:20.590 --> 23:26.650
So we know that in our hypothetical situation, if this all evaluated to a bunch of zeros with a one

23:26.650 --> 23:31.450
at the end, well, that's just a one and it's a non-zero value.

23:31.450 --> 23:39.740
And if statements consider any non-zero value to be true, it considers only zero values to be false.

23:39.760 --> 23:44.440
So in our hypothetical situation, we would make it inside this if statement.

23:44.470 --> 23:46.660
Now, what's the significance of that?

23:46.690 --> 23:54.040
The significance is that the result of this operation gives us true because that first digit, which

23:54.040 --> 23:57.040
we called the zeroth digit, is one.

23:57.220 --> 24:05.680
We interpret that as the first variable represented by that digit has been serialized or should be serialized.

24:05.710 --> 24:10.660
Both are the case In the case where we're saving it should be serialized.

24:10.660 --> 24:15.850
We're going right to left in the case where we're loading, it has been serialized and needs to go from

24:15.850 --> 24:17.290
left to right.

24:17.770 --> 24:25.810
So basically, if we're checking rep bits versus one left shift zero with a bitwise and we know that

24:25.810 --> 24:33.220
one left shift zero is all zeros, but a one on the zeroth digit, the rightmost digit if rep bits has

24:33.220 --> 24:35.740
a one there, we'll make it inside this.

24:35.770 --> 24:38.650
If rep bits has a zero there we will not.

24:38.680 --> 24:44.380
In other words, if we flipped that bit up here because we know that the instigator should be replicated,

24:44.590 --> 24:47.080
then we'll make it inside here.

24:47.080 --> 24:53.830
If we never flipped that bit because instigator was not valid, for example, then we don't need to

24:53.830 --> 24:58.330
get inside here and archive the instigator or unarchive.

24:58.330 --> 25:00.250
It makes sense.

25:00.400 --> 25:02.140
And the same goes for the rest of these.

25:02.140 --> 25:09.790
We're checking rep bits against one left shift one that's all zeros except a one just next to the end

25:09.790 --> 25:10.330
digit.

25:10.330 --> 25:12.550
There's a zero at the end and a one next to it.

25:12.550 --> 25:13.000
Right.

25:13.000 --> 25:18.550
If rep bits has a one there, that means we flipped it up here and we did that because we wanted to

25:18.550 --> 25:23.290
replicate effect calls or we wanted to serialize it because it was valid.

25:23.290 --> 25:23.910
Right?

25:23.920 --> 25:26.980
If it was valid, that bit will be a one.

25:26.980 --> 25:31.810
We'll make it inside here and we'll get to serialize or unserialize.

25:32.050 --> 25:40.210
So you catch the drift and the archive overloads the left shift operator for lots of types, but not

25:40.210 --> 25:41.090
all of them.

25:41.110 --> 25:44.470
Notice that for the array here, we can't just use the array.

25:44.470 --> 25:48.010
With the left shift, we have to use other means.

25:48.010 --> 25:53.740
There's this function SafeNet serialize array, which will serialize the array.

25:54.070 --> 25:58.990
We also see that the hit result had to be handled a little differently In the case that the archive

25:58.990 --> 26:02.590
is loading, there's a check here to see if the hit result is not valid.

26:02.590 --> 26:09.820
If it's not, then a new hit result shared pointer is created and stored in the hit result shared pointer

26:09.820 --> 26:16.180
member variable and then the hit result itself has a net serialized function designed to serialize hit

26:16.180 --> 26:16.930
results.

26:16.930 --> 26:19.240
So that's how you serialize hit results.

26:19.270 --> 26:26.410
SafeNet Serialize array underscore default is a way to serialize arrays.

26:26.680 --> 26:32.680
So as you can see, there are a couple of exceptions to this left shift business.

26:32.680 --> 26:39.430
And way down here at the bottom, notice there's a check to see if the archive is loading and if so,

26:39.430 --> 26:40.690
we call add instigator.

26:40.690 --> 26:45.670
Well, we know what this does and the comment is telling us why it says just to initialize instigator

26:45.670 --> 26:51.130
ability system component, because we know that that gets set along with the instigator and the effect

26:51.130 --> 26:52.030
causer as well.

26:52.030 --> 26:59.620
So this function does the courtesy of calling add instigator and then it just sets be out success equal

26:59.620 --> 27:02.620
to true and it returns true.

27:02.980 --> 27:08.260
So all of that is just net serialize for the gameplay effect context.

27:08.260 --> 27:09.430
Pretty crazy, right?

27:09.430 --> 27:13.510
And we need to do this in our custom effect context.

27:13.550 --> 27:13.800
Next.

27:14.120 --> 27:21.440
And not only do we need to take care of all these, but we also want to handle serializing our new to

27:21.440 --> 27:22.640
Boolean variables.

27:22.640 --> 27:27.680
And we're going to do it just like it's done here in net serialize.

27:27.860 --> 27:29.180
So what do you think?

27:29.210 --> 27:30.800
Are you up to a challenge?

27:30.800 --> 27:35.010
Would you like to do this on your own or would you like to follow along with me?

27:35.030 --> 27:40.910
You're going to get that choice in the next video, and I'll see you soon.
