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 issues with snowfall recycling

The section related to UnrealScript and modding. This board is for coders to discuss and exchange experiences or ask questions.
Post Reply
User avatar
gopostal
OldUnreal Member
Posts: 1005
Joined: Thu Jul 31, 2008 9:29 pm

Online issues with snowfall recycling

Post by gopostal »

I've been trying to fix snow/rain so it works properly online using the scripts from the download page. I have it working (almost) properly online with one small problem that I cannot seem to solve. The first round of snowflakes spawn correctly and fall as they should. However starting with the second cycle (flakes are recycled into the sky to fall again) a small amount of the random flakes lose the ability to fall online and remain in the sky, floating. Over time these build up and ruin the snow effect.

I've sussed out replication so that the snow continues if you leave the zone and if you "kill" the source of the snow (in this case the Ice Dragon). However the flakes that lose falling velocity remain there. I've tested this thing to death and I cannot see any reason for this behavior. I know it's a bit of code but can someone peek at this and tell me if an issue jumps out at you? Once this is fixed I'll post the mod/source so everyone can use fully working snow effects tied to actors (like moving clouds in the sky, etc). I'm really close but I just can't close the deal.

Here is a very short vid of the issue. This is online play:

See the flakes that linger in the sky? They are being affected by the "wind" part of the code but do not fall and do not destroy when the spawning actor is destroyed.

The flake code:

Code: Select all

class SnowDrop expands Effects;

var bool bIgnoreZoneChange;
var SnowActor Snowy;

var float am;
var bool bInitialized;

simulated function SetupSnow(float StartZ)
{
      local vector NewLoc, v;

      bInitialized = true;
      bIgnoreZoneChange = true;

      if (Snowy==None || Snowy.bDeleteMe)
      {
            Snowy=SnowActor(Owner);
            if (Snowy==None || Snowy.bDeleteMe)
            {
                  destroy();
                  bIgnoreZoneChange = false;
                  return;
            }
      }

      NewLoc.X = Snowy.Location.X + FRand()*2*Snowy.Radius-Snowy.Radius;
      NewLoc.Y = Snowy.Location.Y + FRand()*2*Snowy.Radius-Snowy.Radius;
      NewLoc.Z = Snowy.Location.Z - StartZ;
      am = (frand() * 16)+16;
      v = Snowy.WindEffect;
      v.Z = (Snowy.FallSpeedMinimum + (frand() * (Snowy.FallSpeedMaximum-Snowy.FallSpeedMinimum))) * -1;
      if (!SetLocation(NewLoc))
      {
            SetupSnow(StartZ);
            bIgnoreZoneChange = false;
            return;
      }

      Velocity = v;
      GotoState('Fall');
      bIgnoreZoneChange = false;
}

simulated function HitWall(vector HitNormal, actor HitWall)
{
      GotoState('Melting');
}

simulated function Landed(vector HitNormal)
{
      SetupSnow(0);
}

simulated function Touch(actor Other)
{
      SetupSnow(0);
}

simulated event ZoneChange(ZoneInfo NewZone)
{
      if ((bInitialized) && (!bIgnoreZoneChange))
            SetupSnow(0);
}


auto State Fall
{
      simulated function Timer()
      {
            local vector v;
            if (Snowy != none)
            {
                  V = Velocity;
                  v.X = Snowy.WindEffect.X + (am * sin(location.z));
                  v.Y = Snowy.WindEffect.X + (am * sin(location.z));
                  Velocity = V;
            }
      }

begin:
      SetTimer(0.5,true);
}


State Melting
{
      simulated function Timer()
      {
            SetupSnow(0);
      }

begin:
      SetTimer(1.0,false);
}

defaultproperties
{
   Physics=PHYS_Projectile
   RemoteRole=ROLE_None
   DrawType=DT_Sprite
   Style=STY_Translucent 
   Texture=Texture'Snow1'
   DrawScale=0.20
   CollisionRadius=1.00
   CollisionHeight=1.00
   bCollideActors=True
   bCollideWorld=True
}
and the spawning actor code:

Code: Select all

class SnowActor expands Effects;

var float       Radius;
var float       MaxDrops;
var float       FallSpeedMaximum;
var float       FallSpeedMinimum;
var int             SpawnHeight;
var vector       WindEffect;
var int             SnowCount;

replication
{
      reliable if (Role==ROLE_Authority)
            Radius, MaxDrops, FallSpeedMaximum, FallSpeedMinimum, WindEffect, SpawnHeight;
}

