logo
Main

Forums

Downloads

Unreal-Netiquette

Donate for Oldunreal:
Donate

borderline

Links to our wiki:
Wiki

Walkthrough

Links

Tutorials

Unreal Reference

Usermaps

borderline

Contact us:
Submit News
Page Index Toggle Pages: [1] 2  Send TopicPrint
Hot Topic (More than 10 Replies) Online replication problem with projectiles and repulser-item (Read 5382 times)
SFJake
Full Member
***
Offline


Oldunreal member

Posts: 248
Joined: Aug 15th, 2010
Gender: Male
Online replication problem with projectiles and repulser-item
Jul 30th, 2015 at 7:07pm
Print Post  
I hate online roles and all that stuff but here we go.

In my mod, I've created a REPULSER item, which when activated, will push projectiles away from you (as well as monsters).

In single player, obviously, this works perfectly fine.


In multiplayer however, it does not. I try to actively change the remoterole of the projectiles the REPULSER "catches", but it does nothing. Even if it works "server side", the client will never see the projectile being pushed away.

And I have no idea how to handle that. The repulser works just fine with Pawns, going through TakeDamage.

Projectiles, however, are using this formula:

Code
Select All
foreach VisibleCollidingActors(class'projectile', P, 750, Owner.Location)
{
	if (!P.Instigator.bIsPlayer && P.Instigator != self )
	{
		P.RemoteRole=ROLE_SimulatedProxy;
		P.Instigator=Pawn(Owner);
		A=Instigator.Location;
		B=P.Location;
		C=A-B;
		D=rotator(c);

		D.Pitch+=32768;
		D.Roll+=32768;

		P.SetRotation(D);
		P.Velocity = vector(D) * P.speed;
	}
}
 



What essentially happens is the projectile IS pushed back, server side, but visually, its not, even if bNetTemporary on the projectile was false. Client side, it looks like the projectile keeps moving in the same direction.

How can I possibly fix this?
  
Back to top
 
IP Logged
 
han
Global Moderator
Unreal Rendering Guru
Developer Team
*****
Offline


Oldunreal member

Posts: 572
Location: Germany
Joined: Dec 10th, 2014
Gender: Male
Re: Online replication problem with projectiles and repulser-item
Reply #1 - Jul 30th, 2015 at 7:25pm
Print Post  
Code
Select All
	// Location.
	unreliable if ( Role==ROLE_Authority && !bCarriedItem && (bNetInitial || bSimulatedPawn || RemoteRole<ROLE_SimulatedProxy) )
		Location;
	unreliable if ( Role==ROLE_Authority && !bCarriedItem && (DrawType==DT_Mesh || DrawType==DT_Brush) && (bNetInitial || bSimulatedPawn || RemoteRole<ROLE_SimulatedProxy) )
		Rotation;
 


So you wont get Location and Rotation updates for if RemoteRole==ROLE_SimulatedProxy.
  

HX on Mod DB. Revision on Steam. Löffels on Patreon.
Back to top
 
IP Logged
 
SFJake
Full Member
***
Offline


Oldunreal member

Posts: 248
Joined: Aug 15th, 2010
Gender: Male
Re: Online replication problem with projectiles and repulser-item
Reply #2 - Jul 30th, 2015 at 8:25pm
Print Post  
I don't understand. You want me to add this to the projecitles? The Repulser has to push away any projectiles, vanilla or otherwise. I can't add those lines of codes to all potential projectiles.
  
Back to top
 
IP Logged
 
gopostal
Betatester
Offline


Hack coder

Posts: 940
Joined: Jul 31st, 2008
Gender: Male
Re: Online replication problem with projectiles and repulser-item
Reply #3 - Jul 31st, 2015 at 12:32am
Print Post  
I went through this and tried a lot of different things to make it work. In the Food Fight mod I made a Frying Pan weapon that I originally wanted to be able to deflect incoming projectiles back at the sender or off into some random direction. I had varying degrees of success but ended up settling on destroying the projectile then spawning some smoking wrecked chunks to simulate the pan destroying the projectile. It works pretty good visually and has the added benefit of working with any subclassed projectile and there's no online weirdness that you may or may not account for ahead of time.
  

I don't want to give the end away
but we're all going to die one day
Back to top
 
IP Logged
 
SFJake
Full Member
***
Offline


Oldunreal member

