For direct access use https://forums.oldunreal.com
It's been quite a while since oldunreal had an overhaul, but we are moving to another server which require some updates and changes. The biggest change is the migration of our old reliable YaBB forum to phpBB. This system expects you to login with your username and old password known from YaBB.
If you experience any problems there is also the usual "password forgotten" function. Don't forget to clear your browser cache!
If you have any further concerns feel free to contact me: Smirftsch@oldunreal.com

Online replication problem with projectiles and repulser-item

Ask UnrealEd 1 mapping related questions, or give hints, tips and tricks
Post Reply
User avatar
SFJake
OldUnreal Member
Posts: 252
Joined: Sun Aug 15, 2010 4:31 pm

Online replication problem with projectiles and repulser-item

Post by SFJake »

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?
SFJake Center -
Unreal Nightmare - http://sfjake.byethost7.com/unrealnmproject.html
User avatar
han
Global Moderator
Posts: 686
Joined: Wed Dec 10, 2014 12:38 am

Re: Online replication problem with projectiles and repulser-item

Post by han »

Code: Select all

      // Location.
      unreliable if ( Role==ROLE_Authority && !bCarriedItem && (bNetInitial || bSimulatedPawn || RemoteRole
HX on Mod DB. Revision on Steam. Löffels on Patreon.
User avatar
SFJake
OldUnreal Member
Posts: 252
Joined: Sun Aug 15, 2010 4:31 pm

Re: Online replication problem with projectiles and repulser-item

Post by SFJake »

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.
SFJake Center -
Unreal Nightmare - http://sfjake.byethost7.com/unrealnmproject.html
User avatar
gopostal
OldUnreal Member
Posts: 1005
Joined: Thu Jul 31, 2008 9:29 pm

Re: Online replication problem with projectiles and repulser-item

Post by gopostal »

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
User avatar
SFJake
OldUnreal Member
Posts: 252
Joined: Sun Aug 15, 2010 4:31 pm

Re: Online replication problem with projectiles and repulser-item

Post by SFJake »

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.
SFJake Center -
Unreal Nightmare - http://sfjake.byethost7.com/unrealnmproject.html
User avatar
[]KAOS[]Casey
OldUnreal Member
Posts: 4497
Joined: Sun Aug 07, 2011 4:22 am
Location: over there

Re: Online replication problem with projectiles and repulser-item

Post by []KAOS[]Casey »

227 only?

If not, your only real choice is to destroy and recreate the projectiles.
User avatar
SFJake
OldUnreal Member
Posts: 252
Joined: Sun Aug 15, 2010 4:31 pm

Re: Online replication problem with projectiles and repulser-item

Post by SFJake »

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.
Last edited by SFJake on Sun Aug 02, 2015 6:43 pm, edited 1 time in total.
SFJake Center -
Unreal Nightmare - http://sfjake.byethost7.com/unrealnmproject.html
User avatar
gopostal
OldUnreal Member
Posts: 1005
Joined: Thu Jul 31, 2008 9:29 pm

Re: Online replication problem with projectiles and repulser-item

Post by gopostal »

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
User avatar
SFJake
OldUnreal Member
Posts: 252
Joined: Sun Aug 15, 2010 4:31 pm

Re: Online replication problem with projectiles and repulser-item

Post by SFJake »

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 edited by SFJake on Sun Aug 02, 2015 10:40 pm, edited 1 time in total.
SFJake Center -
Unreal Nightmare - http://sfjake.byethost7.com/unrealnmproject.html
User avatar
gopostal
OldUnreal Member
Posts: 1005
Joined: Thu Jul 31, 2008 9:29 pm

Re: Online replication problem with projectiles and repulser-item

Post by gopostal »

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
I don't want to give the end away
but we're all going to die one day
User avatar
SFJake
OldUnreal Member
Posts: 252
Joined: Sun Aug 15, 2010 4:31 pm

Re: Online replication problem with projectiles and repulser-item

Post by SFJake »

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 :P)

"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 :P
Last edited by SFJake on Mon Aug 03, 2015 2:57 am, edited 1 time in total.
SFJake Center -
Unreal Nightmare - http://sfjake.byethost7.com/unrealnmproject.html
User avatar
gopostal
OldUnreal Member
Posts: 1005
Joined: Thu Jul 31, 2008 9:29 pm

Re: Online replication problem with projectiles and repulser-item

Post by gopostal »

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.)
Last edited by gopostal on Mon Aug 03, 2015 3:51 am, edited 1 time in total.
I don't want to give the end away
but we're all going to die one day
User avatar
SFJake
OldUnreal Member
Posts: 252
Joined: Sun Aug 15, 2010 4:31 pm

