Presentation is loading. Please wait.

Presentation is loading. Please wait.

Sega 500 An Introduction to Replication Jeff “Ezeikeil” Giles

Similar presentations


Presentation on theme: "Sega 500 An Introduction to Replication Jeff “Ezeikeil” Giles"— Presentation transcript:

1 Sega 500 An Introduction to Replication Jeff “Ezeikeil” Giles jgiles@artschool.com http://gamestudies.cdis.org/~jgiles

2 Today Is about one of the core elements that make UT2003 what it is. The multiplayer experience. In another word, Replication.

3 Replication, so what is it? In a nutshell, Replication in UT is about how information gets sent across the wire. As well as to whom and who from. It’s how UT shares reality with all the players connected to that game.

4 Replication A dictionary definition: rep·li·cate To duplicate, copy, reproduce, or repeat. Biology To reproduce or make an exact copy or copies of (genetic material, a cell, or an organism).

5 And there you have A very simple introduction to object replication between client and server.

6 UT’s Defintion Unreal views the general problem of "coordinating a reasonable approximation of a shared reality between the server and clients" as a problem of "replication". That is, a problem of determining a set of data and commands that flow between the client and server in order to achieve that approximate shared reality.

7 An important fact… about UT, it is a client server architecture which allow players to join a game which is currently in progress. Meaning one server, and zero or more client machines.

8 Why is this important? The Server Is The Man. the server is authoritative about the gameplay flow, the server's game state can always be regarded as the one true game state.

9 One true game The version of the game state on client machines should always be regarded as an approximation subject to many different kinds of deviations from the server's game state.

10 The players Actors that exist on the client machine should be considered proxies because they are a temporary, approximate representation of an object rather than the object itself.

11 Three Types of Replication The network code is based on three primitive, low-level replication operations for communicating information about the game state between the the server and clients.

