Should I fix this error?

Discussions about Coding and Scripting
Post Reply
MrLoathsome
Inhuman
Posts: 958
Joined: Wed Mar 31, 2010 9:02 pm
Personal rank: I am quite rank.
Location: MrLoathsome fell out of the world!

Should I fix this error?

Post by MrLoathsome »

2 weeks ago me and Dr-Flay were discussing various ideas of things that might be made to happen via decals/scorchmarks.
(Most of which won't happen without a custom class.... Will look at that later.)

While we were bouncing ideas around, I took a look at the source code for the original DecalStay Mod by Mongo.
From Nov. 1999. Probably the 1st 3rd party mod I ever installed.

The original DecalStay runs off a tick via Mod Menu item, and runs client-side only. Works while playing online or offline with everything.
It only acts on 14 of the default UT99 scorch marks. It copies them. Respawns custom replacements. Destroys the original scorch.

While looking at it, I noticed I could make that happen with just a few lines of code. Without spawning or destroying anything.
And have it work with ALL scorch marks.
(2 or 3 lines not including basic overhead to make it a mutator or Mod Menu item...)

Now I have that working as either a Mod Menu item like the original, and a 2nd version, that runs as a mutator, and will run
on a server.

My question is regarding something I noticed while testing the mutator/server version of it.

Had a log file line in the code, to make sure my replication was working, and that things were working as I wanted on client and server.

And this shows up in the logs. Botpack.WallCrack is spawning on both the dedicated server and the client.
Botpack.WallCrack is a tiny Scorch/Decal that gets spawned by Ripper Primary fire when they hit the wall, and probably a few other classes.
In testing on a dedicated FoodFight server, I get the same thing for the BeanSplat decal. (Canopener primary)
But none of the other cool FF decals.

No other scorchmarks are showing up on the dedicated server. I can't think of any reason that they should. (If anybody knows of one, please tell me....)
These scorch classes items should only be spawning on the client.
This has to be an error in those classes or the projectile classes that are spawning them.

My question: Should I have my mutator destroy those items on the server? (It only takes 1 additional line in the code...)
Testing that on 2 of my servers currently, and nothing bad seems to happen. WallCracks and BeanSplats still spawn fine
on the client.

The current full source for my mutator version of this thing is so small, here it is in its entirety so you can see exactly what I mean:

Class 1. DsMut Mutator:

Code: Select all

//----------------------------------------------------------------------------------------------------//
//  DecalStayPlus.  Mutator Version  An Update to Mongo's DecalStay Mod by MrLoathsome.    5/12/2018  //
//----------------------------------------------------------------------------------------------------//

class DsMut extends Mutator config(DSP_Mut);

var() config float TimeMultiplier;
var() config int MaxDecals;

simulated function PostBeginPlay()
{
	Super.PostBeginPlay();
	Spawn(class'MyWatcher');
}

defaultproperties
{
     TimeMultiplier=60.0
     MaxDecals=2000
}
Class 2. MyWatcher:

Code: Select all

class MyWatcher expands SpawnNotify;

var float TM;
var int MaxDecals, DecalCount, K;

replication
{
	// Variables the server should send to the client.
	reliable if( Role==ROLE_Authority )
		TM, MaxDecals;
}

simulated function PostBeginPlay()
{
	Super.PostBeginPlay();
	TM = class'DsMut'.default.TimeMultiplier;
	MaxDecals = class'DsMut'.default.MaxDecals;
}

simulated function CountDecals()
{
	local Scorch S;

	DecalCount = 0;

	foreach Level.allactors(class'Scorch', S) DecalCount++;
}

simulated event actor SpawnNotification(actor A)
{
	if (Scorch(A) == None)
		return A;

//Log(Self@A);

if (Level.NetMode == NM_DedicatedServer) A.Destroy();

	K++;
	if (K > 60)  // Only update the DecalCount once every 60 scorchmarks spawned
	{
		k = 0;
		CountDecals();
	}
	if (TM == 0)
		{
			A.Disable('Timer');
			A.Lifespan = 0.0;
		}
	else if (DecalCount < MaxDecals)
		{
			A.SetTimer(TM, false);
			A.Lifespan = 0.0;
		}
	return A;
}

defaultproperties
{
}
I have the log file line there in SpawnNotification commented out atm.
Above version does destroy the Scorches if they are spawning on the dedicated server.

Other option I was testing just ignores the server-side scorch actors, but excludes them from any adjustments.

Let me know if you have any opinions on that. Or if you notice anything I am doing wrong with the replication or other code.
(Anything left out that should be there, anything I am doing that doesn't need to be done etc...)

Hope to be posting both versions of this new DecalStayPlus thing here soon.

*Edit. Adjustment to CountDecals function....
**Edit 2. Just noticed while re-reading the post. I used Extends in one class, and Expands for the other. Damn I am old. LOL
blarg
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: Should I fix this error?

Post by Higor »

On non-XCGE servers the damage is already done by spawning the decal. (and using up one additional name)
But thanks for the report, should be easy to handle using XCGE's script patcher.
User avatar
Feralidragon
Godlike
Posts: 5489
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: Should I fix this error?

Post by Feralidragon »

Well, from an Actor standpoint, in the case of the Ripper for example, nothing really prevents a Botpack.WallCrack actor from being spawned on both the client and server, since it's being spawned from a simulated HitWall function which runs on both the server and client at the same time, and it has no condition set to prevent it from spawning in the server.
Clearly an oversight from Epic.

Other projectiles generally use the ExplosionDecal property to set the decal class the projectile is meant to spawn upon impact against a wall, which in the Projectile class is actively being prevented from being spawned in the server, as you can see here:

Code: Select all

simulated function HitWall (vector HitNormal, actor Wall)
{
    if ( Role == ROLE_Authority )
    {
        if ( (Mover(Wall) != None) && Mover(Wall).bDamageTriggered )
            Wall.TakeDamage( Damage, instigator, Location, MomentumTransfer * Normal(Velocity), '');

        MakeNoise(1.0);
    }
    Explode(Location + ExploWallOut * HitNormal, HitNormal);
    if ( (ExplosionDecal != None) && (Level.NetMode != NM_DedicatedServer) )
        Spawn(ExplosionDecal,self,,Location, rotator(HitNormal));
}


Having that said however, I used decals quite heavily in NW3 for instance, and although many years have passed, I remember that I actually experimented with spawning decals in the server side on purpose early during its developed, to try to check if I could get the BSP surface textures from the server.
However, as far as I remember (although my memory may not be accurate) was that the return of a spawn of a decal class in a server was always None.

I couldn't even get a decal instance, let alone make the trace and attach it to a BSP server, the engine wouldn't let me.
The same happens if decals are disabled in the client, so if clients have their decals disabled, some effects become disabled or watered down in some sense in my mod.

However, the fact that you are able to log them with a SpawnNotify class (for my surprise), leads me to believe that the engine itself doesn't prevent them from spawning at all, it just destroys them before being returned, which seems highly inefficient, and weird overall.

So maybe, what you're doing there by destroying the server-side decals is probably redundant (but it's been many years since I looked into this as well, so I could be completely wrong somewhere here).
MrLoathsome
Inhuman
Posts: 958
Joined: Wed Mar 31, 2010 9:02 pm
Personal rank: I am quite rank.
Location: MrLoathsome fell out of the world!

Re: Should I fix this error?

Post by MrLoathsome »

Yes. It is indeed an odd issue.

I will have the final of my thing just skip any action on the ones
spawned serverside.

Let the server kill them in its own special way.

Even if it doesn't, the timers on them expire before too long anyway.
(I think, unless the server keeps looking at them. :mrgreen: )
blarg
Post Reply