Posts: 248
Joined: Aug 15th, 2010
Gender: Male
Re: Online replication problem with projectiles and repulser-item
Reply #4 - Jul 31st, 2015 at 7:52pm
Print Post  
Well, I tried something like that, destroying the projectile and spawning a new one instead. Works better, but client-side, it reflects it fine, but it doesn't destroy the original projectile (so it now looks like there's 2).

It does work perfectly fine if they have bNetTemporary False, but not if its true. I'm not sure why I can't seem to get that.
  
Back to top
 
IP Logged
 
[]KAOS[]Casey
Developer Team
Betatester
Offline


nedm

Posts: 3201
Joined: Aug 7th, 2011
Gender: Male
Re: Online replication problem with projectiles and repulser-item
Reply #5 - Jul 31st, 2015 at 9:48pm
Print Post  
227 only?

If not, your only real choice is to destroy and recreate the projectiles.
  
Back to top
 
IP Logged
 
SFJake
Full Member
***
Offline


Oldunreal member

Posts: 248
Joined: Aug 15th, 2010
Gender: Male
Re: Online replication problem with projectiles and repulser-item
Reply #6 - Aug 2nd, 2015 at 6:40pm
Print Post  
Like I said though, for some reason I can't successfully destroy the projectile client side. Purely a visual issue but I don't get how to do it.
  
Back to top
 
IP Logged
 
gopostal
Betatester
Offline


Hack coder

Posts: 940
Joined: Jul 31st, 2008
Gender: Male
Re: Online replication problem with projectiles and repulser-item
Reply #7 - Aug 2nd, 2015 at 8:11pm
Print Post  
If you call .Destroy() on the projectile server side then it will destroy on the client too.
  

I don't want to give the end away
but we're all going to die one day
Back to top
 
IP Logged
 
SFJake
Full Member
***
Offline


Oldunreal member

Posts: 248
Joined: Aug 15th, 2010
Gender: Male
Re: Online replication problem with projectiles and repulser-item
Reply #8 - Aug 2nd, 2015 at 8:49pm
Print Post  
And how does one uh.. do that? The item is used by the player, not the server.

I changed the code above with P.Destroy. But how can I specifically call that "server side"?

I even tried this in the Repulser:

                             if (RemoteRole==ROLE_Authority)
                                   P.Destroy();

The destruction server side happens but again, not client side.


Only projectiles with ROLE_DumbProxy & bNetTemporary=false gets deleted, and even then not completely, I had to add P.LifeSpan=0.1 for them to disapear.

I'm clearly missing something.

I'm using 227i if it changes anything.
« Last Edit: Aug 2nd, 2015 at 10:40pm by SFJake »  
Back to top
 
IP Logged
 
gopostal
Betatester
Offline


Hack coder

Posts: 940
Joined: Jul 31st, 2008
Gender: Male
Re: Online replication problem with projectiles and repulser-item
Reply #9 - Aug 2nd, 2015 at 11:28pm
Print Post  
This is a sick read but if you print it and then take your time you can work though most of it:
http://wiki.beyondunreal.com/Legacy:Replication_De-Obfuscation

Here's a chunk of the code from the FoodFight frying pan. This check occurs when the weapon fires (it swings out in front of the player). If it finds one it spawns some smoking chunks, a small flash, and also destroys the projectile.
Code
Select All
      //looking for an incoming projectile
      foreach RadiusActors(class'Actor', F, 300, Owner.Location)
      {
    	  dir=F.Location-Owner.Location;

         if((normal(dir) DOT normal(X)) > viewangle)
         {
       	  HitLocation = F.Location - normal(dir) * F.CollisionRadius;
            if (F.IsA('Projectile'))
            {
               if(F.IsA('Chunk') ||F.IsA('ForceFieldProj') || F.IsA('Arc') || F.IsA('Fragment') || F.IsA('ShellCase') || F.IsA('FFProjectileDeco') || F.IsA('Mtracer'))
						return;
					//found a valid projectile, spawn some effects and destroy it
          	  for (i=0; i<(3); i++)
	 			  {
						b = Spawn(class'ProjectileFragments',,, HitLocation);
		  				b.Velocity = vector(RotRand()) * (FRand() * 200);
					}
					Spawn(class'SpriteBallExplosion',,,HitLocation);
					F.Destroy();
	       		PlaySound(sound'Gong1', SLOT_None, 150);
            }
    	  }
      } 