12 Actor replication The server identifies the set of "relevant" actors for each client (actors which are either visible to the client or are likely to somehow affect the client's view or movement instantaneously), and tells the client to create and maintain a "replicated" copy of that actor. While the server always has the authoritative version of that actor, at any time many clients might have approximate, replicated versions of that actor.

13 Variable replication Actor variables that describe aspects of the game state which are important to clients can be "replicated". That is, whenever the value of the variable changes on the server side, the server sends the client the updated value.

14 Function call replication A function that is called on the server in a network game can be routed to the remote client rather than executed locally. Alternatively, a function called on the client side may be routed to the server, rather than called locally.

15 For example You can hear other players gunshots because the server is replicating the ClientHearSound function to you. The ClientHearSound function is called for a PlayerPawn whenever that PlayerPawn hears a sound.

16 The replication statement In UnrealScript, every class can have one replication statement. The replication statement contains one or more replication definitions. Each replication definition consist of a replication condition (a statement that evaluates to True or False), and a list of one or more functions and variables to which the condition applies.

17 The replication statement may only refer to variables defined in that class, and functions defined first in that class (that is, it cannot apply to functions defined in a superclass but overridden in that class.

18 The replication statement Therefore, if the Actor class contains a variable DrawType, then you know where to look for its replication condition: it can only reside there in the Actor class.

19 The replication statement Essentially determines what gets sent across the wire, or what functions and values a relevant depending on the role of that class in a network game. Each replication statement reads like a function, but definitions begins with "reliable if (condition)" or "unreliable if (condition)"

20 An example. From Xpawn replication { // client to server reliable if ( Role < ROLE_Authority ) ServerDoCombo, ServerRequestRules, AdminMenu, ServerRequestPlayerInfo, ServerSpecViewGoal; unreliable if( Role < ROLE_Authority ) L33tPhrase; reliable if ( Role == ROLE_Authority) ClientReceiveRule, ClientReceiveCombo; }

21 So what’s going on? Unreliable: Functions replicated with the "unreliable" keyword are not guaranteed to reach the other party and, if they do reach the other party, they may be received out-of-order. The only things which can prevent an unreliable function from being received are network packet-loss, and bandwidth saturation.

22 So what’s going on? Reliable: The replicated function will get through in the proper order. Variables are always reliable Variables are always guaranteed to reach the other party eventually, even under packet- loss and bandwidth saturation condition.

23 A note on Packet loss In a LAN game, we guesstimate that unreliable data is received successfully approximately 99% of the time. However, in the course of a game, hundreds of thousands of things are replicated, so you can be sure that some unreliable data will be lost.

24 A note on Packet loss In a typical low quality 28.8K ISP connection, unreliable data is generally received 90%-95% of the time. In other words, it is very frequently lost.

25 And what’s “ROLE_Authority”? ROLE_Authority is part of the ENetRole enum defined in actor. enum ENetRole { ROLE_None, // Means the actor is not relevant in network play. ROLE_DumbProxy, // A dumb proxy. ROLE_SimulatedProxy, // A simulated proxy. ROLE_AutonomousProxy, // An autonomous proxy. ROLE_Authority, // The one authoritative version of the actor. };

26 What’s “ROLE_Authority”? And it’s intended for use with two variables, Role and RemoteRole. These variables describe how much control the local and remote machines, respectively, have over the actor:

27 Role==ROLE_DumbProxy The actor is a temporary, approximate proxy which should not simulate any physics at all. On the client, dumb proxies just sit around and are only moved or updated when the server replicates a new location, rotation, or animation information. This situation is only seen in network clients, never for network servers or single-player games.

28 Role==ROLE_SimulatedProxy The actor is a temporary, approximate proxy which should simulate physics and animation. On the client, simulated proxies carry out their basic physics (linear or gravitationally-influenced movement and collision), but they don't make any high-level movement decisions. They just go. This situation is only seen in network clients, never for network servers or single-player games.

29 Role==ROLE_AutonomousProxy The actor is the local player. Autonomous proxies have special logic built in for client-side prediction (rather than simulation) of movement. This situation is only seen in network clients, never for network servers or single-player games.

30 Role==ROLE_Authority This machine has absolute, authoritative control over the actor. This is the case for all actors in single-player games. This is the case for all actors on a server. On a client, this is the case for actors that were locally spawned by the client, such as gratuitous special effects which are done client-side in order to reduce bandwidth usage.

31 On roles Actor’s play On the server side, all actors have Role==ROLE_Authority, and RemoteRole set to one of the proxy types. On the client side, the Role and RemoteRole are always the exactly reversed relative to the server's value.

32 Core replication variables To get your actors to replicate properly there is a rather long list of special replication variables to know about. Here, I’m only gone to address the most important of them:

33 NetPriority Each actor has a floating point variable called NetPriority. The higher the number, the more bandwidth that actor receives relative to others. An actor with a priority of 2.0 will be updated exactly twice as frequently as an actor with priority 1.0. The only thing that matters with priorities is their ratio.

34 NetPriority Since 3.0 is the highest on the list, there is no real difference between giving your actor a NetPriority of 4.0 and 4000.0, since they will both be placed at the top of the list.

35 bNetInitial true if this is the first time this actor is being replicated across the network. Useful for variables that differ from the defaultproperties, yet will not change over the life of the actor.

36 Some others… bNetOwner True if the player we are replicating to owns this actor directly. bAlwaysRelevant Always keep the actor relevant to network play.

37 Determining relevance An Unreal level can be huge, and at any time a player can only see a small fraction of the actors in that level. Most of the other actors in the level aren't visible, aren't audible, and have no significant effect on the player.

38 Determining relevance The set of actors that a server deems are visible to or capable of affecting a client are deemed the relevant set of actors for that client. This is a significant bandwidth optimization in Unreal's network code is that the server only tells clients about actors in that client's relevant set.

39 Determining relevance The basic rules are: 1) The actor belongs to the ZoneInfo class, then it is relevant. 2) If the actor has static=true or bNoDelete=true, then it is relevant. 3) If the actor is owned by the player (Owner==Player), then it is relevant. 4) If the actor is a Weapon and is owned by a visible actor, then it is relevant.