simulated function Tick(float deltatime)
{
   local int i;
   local float MaxZ;
   local Vector T,V,N;
   local Actor A;
   local SnowDrop Flake;

      if (Owner == None)
      {
            if (Role == ROLE_Authority)
                  Destroy();
            return;
      }
      else if (Level.Netmode == NM_DedicatedServer)
            return;

   if(FastTrace(location + vect(0, 0, +1) * SpawnHeight))
      SetLocation(Owner.Location + vect(0, 0, +1) * SpawnHeight);
   else if(FastTrace(location + vect(0, 0, +1) * (SpawnHeight/2)))
      SetLocation(Owner.Location + vect(0, 0, +1) * (SpawnHeight/2));
   else SetLocation(Owner.Location);

   if (SnowCount
I don't want to give the end away
but we're all going to die one day
User avatar
Hyper
OldUnreal Member
Posts: 3514
Joined: Fri Oct 11, 2002 5:41 pm
Contact:

Re: Online issues with snowfall recycling

Post by Hyper »

Must be special snowflakes. Just give them some personalized love and attention and everything will turn out fine. ;)
The man who stopped a tsunami

http://www.hypercoop.tk
unreal://hypercoop.tk
User avatar
gopostal
OldUnreal Member
Posts: 1005
Joined: Thu Jul 31, 2008 9:29 pm

Re: Online issues with snowfall recycling

Post by gopostal »

Holy shit, that made sense. It also answers some other issues I've had over the years that suffered from this type of problem. Thank you again MK!!
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 issues with snowfall recycling

Post by Masterkent »

After I copied your code to a normal text editor and read it properly, I noticed that you spawn SnowDrop actors client-side (which makes sense), hence they have Role == ROLE_Authority anyway and therefore don't need to rely on the simulated keyword (you could remove all occurrences of that keyword in SnowDrop). So, at this moment I have no idea what may be wrong with the code you showed, except that potentially infinite recursion in SetupSnow looks a bit scary. Besides, I couldn't notice a problem on the given video. Could you show the difference between the behavior in standalone and online game?
Last edited by Masterkent on Thu Sep 14, 2017 6:08 am, edited 1 time in total.
User avatar
gopostal
OldUnreal Member
Posts: 1005
Joined: Thu Jul 31, 2008 9:29 pm

Re: Online issues with snowfall recycling

Post by gopostal »

This is a 10 second video of offline play in the same spot:


See how the snowfall cycles correctly and no flakes end up hanging in the air? That's the online problem that I was trying to solve.

It's really weird because the broken falling snow accepts the first adjustment for wind but not the dropping velocity but then doesn't timer update for any further wind adjustments. BTW, you can 'kill' the cloud and stop the snow and all that works just fine but the hanging snow doesn't delete. This may be because it never reaches the recycle point and the check to see if the spawning actor is != none. 

This is online play where I kill the cloud. You can clearly see the issue with this video (20 seconds):


Last edited by gopostal on Thu Sep 14, 2017 12:15 pm, 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
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: Online issues with snowfall recycling

Post by Masterkent »

It looks like you've set FallSpeedMinimum or FallSpeedMaximum to a very low value, so some particles get low random vertical velocity.

Code: Select all

   FallSpeedMaximum=128.00
   FallSpeedMinimum=256.00
should be changed to

Code: Select all

   FallSpeedMaximum=256.00
   FallSpeedMinimum=128.00
(albeit the current implementation handles both variants similarly)
Last edited by Masterkent on Fri Sep 15, 2017 6:48 pm, edited 1 time in total.
User avatar
gopostal
OldUnreal Member
Posts: 1005
Joined: Thu Jul 31, 2008 9:29 pm

Re: Online issues with snowfall recycling

Post by gopostal »

Thank you for staying with this. I tested the changes (twice to be sure) and it made no difference in online play. Offline still performs correctly. Would it help if I generated a short log file of the individual flake velocities?
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 issues with snowfall recycling

Post by Masterkent »

OK, this time I decided to analyze the given code in depth and check how it works. It looks like that online issue is caused by some UT glitch related to resetting Velocity by a postponed effect of SetLocation. When Velocity is changed on the next tick after execution of SetLocation, I couldn't notice such troubles.

But I think that this is the least trouble you should worry about; there are more severe issues in that code.

Spawn(class 'SnowDrop',Self,,N) may always try to spawn a SnowDrop actor out of world for a particular level, because N is close to location (X=0,Y=0,Z=0) that does not necessarily correspond to a free space where you can place such actors.

I could reproduce a real infinite recursion in SetupSnow after spawning SnowActor in "bad" place (UT immediately crashes).

SnowActor.Touch would reset the snow particle even when the particle touches a non-solid actor such as Engine.Trigger.

ZoneChange also unconditionally resets the snow particle, albeit I don't understand why somebody would want such a behavior if the new zone is not supposed to be a fluid and we have a plain air-to-air transition.

I couldn't figure out the purpose of MaxZ.

Code: Select all

      A = Trace(v,n,t,location,false);
      if (A!=None)
         MaxZ = location.z - a.location.z;
      else
         MaxZ = location.z - 20480;
If Trace(v,n,t,location,false) returns the LevelInfo actor, then A.Location can be very far from the hit location (actual hit location is stored in v).

In the end, I rewrote a big part of this implementation when playing with the code, here's the result which can be used for testing (it's not for end users):