Remember to mentally sort between what is simulated and what isn't. Calling destroy on a projectile will replicate that out and destroy it on all clients provided you haven't made changes to it's replication roles. Destroying something that's simulated will remove it for that player only (with exceptions for sure, it's not that simple lol).
  

I don't want to give the end away
but we're all going to die one day
Back to top
 
IP Logged
 
SFJake
Full Member
***
Offline


Oldunreal member

Posts: 248
Joined: Aug 15th, 2010
Gender: Male
Re: Online replication problem with projectiles and repulser-item
Reply #10 - Aug 3rd, 2015 at 2:56am
Print Post  
Man, are you sure your code works and projectiles that are bNetTemporary=True are destroyed? There is nothing different in your code, not really. Except its using foreach RadiusActors.

Here's a line from that link (which I knew about, but thanks Tongue)

"bNetTemporary actors need to be destroyed in clientside simulated code, since a server destruction of the actor will not replicate to the client, because of it's bNetTemporary status."

I would THINK thats the real issue. But I don't know why it happens. My code happens upon activation of the item.. something is not properly simulated client side from that? I don't know.

Gah, well I'm done trying random things at this point. I'd have to use Log and figure whats not happening. I'll see if I ever find time for that. I've read that page about replication various times but its so complicated. Too much work for so little gain, its just a hobby damnit Tongue
  
Back to top
 
IP Logged
 
gopostal
Betatester
Offline


Hack coder

Posts: 940
Joined: Jul 31st, 2008
Gender: Male
Re: Online replication problem with projectiles and repulser-item
Reply #11 - Aug 3rd, 2015 at 3:43am
Print Post  
Don't give up yet, you are really close to the key turning in the lock.

We are playing DM together and you fire a rocket at me. The server sends out the rocket being spawned as well as it's direction to both of us. The server is in charge of this rocket and accepts input from us that may affect what it does but it has the final say.

On screen your game creates the rocket. The server tells your game "Spawn it here and point it that way". Your local machine renders all this but your copy is local. In order to really affect the rocket you need to tell the server you want to do something (like jump in front of it). If you pulled your internet plug at this second you could blow up the rocket but the server's rocket would still carry on flying.

This is why your mod works locally but not on server. In order to rebound a rocket You need to tell the server to totally change the direction of the projectile. You can do this in a minor way (see function TraceAltFire() in the impact hammer) but to do wholesale reflection you really need to destroy the projectile then create a new one oriented in the direction you want it to go. You can do that easily on your local system since it's all simulated and there's no need to share this new information with anyone else.

I hope that helps.

(Edit: I should add that you need to do the creation of a new one because direction [velocity] isn't replicated often enough. Projectiles don't need direction replicated often since they continue on their path until they are acted upon. Consider the ripper blade...it flies straight until it hits a wall, but then the code kicks in and changes the direction for it. Since both client and server have that code the client can accurately predict the path and render the blade with periodic updates from the server and it all looks smooth. Take that code-assisted prediction away and you end up with the alt-guided redeemer that looks all herky-jerky as you watch someone fly it. And that's with a ton of added code to help it be smoother.)
  

I don't want to give the end away
but we're all going to die one day
Back to top
 
IP Logged
 
SFJake
Full Member
***
Offline


Oldunreal member

Posts: 248
Joined: Aug 15th, 2010
Gender: Male
Re: Online replication problem with projectiles and repulser-item
Reply #12 - Aug 3rd, 2015 at 4:13am
Print Post  
I appreciate the effort, really, but you're telling me what I already know (on paper, anyway) and not the helping the issue I'm having.

Like I said, I already use Destroy(). It doesn't work, at least when used from my inventory item. Why is the projectile only destroyed server side, but not client side, and how do you get to it?

Somehow it works with your frying pan, yet it doesn't work here, and the core of the code that does it is the same, so thats not the issue.

I can understand what bNetTemporary=True and SimulatedProxy roles, and that makes those projectiles impossible to alter, since the client side simulates the entire thing (because it can, because the projectile is obvious/predictable).


But that does not tell me how to reach it and destroy it on the client. Again, I CANNOT change the scripting or default properties of a projectile. I have to deal with vanilla projectiles here.


We KNOW the server destroys the projectiles but does not send it to the client. Everything works exactly as it should, except that a "phantom" projectile still exists client side.

The problem is I have no clue how the code works intricately on the inside and why I can't reach the client-side projectile.
  
Back to top
 
IP Logged
 
gopostal
Betatester
Offline


Hack coder

Posts: 940
Joined: Jul 31st, 2008
Gender: Male
Re: Online replication problem with projectiles and repulser-item
Reply #13 - Aug 3rd, 2015 at 10:14am
Print Post  
Send me your mod. Let me look at things, I'll bet you it's something simple you are overlooking. I can't tell you the number of times I've done that and someone else looks at it and sees the issue in moments. You most certainly can get too close to your code.

The bottom line is that if you properly destroy a projectile in code and that code is not simulated then it should destroy it on the server (oversimplified but mostly accurate). If it doesn't then you need to declare some missing replication for your inventory item so that command passes from client to server. The code bit I posted is from 'state NormalFire', and state code is set up all the way back in 'object'.

If you are calling the visiblecolliding in your OP from a new function you are declaring then you need to set up replication for that function most likely, or you could move that into a state code that is already replicated.
  

I don't want to give the end away
but we're all going to die one day
Back to top
 
IP Logged
 
Masterkent
Developer Team
Offline



Posts: 1332
Location: Russia
Joined: Apr 5th, 2013
Gender: Male
Re: Online replication problem with projectiles and repulser-item
Reply #14 - Aug 3rd, 2015 at 3:18pm
Print Post  
SFJake wrote on Jul 31st, 2015 at 7:52pm:
It does work perfectly fine if they have bNetTemporary False, but not if its true. I'm not sure why I can't seem to get that.

AFAIR, bNetTemporary = true makes the client-side projectile completely independent from the original server-side projectile immediately after its initialization. That is, there is no any synchronization between them, unless you explicitly provide such a synchronization somehow. After detaching it's even not possible to replicate a reference to the server-side projectile to the client in order to check if the client-side projectile and its prototype are supposed to be the same object.

This is an ugly optimization whose side-effects are often observable even without such mods - sometimes client-side behavior radically differs from server-side behavior.

I know only two possible solutions:
1) add synchronization actors for all projectiles - difficult and costly method;
2) try to apply nearly the same actions on both server and client sides.