40 Determining relevance 5) If the actor is hidden (bHidden=true) and it doesn't collide (bBlockPlayers=false) and it doesn't have an ambient sound (AmbientSound==None) then the actor is not relevant. 6) If the actor is visible according to a line-of-sight check between the actor's Location and the player's Location, then it is relevant. 7) If the actor was visible less than 2 to 10 seconds ago (the exact number varies because of some performance optimizations), then it is relevant.

41 Simulated functions Declares that a function may execute on the client-side when an actor is either a simulated proxy or an autonomous proxy. All functions that are both native and final are automatically simulated as well.

42 For more reading And a whole lot more specific information, read these: http://unreal.epicgames.com/Network.htm http://www.planetunreal.com/pipeline/tutorials/replication.html

43 And now for our example… For today, I wanted to do something rather simple, and that was allow the players to throw some rocks at each other. But not just any rocks, Karma rocks that replicate their positions over the network.

44 Krock And keeping with the cheesy art skills, I used the editor to create a simple static mesh for the KRocks. Complete with Karma primitives…

45 The plan Is to have the player spawn one of these whenever they fire their weapon. Then they can shoot them around some and play a bit of “gun hockey” with them. But too keep the network bandwidth reasonable, I’ve also created a cap on the number that players can spawn.

46 The plan I’ve also created a few debug methods so that was can see what going on, either on the HUD or in the log.

47 Getting started… For convenience, I created a gametype for testing the replication as the easies way to intercept the fire command from the player is through the controller, but we’ll talk about that in a second.

48 The Gametype There is really nothing new going on here, just some defaults so that we can use the new controller and HUD. class ERepGame extends xDeathMatch; DefaultProperties { HUDType="Ezerep.EHUD" CountDown=0 PlayerControllerClassName="EzeRep.Epc" }

49 The Gametype Now, keep in mind that only the server has a gametype object. The clients do not. Thus any attempt to access information in the gametype via Level.game will access none.

50 The Gametype Which brings me to the one function in the gametype. This function was intended to spit out information to the HUD or log based on the role of the player. However, due to the a for mention of the gamtypes existence, this function will not *properly*. simulated function LogRole()

51 The Gametype However, the logic is sound. Therefore, left in for reference purposes, just don’t try to access it from the client. This function will work fine if it’s copied into other classes.

