Presentation is loading. Please wait.

Presentation is loading. Please wait.

Sega 500 More replication Jeff “Ezeikeil” Giles

Similar presentations


Presentation on theme: "Sega 500 More replication Jeff “Ezeikeil” Giles"— Presentation transcript:

1 Sega 500 More replication Jeff “Ezeikeil” Giles jgiles@artschool.com http://gamestudies.cdis.org/~jgiles

2 More Replication Yes…that’s the plan for today. Replication in UT is so important that it really is worth taking another class to look at another example.

3 Rolling back the clock I figure I’d have some fun with this lesson and reuse some code that you are already familiar with. We are going to create the network functionality for the King of the Hill Gametype we made in lesson 9.

4 As you recall… The rules were fairly straight forward. When a player was killed for the first time, a special damage doubler would be spawned. This doubler would be carried by the player until he was killed. At which time it get dropped for the next player to pickup.

5 As you recall… Only the player with the special doubler was able to score and there could only ever be one in play.

6 And as you no doubt recall… When we did the network test, it fail miserably. The reason was that the client and server for the EzeUdam would go out of sync… in effect, being in 2 different locations, with only the one on the server being valid. However, it worked fine in single player.

7 Now at this point… It would be a good idea to refer back to lesson 9 and look at the code intend to modify. It boils down to three classes: Gametype EzeUdam Message class

8 Gametype Was essentially our rule of play with most of the work happening in the Killed function. The Killed function did the spawning of the EzeUDam and broadcasting of messages to the player.

9 EzeGameMSG Was simply the localized message class which is used for two reasons. 1. Formatting and placement of messages of that class is super easy. 2. Network optimization. As opposed to sending a string, it sends an index into this class… much more efficient.

10 EzeUDam Essentially the pickup which enabled the player Pawns UDamage parameter. The only real difference between ours an the UDamagePack was that ours broadcasted messages as well

11 EzeUDam And spawned navigation information so that the bots would take after it… Other than that, no real significant differences.

12 Making replication Now, working with these classes, things replicate differently then they did with the KRock. And this cause me much grief. I spend a couple of hours just trying to figure out why the client wouldn’t replicate properly.

13 It came down to the Gametype Now as I said yesterday, and I’ll say it again…Clients don’t have gametypes. And Because it was in the Gametype that I was updating and tracking changes. This really caused me some puzzlement in trying to figure out how to track who had the EzeUdam, not to mention it’s location.

14 But as it turns out… Once I got my head around it, it wasn’t that big of a deal. I just had to remember that the clients don’t need the game info class because the server is the authority on what goes on in that level…It’s word is law.

15 Thus… The client never makes any decisions for itself. The server makes all the decisions and then tells the clients. Hence, most of the replication conditions are based on whether or not I am the server. If I am, replicate the condition. If not…skip it.

16 Getting started In the Gametype, there are 2 variables that the clients have to be aware of These are who has the EzeUDam and the EzeUdam itself. var pawn HasUDam; var EzeUDam dam;

17 The Gametype The server will use these to track who has the Udamage and if it can be pickup (not out of play). Hence our replication statement : reliable if(role==ROLE_AUTHORITY) HasUDam, dam, snd;

18 The Gametype If I am the server, these variables are reliable and I can safely send them to the client. reliable if(role==ROLE_AUTHORITY) HasUDam, dam, snd;

19 The Gametype Which brings us down to the Killed function. Now there is not a lot of anything new in this class…mostly some gameplay tweaks which we will come back to. Right now, we only care about the replication…Which in this case, is related to how the EzeUDam is flung into the air.