Re: Online replication problem with projectiles and repulser-item

Post by SFJake »

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.
Last edited by SFJake on Mon Aug 03, 2015 4:14 am, edited 1 time in total.
SFJake Center -
Unreal Nightmare - http://sfjake.byethost7.com/unrealnmproject.html
User avatar
gopostal
OldUnreal Member
Posts: 1005
Joined: Thu Jul 31, 2008 9:29 pm

Re: Online replication problem with projectiles and repulser-item

Post by gopostal »

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
User avatar
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: Online replication problem with projectiles and repulser-item

Post by Masterkent »

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 edited by Masterkent on Tue Aug 04, 2015 7:51 am, edited 1 time in total.
User avatar
SFJake
OldUnreal Member
Posts: 252
Joined: Sun Aug 15, 2010 4:31 pm

Re: Online replication problem with projectiles and repulser-item

Post by SFJake »

Interesting way to do it! So all I really had to do, was go through a separate, reliable actor that does the reflection effect predictably so both server & client can see it? Maybe because in this case the pusher is also "bAlwaysRelevant" as well. Or its just the way you handle it and call it again in ProjectilePusher, particularily.

Well, its working perfectly now. Thank you!

And thanks gopostal, for all the effort. Maybe there are some silly mistakes in my code that made this harder, I'm very amateurish at all this.

But it works now, and I'm happy, and hopefully I learned something.
Last edited by SFJake on Mon Aug 03, 2015 5:02 pm, edited 1 time in total.
SFJake Center -
Unreal Nightmare - http://sfjake.byethost7.com/unrealnmproject.html
User avatar
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: Online replication problem with projectiles and repulser-item

Post by Masterkent »

So all I really had to do, was go through a separate, reliable actor that does the reflection effect predictably so both server & client can see it?
The only purpose of the auxiliary actor is to execute PushProjectiles on client. The same thing can be done by means of replicated function calls, but it would require giving some inventory item to every PlayerPawn in the game and calling replicated function for such item of every player. I think, the solution with actor is more simple (although replicated function calls could eat less network bandwidth).
Maybe because in this case the pusher is also "bAlwaysRelevant" as well.
Once projectiles are pushed on server, the corresponding client-side call should take place as soon as possible, therefore, the newly spawned actor should become visible to client immediately; otherwise, client-side execution of its PostBeginPlay function could be postponed or not happen at all. The simplest way to make the actor immediately relevant to all clients that might observe the pushing effect is to set its bAlwaysRelevant to True.
Well, its working perfectly now.
Not perfectly. As I said, this is just a rough approximation. You can expect that trajectories of pushed projectiles differ between server and client. But they may differ without any mods anyway.

For example, Eightball grenades after bouncing almost always have different actual (server-side) and predicted (client-side) move directions (and even explosion time differs between server and client). For another example, you can try to shoot over the bridge near to the end of Dig (Rrajigar Mine), where there is a powerful fan that is supposed to be able to deflect projectiles (technically their direction is changed when they enter some zone with special ZoneVelocity). In multiplayer game entering that zone often changes only server-side projectile's direction while client-side prediction does not take into account ZoneVelocity at all.
User avatar
gopostal
OldUnreal Member
Posts: 1005
Joined: Thu Jul 31, 2008 9:29 pm

Re: Online replication problem with projectiles and repulser-item

Post by gopostal »

You'll always have silly mistakes in your code. Literally every single time I post code part of me winces because I know that way smarter people than me are going to see it and if I missed something or made some stupid error then it's there for everyone to see. Learning to code is humbling and I've found that you just have to open up to the process and set aside ego. MK's posts are a perfect example of this. His code is a great workaround and I wish I had known of it when I did my Frying Pan. Like you I don't mind if it's 100% accurate across all clients, it's the effect I wanted.

I'm proud you didn't give up and you kept after things until you got it. That's impressive and bodes well for the quality of your work.
I don't want to give the end away
but we're all going to die one day
Post Reply

Return to “UnrealEd, the editor for Unreal up to version  226”