52 The Gametype That being said… simulated function LogRole() { if(role==ROLE_Authority) { log("--->We are Server"); BroadcastLocalizedMessage(class'RepMsg', 0); } if(Role<ROLE_Authority) { log("--->We are Client"); BroadcastLocalizedMessage(class'RepMsg', 1); }

53 The Gametype This is a very simple debug method which, based on our role, determines what function to execute. if(role==ROLE_Authority) { log("--->We are Server"); BroadcastLocalizedMessage(class'RepMsg', 0); } If we are the server, do this

54 The Gametype All we do is splash some info to the log or screen, based on the role we play. if(Role<ROLE_Authority) { log("--->We are Client"); BroadcastLocalizedMessage(class'RepMsg', 1); } If we are a client, do this

55 The RepMsg This is simply a local message handler to display info to the HUD. Nothing of interest here, just some debug strings. class RepMsg extends LocalMessage;

56 The KRock Now this class likely isn’t going to to be what you’d expect… What we end up doing here is setting up a bunch of variables. No replication work…

57 Krock Starting with the physics… //physics and collision DrawType=ST_Staticmesh StaticMesh=staticmesh'ErepTest.box' bCollideWorld=true bCollideActors=true CollisionRadius=8 Collisionheight=8

58 Krock And The Karma Params //Karma Physics=PHYS_Karma Begin Object Class=KarmaParams Name=KParams0 KAngularDamping=0 KLinearDamping=0 bHighDetailOnly=False bClientOnly=False bKDoubleTickRate=True Name="KParams0" End Object KParams=KarmaParams'KParams0'

59 Krock And you can play with some of these params to change the Karma properties…but I leave that to you. I’m just using the defaults in the sample code, so it’s really slippery for the KRock’s The only function to note is the tick function which calls KWake, so the KRock can never “sleep”.

60 Krock And finally, the network parameters. These are so that the object is deemed not “fixed in place”. And Karma can updated it’s position and send it over the wire…eg it’s deemed relevant. bStatic=false //req'd bNoDelete=false //req'd bHidden=false

61 Krock More to guarantee the objects relevance to the client… Btw: I likely don’t need the bGameRelevant. But when I wrote up the lesson, I was no where near a network to test out its absence. bGameRelevant=True bAlwaysRelevant=True //req'd bNetRelevant=true //req'd

62 Krock We update the movment oof the objet so they stay in sync, and change the update frequency to reflect how frequely this object is updated by the server. bReplicateMovement=true NetUpdateFrequency=10.000000 NetPriority=2.500000 bNetInitialRotation=True

63 Krock As found in the actor class NetUpdateFrequency reflects how many seconds between net updates. This should reflect the importance of your object. E.g. if the NetPriority is high (important) I would expect the NetUpdateFrequency to be low (more frequent).

64 Krock And lastly, change the remote role so that the client can anticipate where the Krock will be… RemoteRole=ROLE_SimulatedProxy bUpdateSimulatedPosition=True

65 Epc: the player controller Now, it’s actually the player controller that does the work in this case. This controller is really responsible for two actions, spawning the KRock through the fire command, and count the number spawned.

66 Epc: the player controller Thus the fire function: exec function Fire( optional float F ) { local vector l; local Krock t; if(ctr >= 5) return; else ctr++; Simple counting

67 Epc: the player controller Change what function gets called if we are not the server! if(role < Role_AUTHORITY) { clientFire(f); return; }

68 Epc: the player controller Then Spawn the Krock l=pawn.location; l.z+=64; super.Fire(f); t= Spawn(class'Krock',pawn,,l); t.Velocity=50*vector(pawn.Rotation);

69 Epc: the player controller But his is the interesting bit The client must call this function so that the server know that a new KRock has been spawned…otherwise it’s only client side! if(role < Role_AUTHORITY) { clientFire(f); return; }

70 Epc: the player controller Which brings us to: simulated function clientFire( optional float F ) { local vector l; local Krock t; l=pawn.location; l.z+=64; super.Fire(f); t= Spawn(class'Krock',pawn,,l); t.Velocity=50* vector(pawn.Rotation); } Which does fundamentally the same thing…

71 Epc: the player controller But the function itself is SIMULATED. Meaning that it can be called by a remote machine. This is how the server knows to spawn the KRock.

72 Epc: the player controller And lastly, we need a replication statement. replication { reliable if(role < Role_AUTHORITY) clientfire; reliable if(role == Role_AUTHORITY) ctr; }

73 Epc: the player controller Without the replication statement, even if the rest of the code is fine, we will not be able to see KRocks spawned on client machines.

74 On an interesting note: One this is up and running, take a look in the client machines and the servers log files. In the sample code I left in some log entries in the Epc.

75 On an interesting note: In the fire function: ClientFire function: log("Server----Fire"@t); log("Client----FIre"@t);

76 On an interesting note: The client machine, shows no entries at all with regards to the client fire log...none…nada…zip. However, the server machine show entries from both client and server.

77 On an interesting note: This means that it is the server that is in fact doing the spawning Krock and execution of the of the simulated function, which gets sent back to the client machine.

78 And what we should have Is a bunch of KRocks spinning around the level that get properly replictated on both client and server.

79 For fun Try changing the parent class of Krock to one of the projectiles, or even replace the spawning of the KRock with a projectile. Then remove the replication statement. Notice the changes this incurs.


Download ppt "Sega 500 An Introduction to Replication Jeff “Ezeikeil” Giles"

Similar presentations


Ads by Google