PDA

View Full Version : Composition and replication



Bankler
09-01-2011, 10:19 AM
More replication issues...

In my game, I have a quite detailed injury system. My pawn (WPPawn) has a variable:
var WPHealth HealthSystem;

This is a class handling all kinds of injuries the pawn can get. So a pawn HAS A HealthSystem (the class is called WPHealth).

In the HealthSystem, I have a collection of functions to handle logic of different kinds of hits (all this logic should preferably be handled server side if I'm not mistaken). It also has a collection of integer variables, like HPTotal, Stun, HPHead, HPTorso and so on. These need to be accessible clientside so I can show the correct stuff in the HUD.

What would be the best design?

If I only create the HealthSystem serverside:

simulated function PostBeginPlay()
{
if(Role == ROLE_Autority)
{
HealthSystem = Spawn(class'WPHealth');
HealthSystem.Setup(self);
}
}
... I cannot find any way of accessing its variables (or even the healthSystem object itself) when I'm on the client. Because from the client's point of view, the pawn doesn't have a HealthSystem.

If I instead create the HealthSystem on both sides:

simulated function PostBeginPlay()
{
HealthSystem = Spawn(class'WPHealth');
HealthSystem.Setup(self);
}

... the HealthSystem becomes two totally independent copies (both are ROLE_Authority but on its own respective side), and the important variables that I need to be able to read will not be replicated from the server by putting them in the class' replication block.

The Pawn class is huge as it is, so I would prefer a solution based on composition, rather than just putting all the stuff in the pawn class.

Bankler
09-01-2011, 02:06 PM
Small update:

Current solution (which works, but I'm not really comfortable with it) is that the HealthSystem is created in the pawn and only lives on the server (which sounds reasonable). It's only created if we are ROLE_Authority. Every time the important health stats (the ones i wanted to replicate.. or something) change, I mirror them in the pawn-class, where they get replicated to the clients version of the pawn.

So my gui looks for the values (the mirrored ones) it needs in the Pawn, instead of directly in Pawn.HealthSystem.

Did someone say "unnecessary data duplication"? Yeah, I'd agree. I get the feeling I shouldn't need to do this. :(

one1
09-08-2011, 09:05 AM
Sorry for late reply.

You have 2 options to solve your issue. First one, which is also more optimized one, is to have all these vars simply on Pawn already and replicate them from server to player that owns the pawn - or to all players (in case you want all players to be able to see health of certain player).

Second one is to create another actor with role SimulatedProxy (best is to extend out of info, since this is invisible actor). It's owner MUST be Pawn that has this healthsystem, so when you do spawning in your pawn, you must set owner:


simulated function PostBeginPlay()
{
if (Role == ROLE_Authority)
{
HS = Spawn(class'HealthSystem', self);
}
}

In Pawn var declaration section, HS is:

var HealthSystem HS;

And in Pawn's replication block add:

replication
{
if (Role == ROLE_Authority && bNetOwner) HS;
}

That way, if you are client that owns the pawn, you will have reference to replicated healthsystem.

Inside your healthsystem actor, just declare all kind of vars you would like to be displayed on HUD inside replication block - that way they are surely replicated FROM server to CLIENT and server has full authority over them while client just reads and displays them.

EDIT: In defaultproperties of your HS actor, add: bOnlyRelevantToOwner=true