20 The Gametype Which occurs here: if(HasUDam == none && dam == none) { dam=spawn(class'EzeUDam',,,KilledPawn.location); //toss the UDamage in to the air dam.Toss(); snd=none; } Does the flinging

21 The Gametype Now this is a very important difference to make note of. In the previouve version of the code, we just applied the velocity to the EzeUDam here. We can no longer do that. We have to go into the EzeUdam itself and call the Toss function.

22 Why? Well, it comes down to a matter of replication and we need to access a simulated function to ensure that it get run on the right machine. Now, the Toss function itself is not simulated, but the one it calls, is.

23 EzeUDam function Toss() { bOnlyReplicateHidden = false; //if I am the server, tell the clients the velocity if(Role==ROLE_Authority) { ClientToss(); return; } If I am the server call the Clienttoss. Otherwise, do nothing

24 EzeUDam And the ClientToss function is was does the actual flinging. simulated function ClientToss() { Velocity= 500*VRand(); Velocity.Z= RandRange(500,800); SetPhysics(PHYS_Falling); }

25 EzeUDam Notice that the ClientToss is simulated where the Plan-Jane Toss is not. By making the actual fling method simulated, it get replicated over the wire. I was not able to get this to run by simply calling the ClientToss from the Gametype.

26 EzeUDam Which brings us to EzeUdam’s replication statement. Not much, If I am the server, trust in the client toss function for replication. reliable if(role==ROLE_AUTHORITY) ClientToss;

27 EzeUDam And before we go any further with this class, we should have a look at the Defaults. bStatic=false bNoDelete=false bHidden=false No to surprising

28 EzeUDam if true, only replicate actor if bNetDirty is true - useful if no C++ changed attributes (such as physics) bOnlyDirtyReplication only used with bAlwaysRelevant actors. bOnlyDirtyReplication=false bAlwaysRelevant = true bReplicateMovement=true NetUpdateFrequency=100.000000 NetPriority=2.000000 bNetInitialRotation=True

29 EzeUDam Still not any newness: But do notice that I’m using DumbProxy. If I were using some other replication property, the server would try to replicate its rotation as well…Very ugly. RemoteRole=ROLE_DumbProxy bUpdateSimulatedPosition=True

30 EzeUDam And finally, we also update the gametype…if we are the server….from inside the touch function: if(Role== ROLE_Authority) { EzeGame(level.Game).HasUDam=P; EzeGame(level.Game).PlayClientSeekSound(); }

31 EzeUDam Update the player who has the EzeUdam with whoever just picked it up. if(Role== ROLE_Authority) { EzeGame(level.Game).HasUDam=P; EzeGame(level.Game).PlayClientSeekSound(); }

32 EzeUDam And have the server make some noise. if(Role== ROLE_Authority) { EzeGame(level.Game).HasUDam=P; EzeGame(level.Game).PlayClientSeekSound(); }

33 Gametype Now, for the PlayClientSeekSound function I’m reaching into my bag of tricj on this one… What I plan to do is play a sound on the client side only…excluding the player who has the EzeUdam.

34 Gametype And because of where we are calling this from, we know that we are the server… Hence, we have the gametype… Hence, we have access to all the players in the game… Hence, we can manipulate any one (or all) of them. Remember, the server makes the rules.

35 Gametype So how am I going to pull this off you ask? Well, being the server, we have the gametype, which has a list of all the controllers in play… Just going to iterated over all those…

36 Gametype simulated function PlayClientSeekSound() { local controller c; snd=sound'XEffects.LightningSound'; For ( C=Level.ControllerList; C!=None; C=C.NextController ) { if(c.IsA('Playercontroller') && c.Pawn != HasUDam) Playercontroller(c).ClientPlaySound(snd); }

37 ClientPlaySound Which allows me to introduce a very interesting function. ClientPlaySound. The function will only play sound on the client side…no other players will be able to hear it.

38 ClientPlaySound Which, in of itself, is really cool…not to mention handy. But even better, go over to playercontroller and look at how its implemented… Not how you might expect.

39 ClientPlaySound simulated function ClientPlaySound(sound ASound, optional bool bVolumeControl, optional float inAtten, optional ESoundSlot slot ) { local float atten; atten = 0.9; if( bVolumeControl ) atten = FClamp(inAtten,0,1); if ( ViewTarget != None ) ViewTarget.PlaySound(ASound, slot, atten,,,,false); }

40 ClientPlaySound Now, most of this dosen’t rate to highly on the “YIPPEE” scale of things…except for the last line… Where it’s using the viewport to play the sound.

41 ClientPlaySound ViewTarget? What the heck is that? We are using the clients machine to play a “none specific” sound to the client player. More exactly, we are playing the sound through the clients player, kind of like the announcers voice.

42 ClientPlaySound What this results in is a sound that only plays for that players who do not have the EzeUdam, giving a heads up that its been picked up. As for the sound, well I found a really pleasing thunder clap effect.

43 Another effect… And just to furthur make the player stand out, back in the ouch function of the EzeUdam class I added. This is the derez effect material seen when you die…what it does for us: p.OverlayMaterial=FinalBlend'DeRez.DeRezFinalBody';

44 Another effect… A green techno ghost

45 And this should Leave use some time today for poking at it and playing with the code… Replication is a rather opaque thing, and the only way to get good at it, is to practice.

46 A wrap… I hope today’s lesson helps to clear up the relation between client and server in UT and further illustrates how they talk to each other.


Download ppt "Sega 500 More replication Jeff “Ezeikeil” Giles"

Similar presentations


Ads by Google