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 Send TopicPrint
Hot Topic (More than 10 Replies) Online issues with snowfall recycling (Read 362 times)
gopostal
Betatester
Offline


Retired

Posts: 726
Joined: Jul 31st, 2008
Gender: Male
Online issues with snowfall recycling
Sep 13th, 2017 at 1:33pm
Print Post  
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:
https://www.youtube.com/watch?v=jFzHcqEViys
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 (C++)
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 (C++)
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<MaxDrops)
   {
      t = Location;
      t.Z-= 20480;
      A = Trace(v,n,t,location,false);
      if (A!=None)
         MaxZ = location.z - a.location.z;
      else
         MaxZ = location.z - 20480;

      for (i=SnowCount;i<MaxDrops;i++)
      {
         Flake = Spawn(class 'SnowDrop',Self,,N);
         if (Flake != None)
         {
            Flake.SetupSnow(Rand(MaxZ));
            SnowCount++;
         }
      }
   }
}

defaultproperties
{
	SpawnHeight=1024
	WindEffect=(X=20.0,Y=20.0,Z=0.0)
   Radius=512.00
   MaxDrops=150.00
   FallSpeedMaximum=128.00
   FallSpeedMinimum=256.00
   bHidden=True
   bAlwaysRelevant=True
   RemoteRole=ROLE_SimulatedProxy
   DrawType=DT_Sprite
   Style=STY_Masked
   Texture=Texture'Snow1'
	bNetTemporary=False
}

 


  

I'm outta here. C ya!
Back to top
 
IP Logged
 
Hyper
Board Moderator
Betatester
*****
Offline


It's Unreal.

Posts: 2873
Joined: Oct 11th, 2002
Re: Online issues with snowfall recycling
Reply #1 - Sep 13th, 2017 at 5:06pm
Print Post  
Must be special snowflakes. Just give them some personalized love and attention and everything will turn out fine.  Wink
  

"Darkness cannot drive out darkness; only light can do that.
Hate cannot drive out hate; only love can do that."

- Martin Luther King, Jr.

http://www.hypercoop.tk
unreal://hypercoop.tk
Back to top
WWW  
IP Logged
 
gopostal
Betatester
Offline


Retired

Posts: 726
Joined: Jul 31st, 2008
Gender: Male
Re: Online issues with snowfall recycling
Reply #2 - Sep 14th, 2017 at 2:39am
Print Post  
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'm outta here. C ya!
Back to top
 
IP Logged
 
Masterkent
Developer Team
Offline



Posts: 864
Location: Russia
Joined: Apr 5th, 2013
Gender: Male
Re: Online issues with snowfall recycling
Reply #3 - Sep 14th, 2017 at 6:05am
Print Post  
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?
  
Back to top
 
IP Logged
 
gopostal
Betatester
Offline


Retired

Posts: 726
Joined: Jul 31st, 2008
Gender: Male
Re: Online issues with snowfall recycling
Reply #4 - Sep 14th, 2017 at 12:00pm
Print Post  
This is a 10 second video of offline play in the same spot:
https://youtu.be/-ZwxTaXROXM

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):
https://youtu.be/xzh-ZdXa0oI

  

I'm outta here. C ya!
Back to top
 
IP Logged
 
Masterkent
Developer Team
Offline



Posts: 864
Location: Russia
Joined: Apr 5th, 2013
Gender: Male
Re: Online issues with snowfall recycling
Reply #5 - Sep 14th, 2017 at 4:59pm
Print Post  
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 Edit: Sep 15th, 2017 at 6:48pm by Masterkent »  
Back to top
 
IP Logged
 
gopostal
Betatester
Offline


Retired

Posts: 726
Joined: Jul 31st, 2008
Gender: Male
Re: Online issues with snowfall recycling
Reply #6 - Sep 14th, 2017 at 5:15pm
Print Post  
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'm outta here. C ya!
Back to top
 
IP Logged
 
Masterkent
Developer Team
Offline



Posts: 864
Location: Russia
Joined: Apr 5th, 2013
Gender: Male
Re: Online issues with snowfall recycling
Reply #7 - Sep 15th, 2017 at 7:46pm
Print Post  
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.
  
Back to top
 
IP Logged
 
gopostal
Betatester
Offline


Retired

Posts: 726
Joined: Jul 31st, 2008
Gender: Male
Re: Online issues with snowfall recycling
Reply #8 - Sep 15th, 2017 at 11:56pm
Print Post  
Masterkent wrote on Sep 15th, 2017 at 7:46pm:
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 Edit: Sep 16th, 2017 at 3:37am by gopostal »  

I'm outta here. C ya!
Back to top
 
IP Logged
 
Masterkent
Developer Team
Offline



Posts: 864
Location: Russia
Joined: Apr 5th, 2013
Gender: Male
Re: Online issues with snowfall recycling
Reply #9 - Sep 16th, 2017 at 1:01pm
Print Post  
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).
  
Back to top
 
IP Logged
 
gopostal
Betatester
Offline


Retired

Posts: 726
Joined: Jul 31st, 2008
Gender: Male
Re: Online issues with snowfall recycling
Reply #10 - Sep 17th, 2017 at 12:50pm
Print Post  
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 Edit: Sep 18th, 2017 at 2:13pm by gopostal »  

I'm outta here. C ya!
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint
Bookmarks: del.icio.us Digg Facebook Google Google+ Linked in reddit StumbleUpon Twitter Yahoo