The second solution gives a very rough approximation, but I would use it nevertheless, considering the fact that prediction with bNetTemporary is very far from perfect anyway. I hardly get the rationale behind some of your implementation choices such as checks for Instigator, so I'll demonstrate the idea on a different example:

Code
Select All
class ProjectilePusher expands Info;

simulated function PostBeginPlay()
{
	if (Level.NetMode == NM_Client)
		PushProjectiles(Level, Location);
}

static function bool PushProjectiles(LevelInfo Level, vector Pos)
{
	const Radius = 750;
        const PushFactor = 1.0;
	local Projectile P;
	local vector Offset, OldVelocity;
	local float Speed;
	local bool bPushed;

	foreach Level.RadiusActors(class'Projectile', P, Radius, Pos)
		if (P.Role != ROLE_DumbProxy)
		{
			Offset = P.Location - Pos;
			OldVelocity = P.Velocity;
			Speed = VSize(P.Velocity);
			P.Velocity += PushFactor * (Radius - VSize(Offset)) * Normal(Offset);
			P.Velocity = Normal(P.Velocity) * Speed;
			if (VSize(P.Velocity) > 0)
			{
				P.Acceleration = Normal(P.Velocity) * VSize(P.Acceleration);
				P.SetRotation(rotator(P.Velocity));
			}
			else
				P.Velocity = OldVelocity;
			bPushed = true;
		}

	return bPushed;
}

static function Apply(LevelInfo Level, vector Pos)
{
	if (PushProjectiles(Level, Pos) && Level.NetMode != NM_Standalone) // push projectiles server-side
		Level.Spawn(class'ProjectilePusher',,, Pos); // then do the same client-side
}

defaultproperties
{
	bAlwaysRelevant=True
	bNetTemporary=True
	LifeSpan=1
	RemoteRole=ROLE_SimulatedProxy
} 


Code
Select All
// somewhere in the inventory class...

function Timer()
{
	if (Owner != none)
		class'ProjectilePusher'.static.Apply(Level, Owner.Location);
} 


« Last Edit: Aug 4th, 2015 at 7:51am by Masterkent »  
Back to top
 
IP Logged
 
Page Index Toggle Pages: [1] 2 
Send TopicPrint
Bookmarks: del.icio.us Digg Facebook Google Google+ Linked in reddit StumbleUpon Twitter Yahoo