https://www.upload.ee/files/7461600/Snow.u.html

Usage: Summon Snow.SnowActor

The package includes all sources, maybe you'll find something useful there.
Last edited by Masterkent on Fri Sep 15, 2017 7:51 pm, edited 1 time in total.
User avatar
gopostal
OldUnreal Member
Posts: 1005
Joined: Thu Jul 31, 2008 9:29 pm

Re: Online issues with snowfall recycling

Post by gopostal »

maybe you'll find something useful there.
Are you kidding? I find something useful in everything you put out. Thank you X100 for spending your time on this and correcting my mistakes. I downloaded the u file and I'm looking forward to seeing where your improvements are. It will be nice to be able to have true, fully working online snow that can be tied to an actor or spawned in place. Thank you for helping with that! 

Update: I imported your code and it works wonderfully, online and off. You did considerable work and pretty much rewrote the entire thing. On one hand I'm sad that my work was so bad but I'm happy you fixed it and I can see the better way to get where I wanted to go.

Do you have an Amazon account I can tip into? You did real work here and saved me a ton of lost hours. This was crucial in what I'm working on and I owe you above forum thanks for this.
Last edited by gopostal on Sat Sep 16, 2017 3:37 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
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: Online issues with snowfall recycling

Post by Masterkent »

Basically, I wanted to try to implement a different physical model that would rely on gravity force, air resistance force and air/wind velocity, so snow would not adhere to vertical walls and could roll down on slopes and then fall following a parabolic trajectory. Also I was curious about how many particles the client could handle and render without noticeable FPS drops.

I removed the vortical movement, because it didn't look good from my point of view and I couldn't devise a decent alternative. You can return it back.

I forgot to declare MinAllowedResitanceFactor as simulated. This function is supposed to prevent too fast movement in case if MinAirResistanceFactor or MaxAirResistanceFactor is set to a very low value, it should be made simulated to be callable in an online game. If you want to have a uniform distribution of speeds for different particles, AirResistanceFactor should be calculated a bit differently:

Code: Select all

                  AirResistanceFactor = Square(
                        Sqrt(Snowy.MinAirResistanceFactor) +
                        FRand() * (Sqrt(Snowy.MaxAirResistanceFactor) - Sqrt(Snowy.MinAirResistanceFactor)));
Additionally, SnowDrop.FallingDown.Tick should not change the velocity immediately after bouncing (processed by HitWall):

Code: Select all

      event HitWall(vector HitNormal, actor HitWall)
      {
            bHitWall = true;

Code: Select all

      event Tick(float DeltaTime)
      {
            if (Snowy != none && !Snowy.bDeleteMe)
                  WindVelocity = Snowy.WindVelocity;
            if (bHitWall)
                  bHitWall = false;
            else
                  Velocity = class'SnowActor'.static.AdjustVelocity(Velocity + CalcAcceleration() * DeltaTime, Region.Zone);
Anyway, this stuff has a very limited application due to inherent performance issues, and you should pay attention to optimizing such snow effects and maintaining a decent FPS value in case if the client is not capable of rendering so many actors simultaneously.

The first major performance hit is implied by checking intersections of every snow particle with other actors. Doubling the number of particles may result in increasing the number of required checks by ~4 times. For example, if we have 1500 particles, the engine has to check more than 1'124'250 potential intersections between all colliding actors on the map; if we have 3000 particles, the number of potential intersections is greater than 4'498'500, etc. If you don't think that interaction of particles with actors is important, I'd suggest to keep SnowDrop actors with bCollideActors == false. This would allow to use much more particles without huge FPS drops.

Another thing you could do is to reduce the number of simultaneously rendered particles in case if the frame rate went below some threshold. A simple implementation could use something like

Code: Select all

            if (DeltaTime > Level.TimeDilation / MinDesiredFPS && FRand() < 0.1)
                  bHidden = true;
in the SnowDrop's Tick function. MinDesiredFPS can be either a hardcoded value or a value calculated in some sophisticated way. Here's the updated code:

SnowActor.uc
SnowDrop.uc

(of course, the final implementation should use proper textures instead of S_Actor).
Last edited by Masterkent on Sat Sep 16, 2017 1:11 pm, edited 1 time in total.
User avatar
gopostal
OldUnreal Member
Posts: 1005
Joined: Thu Jul 31, 2008 9:29 pm

Re: Online issues with snowfall recycling

Post by gopostal »

Wow...just...wow. This is a blessing to me. Thank you so very much!! I sent you a PM.

I'll post this as a fixed and placeable actor along with a demonstration map, etc. in a few days.

Update: Added rain to this. Looks incredible and works flawlessly.
Last edited by gopostal on Mon Sep 18, 2017 2:13 pm, edited 1 time in total.
I don't want to give the end away
but we're all going to die one day
Post Reply

Return to “UScript Board”