Replication from client to server.

Discussions about Coding and Scripting
Post Reply
Fulcrum
Novice
Posts: 24
Joined: Wed May 30, 2012 2:03 pm

Replication from client to server.

Post by Fulcrum »

Hey,

I've got a replication problem and I haven't got a clue what the problem might be.
I test the .u file using a dedicated server.

Code: Select all

class MyClass extends Actor
				native;

var bool hiyo;

native(1780) final function bool tits();

replication
{
	reliable if (Role < ROLE_Authority)
		send;
}

function send()
{
	Log("debugging");
}

simulated function PreBeginPlay()
{
	if (Role < ROLE_Authority) // client
	{
		send(); // should execute on the server
		
	}	
	Super.PreBeginPlay();
}
Basically send() never gets executed on the server. I check that by writing to the log. In the log I never see the line "debugging".

I hope you can help me out.

Cheers
User avatar
Feralidragon
Godlike
Posts: 5493
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: Replication from client to server.

Post by Feralidragon »

Well, client to server replication is a special case.

In short, your actor has to have a player as its Owner (PlayerPawn, TournamentPlayer, or other PlayerPawn subclass), and that PlayerPawn must be the one you want to replicate data from (in this case, your player PlayerPawn so you can see things in your client log).
You should also set the owner in the server alone and let it replicate normally to the client, so both get the exact same reference.

In a longer explanation, the main reason for this is ambiguity (if we can call it that way), since one thing is 1 point replicating to 1 or many endpoints (which is what happens in server->client), another is many points replicating to one: which one should execute/accept? All of them? That would be overkill for a server and wouldn't make much sense, so the correct thing to do is to keep the "1 to 1" or "1 to many" replication model, in this case "1 to 1" (1 specific client to 1 server), thus the need to define which player/client you want to replicate from (as the Owner).
Fulcrum
Novice
Posts: 24
Joined: Wed May 30, 2012 2:03 pm

Re: Replication from client to server.

Post by Fulcrum »

So can I just change the owner then?

Code: Select all

simulated function PreBeginPlay()
    {
       if (Role < ROLE_Authority) // client
       {
          Owner = LocalPlayerPawn; // how to get it?
		  Send();
          
       }   
       Super.PreBeginPlay();
    }
Or does it have to be done like this?

Code: Select all

    class MyClass extends Actor
                native;

    var bool hiyo;
	var MyInfo sup;

    native(1780) final function bool tits();

    simulated function PreBeginPlay()
    {
       if (Role < ROLE_Authority) // client
       {
          sup = Spawn(class'MyInfo', PlayerPawn); // with PlayerPawn being the local playerpawn; how to get it?
		  sup.Send();
          
       }   
       Super.PreBeginPlay();
    }

Code: Select all

class MyInfo extends Actor;

replication
{
   reliable if (Role < ROLE_Authority)
      send;
}

function send()
{
	Log("debugging");
}
Also what do you mean with setting the owner on the server alone?


Ty for you help btw :)
User avatar
Feralidragon
Godlike
Posts: 5493
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: Replication from client to server.

Post by Feralidragon »

I meant something along this:

Code: Select all

class MyClass extends Actor
native;

var bool hiyo;
var bool bSent;		//Variable to be set once send() is called from the client

native(1780) final function bool tits();

replication
{
	reliable if (Role < ROLE_Authority)
		send;
}

function send()
{
	Log("debugging");
}

simulated function PreBeginPlay()
{
local Pawn P;

	//Set owner in the server and let it replicate
	if (Role == ROLE_Authority)
	{
		for (P = Level.PawnList; P != None; P = P.NextPawn)
		{
			if (PlayerPawn(P) != None /* && <some other conditions here> */)
			{
				SetOwner(P);
				break;
			}
		}
	}

	Super.PreBeginPlay();
}

//Setup a tick waiting for the PlayerPawn(Owner) to be set
//The PostNetBeginPlay() event won't do the trick here since it only works with tear-off replication (bNetTemporary=True)
simulated function Tick(float Delta)
{
	if (!bSent && PlayerPawn(Owner) != None && Role < ROLE_Authority)
	{
		send();
		bSent = True;
	}
	
	Super.Tick(Delta);
}

//Set the RemoteRole to SimulatedProxy and bNetTemporary=False so the client version of the actor keeps connected to the server version
defaultproperties
{
	RemoteRole=ROLE_SimulatedProxy
	bNetTemporary=False
}
Although you can remove the whole "Set owner in the server and let it replicate" block from the code as long as you spawn the actor in the server only and like this:
Spawn(Class'MyClass ', <Some_PlayerPawn>,, <Some_PlayerPawn>.Location);

Anyway, the flow should be something like this:
1 - Spawn the actor in the server only (where Role == ROLE_Authority)
2 - Either:
a) assign a playerpawn owner from the spawn itself;
b) assign a playerpawn owner by searching in the pawn list and getting the one you actually want (server side only as well, aka Role == ROLE_Authority, so the Owner reference can replicate properly)
3 - In a client event of your choice (I have chosen Tick since it's the most reliable with the least delay, but that's just a personal preference, PostNetBeginPlay is the best of all but it doesn't get called in bNetTemporary=False actors, hence this alternate mode of doing things), and only AFTER the actor gets the playerpawn owner assigned on that end, call the function you want.
Fulcrum
Novice
Posts: 24
Joined: Wed May 30, 2012 2:03 pm

Re: Replication from client to server.

Post by Fulcrum »

Thanks a ton man. I'll try that out and report back here. :)

edit: It works now ty.
Post Reply