Replication Idioms

From Unreal Wiki, The Unreal Engine Documentation Site
Revision as of 19:29, 30 August 2013 by imported>Wormbo (some basic examples, to be expanded (feel free to add to it))
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

This article provides code examples for various replication concepts and tasks. If any example includes a defaultproperties block, keep in mind that default values are inherited from parent classes. Often you don't need to specify all of the values listed here.

Actor replication examples

The following are a few example class frames for various types of actor replication.

The ReplicationInfo (always replicate)

The class ReplicationInfo(no matching games found) already exists in all Unreal Engine games and contains the following relevant default values: <uscript> class ReplicationInfo extends Info abstract native;

defaultproperties {

 RemoteRole=ROLE_SimulatedProxy
 bAlwaysRelevant=True

} </uscript> RemoteRole=ROLE_SimulatedProxy ensures that actors of this type participate in replication, while bAlwaysRelevant=True ensures that actors of this type will be replicated to all clients, bypassing any relevance checks. The ReplicationInfo class itself is abstract, because creating instances of it wouldn't make sense - you should subclass it. ReplicationInfo is declared as native class for two reasons. One is that there are native subclasses, which is only allowed if the parent class is native as well.

The other reason is a special native handling of the bSkipActorPropertyReplication for replication purposes. (That property is set to True in ReplicationInfo's parent class Info.) If you look at the replication block of class Actor, you will notice that bSkipActorPropertyReplication can be overridden by bNetInitial, causing corresponding properties to be replicated at least once. The ReplicationInfo native code overrides this behavior and turns off even initial replication. Thus only replicated variables declared in subclasses will be replicated, even when sending the initial data. This makes ReplicationInfo more efficient for replication than other classes with the same default values.

Owner-only replication

Ensuring that an actor is only replicated to its owner can be achieved in multiple ways. An actor is always relevant to its owning client (i.e. the actor's owner must be the client's PlayerController/PlayerPawn, or the owner actor must be owned by the client), but only relevant to other clients under certain circumstances.

Invisible actors

If the actor is not supposed to be visible, owner-only replication can easily be achieved by hiding the actor: <uscript> defaultproperties {

 RemoteRole=ROLE_SimulatedProxy // or ROLE_DumbProxy or ROLE_AutonomousProxy
 bAlwaysRelevant=False // inherited from Actor, but keep in mind when inheriting from e.g. ReplicationInfo
 bHidden=True

} </uscript>

Visible actors

If the actor must be visible, but only to its owner, you can use the standard visibility settings for that purpose and at the same time replicate the actor only to its owning client: <uscript> defaultproperties {

 RemoteRole=ROLE_SimulatedProxy // or ROLE_DumbProxy or ROLE_AutonomousProxy
 bAlwaysRelevant=False // inherited from Actor, but keep in mind when inheriting from e.g. ReplicationInfo
 bOnlyOwnerSee=True

} </uscript> Note that the reverse, bOwnerNoSee won't prevent the actor from being replicated to its owner, because ownership is a stronger relevance criteria.

Regardless of visibility

Starting with Unreal Engine 2, replication can be limited to the owner without having to change rendering properties: <uscript> defaultproperties {

 RemoteRole=ROLE_SimulatedProxy // or ROLE_DumbProxy or ROLE_AutonomousProxy
 bAlwaysRelevant=False // inherited from Actor, but keep in mind when inheriting from e.g. ReplicationInfo
 bOnlyRelevantToOwner=True

} </uscript> Since the actor still also exists serversidely, you will probably still use bOwnerNoSee for the actor.

Replicate as if visible

In special cases you might want to replicate an invisible actor as if it was visible, i.e. only to clients that would be able to see the actor if it wasn't invisible. For example you might want to replicate a projectile, but handle its visibility entirely via a separate Emitter actor. In that case you cannot rely on bHidden, because it would prevent replication for all but the owning client: <uscript> defaultproperties {

 RemoteRole=ROLE_SimulatedProxy // or ROLE_DumbProxy or ROLE_AutonomousProxy
 bAlwaysRelevant=False // inherited from Actor, but keep in mind when inheriting from e.g. ReplicationInfo
 DrawType=DT_None

} </uscript>

Variable replication

This section describes various ways to replicate variable values.

Replicating all changes

Unreal Engine 1 and Unreal Engine 2: <uscript> replication {

 unreliable if (Role == ROLE_Authority)
   VariableToReplicate;

} </uscript> Only Unreal Engine 2: <uscript> replication {

 unreliable if (True)
   VariableToReplicate;

} </uscript> Unreal Engine 3: <uscript> replication {

 if (True)
   VariableToReplicate;

} </uscript> Why just True? Well, variables can only be replicated in one direction: From the server to the clients. On the server the expression Role == ROLE_Authority always evaluates to True, so there's no need to evaluate it every time.

Only the initial value

Often all changes of a value can be simulated by the client, as long as it knows the starting value. In that case it would be a waste of bandwidth to replicate additional serverside changes.

Unreal Engine 1 and Unreal Engine 2: <uscript> replication {

 unreliable if (Role == ROLE_Authority && bNetInitial)
   VariableToReplicate;

} </uscript> Only Unreal Engine 2: <uscript> replication {

 unreliable if (bNetInitial)
   VariableToReplicate;

} </uscript> Unreal Engine 3: <uscript> replication {

 if (bNetInitial)
   VariableToReplicate;

} </uscript>

From client to server

As mentioned above, variable values only replicate from the server to clients. For the other way, you need to use function replication to update the serverside value. But even then, replication is only possible from the owning client to the server. If the actor isn't owned by the sending client, the server will discard the replicated call or value.

Unreal Engine 1 can actually replicate values from the owning client to the server: <uscript> replication {

 unreliable if (Role != ROLE_Authority) // only works in Unreal Engine 1 and only for owning client!
   VariableToReplicate;

} </uscript>

Replicated function calls