[No] WorldThing Event Disabling Flags

Moderator: GZDoom Developers

WorldThing Event Disabling Flags

Postby Major Cooke » Tue Apr 10, 2018 10:19 am

Pull Request

This solves an issue where a potentially complex WorldThing* event could be called for potentially LOTS of actors at once, causing one hell of a notable dip in FPS. For example, AEons of Death has directors -- the Left 4 Dead director in particular at any time could spawn 100-600 zombies if a horde is suddenly unleashed. This horde of common infected, if blasted with a big enough explosion, could kill them all at once, and each one spawns ~4-8 gibs at once. THOUSANDS of spawned actors in an instant.

Giving the gibs NOEVENTSPAWN and NOEVENTDESTROY worked extremely well at preventing that lag spike, along with all of the special effects that would have nothing to do with the gameplay otherwise.

And lets not forget, more than one event handler can be present, especially if addons are loaded.

There are 5 in total, all prefixed with NOEVENT:
  • SPAWN
  • DEATH
  • DAMAGE
  • REVIVE
  • DESTROY

The revive flag will also be checked before having it's flags reset (and on that note, I noticed that flags8 was not in the revival code and fixed it).

I also do not believe they should be merged into one flag at all. Some events may still be desired while others are exempt from calling.
User avatar
Major Cooke
Do unto others as you would have unto you. Judge yourself first.
 
Joined: 28 Jan 2007

Re: WorldThing Event Disabling Flags

Postby Graf Zahl » Tue Apr 10, 2018 12:18 pm

I hope this doesn't end up like the pain stuff with exceptions of exceptions of exceptions. Wanna bet that some people will request an override? And wanna bet that some people will use this as a means to outmaneuver mods that use event handlers?

Therefore I'd like to hear a second opinion first.
User avatar
Graf Zahl
Lead GZDoom Developer
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: WorldThing Event Disabling Flags

Postby Major Cooke » Tue Apr 10, 2018 12:52 pm

Making further exceptions is not only unneeded, it's utterly pointless. One can just do this:
Code: Select allExpand view
let event = SomeEventHandler(EventHandler.Find("SomeEventHandler"));

and then call a function in the handler if they need it. Or ultimately, they can just remove, say, the NOEVENTSPAWN flag in BeginPlay based on conditions.

And I have no further plans dealing with events after this submission. This is simply it, because calling this every single time something is destroyed:

Code: Select allExpand view
    override void WorldThingDestroyed(WorldEvent e)
    {
        Actor mo = e.Thing;
       
        if (mo.bNOINTERACTION || mo.bMISSILE || mo.bNOSECTOR ||
            mo is "AEoDMonsterSpawner" || mo is "DirectorBase")   
            return;
        if (mo is "SpecialMonsterBase")
        {
            if (Spec.Size())
            {
                int size = Spec.Size();
                int pos = Spec.Find(mo);
                if (pos < size)            Spec.Delete(pos);
            }
        }
        else if (mo.bISMONSTER || mo.bCORPSE)
        {
            if (Monsters.Size())
            {
                int size = Monsters.Size();
                int pos = Monsters.Find(mo);   
                if (pos < size)            Monsters.Delete(pos);
            }
        }
        else if (mo is "Inventory")
        {
            if (Absorbables.Size())
            {
                int size = Absorbables.Size();
                int pos = Absorbables.Find(mo);   
                if (pos < size)            Absorbables.Delete(pos);
            }
        }
    }


...absolutely dropkicks performance. Especially if there's more than one event handler or WorldThingSpawned is done, or both!
User avatar
Major Cooke
Do unto others as you would have unto you. Judge yourself first.
 
Joined: 28 Jan 2007

Re: WorldThing Event Disabling Flags

Postby Gutawer » Tue Apr 10, 2018 1:14 pm

I'm very much not a fan of this. Part of the reason why these events are useful at all is because they are guaranteed to happen when they need to, so mod behaviour can rely on things being properly set up by these events. If an actor can just disable certain events from occurring because it causes lag (which, I would consider a fault of the mod itself, not the event handler system), then that guarantee is lost and modding becomes a lot trickier for stuff that needs to 100% happen. To me, this would seem like a feature suggestion to disable ENTER scripts for certain player classes, which would obviously break map behaviour in many places, and I'd consider this to have the same harmful effect.
User avatar
Gutawer
User Accounts Assistant
 
Joined: 16 Apr 2016
Discord: Gutawer#3431

Re: WorldThing Event Disabling Flags

Postby ZZYZX » Tue Apr 10, 2018 1:15 pm

I don't like this.

Quote from Discord

[9:12 PM] ZZYZX: WorldThing events are created so that custom mods can do stuff to arbitrary other mods
[9:12 PM] ZZYZX: In an universal way
[9:12 PM] ZZYZX: What you propose will cause things like
[9:12 PM] ZZYZX: mymod.pk3 and mymod_aeod_compat_patch.pk3
[9:13 PM] ZZYZX: Because inheritance is not possible when the parent actor is not defined... which means the inheritance patch cannot be loaded by default
[9:13 PM] ZZYZX: Which basically breaks the whole point of having an event handler
[9:13 PM] ZZYZX: So please find another reason why it lags and don't do this


Please provide minimal example of laggy code so that it can be debugged. I don't understand why 500*4 "if..return" calls in a tic should bring FPS to zero.
User avatar
ZZYZX
le chat du rabbin
 
 
 
Joined: 14 Oct 2012
Location: Ukraine

Re: WorldThing Event Disabling Flags

Postby Major Cooke » Tue Apr 10, 2018 1:38 pm

I'll make one.

But in the mean time, perhaps a blacklist/whitelist approach like inventory items have Forbidden/RestrictedTo would be better.
User avatar
Major Cooke
Do unto others as you would have unto you. Judge yourself first.
 
Joined: 28 Jan 2007

Re: WorldThing Event Disabling Flags

Postby Graf Zahl » Tue Apr 10, 2018 1:42 pm

ZZYZX wrote:I don't understand why 500*4 "if..return" calls in a tic should bring FPS to zero.


They probably don't. But executing 500 event handlers can surely have a devastating impact. Major Cooke is correct about one thing: If these events are being called on every chunk of debris that gets spawned, destroyed or mutilated they surely will kill performance quite efficiently.
User avatar
Graf Zahl
Lead GZDoom Developer
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: WorldThing Event Disabling Flags

Postby Major Cooke » Tue Apr 10, 2018 1:48 pm

Well, more like 2 event handlers where WorldThingSpawned and WorldThingDestroyed are both called so that quickly adds up.

So I'm wondering if perhaps a blacklist approach similar to Forbidden/RestrictedTo would do the trick?

And yes, it is being called on everything that spawns and destroys.
User avatar
Major Cooke
Do unto others as you would have unto you. Judge yourself first.
 
Joined: 28 Jan 2007

Re: WorldThing Event Disabling Flags

Postby ZZYZX » Tue Apr 10, 2018 1:53 pm

This script creates 5000 actors all of which are registered by two handlers (verified using counter). Does not lag.
Each actor spawns, waits for 1 tick, spawns more actors and dies. First 500 are spawned (by summon testactor), then each of these spawns 10 more.

I also bound "summon testactor" to a key and could not produce any noticeable FPS drop by spamming that key.

FPS drop only becomes apparent when I crank the first number up to 5000 (5000 then each spawns 10), but that's... not very good either way. nuts.wad is not recommended.

Expected log (from 5000) looks like this: https://i.imgur.com/Qta3Puk.png

This is to back my point that I don't understand why it should lag. It does almost nothing if the first thing in the function is "if actor should not be handled".
Attachments
testhandlers.pk3
(828 Bytes) Downloaded 35 times
User avatar
ZZYZX
le chat du rabbin
 
 
 
Joined: 14 Oct 2012
Location: Ukraine

Re: WorldThing Event Disabling Flags

Postby Major Cooke » Tue Apr 10, 2018 2:14 pm

I'll be more specific: the lag comes from the compounding dual event handlers spawning and destroying calls happening. And specifically, I'm recording them to an array of interactable entities.

Whenever they're spawned, they're pushed to an array in ONE event handler:

Code: Select allExpand view
Array<Actor> FX;
Array<SpecialMons> Spec;
Array<Actor> Monsters;
Array<Inventory> Absorbables;

override void WorldThingSpawned(WorldEvent e)
{
   Actor mo = e.Thing;
   if (!mo || mo.bNOINTERACTION || mo.bNOBLOCKMAP || mo.bNOSECTOR ||
      mo is "AEoDMonsterSpawner" || mo is "DirectorBase")
   {
      return;
   }
   if (mo.bISMONSTER || mo.bCORPSE)
   {
      if (mo is "SpecialMonsterBase")
      {
         let SpecialMon = SpecialMonsterBase(mo);
         if (SpecialMon)
         {
            SpecialMon.Tracker = self;
            Spec.Push(SpecialMon);
         }
      }
      else if (Spec.Size())   Monsters.Push(mo);
   }
   else if (mo is "Inventory" && mo.species == 'Absorbable')
   {
      Absorbables.Push(mo);
   }
   else if (mo is "PlayerPawn" && Spec.Size())
   {
      Monsters.Push(mo);
   }
}


While another does this:
Code: Select allExpand view
override void WorldThingSpawned(WorldEvent e)
{
   if (DemonMorph)
   {
      Actor mo = e.Thing;
      if (!mo || mo.bNOINTERACTION || mo is "DirectorBase")   return;
      if (mo.bISMONSTER && mo.health > 0)
      {
         mo.A_GiveInventory("DemonMorphTranslationItem", 1);
      }
   }
}


...Hmm, I think the culprit might be the array functions...
User avatar
Major Cooke
Do unto others as you would have unto you. Judge yourself first.
 
Joined: 28 Jan 2007

Re: WorldThing Event Disabling Flags

Postby Graf Zahl » Tue Apr 10, 2018 2:27 pm

The culprit is that you actually *DO* something in your handler. Of course, with a nearly empty handler the impact will be considerably less severe.
User avatar
Graf Zahl
Lead GZDoom Developer
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: WorldThing Event Disabling Flags

Postby ZZYZX » Tue Apr 10, 2018 2:37 pm

Ok, I added array access, it now reads/writes all secondary actors to an array. Logs array size of 5000. Still no lag. I didn't measure exact millisecond timing but by FPS counter it takes approximately 10-17ms on the "hard" frames.

So while overall I understand that this might be caused by lag accumulation in AEoD (due to AEoD being complex enough for lag accumulation to be possible), but I don't think this is an event handlers problem.

upd: I'll try to hack the full AEoD version of this code tomorrow once I'm a bit more awake. Will know what's wrong better at that point. I hope I provided enough evidence that it's not as simple as event handlers being laggy here so that it doesn't get changed until more is known :P
Attachments
testhandlers.pk3
(915 Bytes) Downloaded 35 times
Last edited by ZZYZX on Tue Apr 10, 2018 3:08 pm, edited 2 times in total.
User avatar
ZZYZX
le chat du rabbin
 
 
 
Joined: 14 Oct 2012
Location: Ukraine

Re: WorldThing Event Disabling Flags

Postby Major Cooke » Tue Apr 10, 2018 3:42 pm

The thing about AEoD is, it's very hands on about the effects in game.

There can be a TON of effects too, but that doesn't cause the same notable amount of lag as including the event handlers on top of it. And those spawn/destroy functions are called on every actor that spawns.

Which is why I now propose a blacklist/whitelist approach for actors.

Code: Select allExpand view
BlacklistHandler "Handler1", "Handler2", ...;


Or blacklisting which handler's functions are allowed to trigger:

Code: Select allExpand view
BlacklistHandlerSpawn "Handler1", ...;


Thoughts? Ideas?
User avatar
Major Cooke
Do unto others as you would have unto you. Judge yourself first.
 
Joined: 28 Jan 2007

Re: WorldThing Event Disabling Flags

Postby Graf Zahl » Tue Apr 10, 2018 4:10 pm

I'm sorry but that's not going to happen. Seriously, the only solution here can be: Do not use event handlers if you spawn tons of stuff.

In retrospect I have to say that it was a stupid idea to have an event handler being unconditionally called whenever ANY actor gets spawned. This should have been restricted from the start to 'important' actors like monsters and inventory stuff and for the test been purely opt-in.
User avatar
Graf Zahl
Lead GZDoom Developer
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: WorldThing Event Disabling Flags

Postby Major Cooke » Tue Apr 10, 2018 5:48 pm

I agree that it being an opt-in would have been nice, but limiting it to just important actors would have only hurt creativity, resorting to hacks. A_RadiusGive certainly taught me that.
User avatar
Major Cooke
Do unto others as you would have unto you. Judge yourself first.
 
Joined: 28 Jan 2007

Next

Return to Closed Feature Suggestions

Who is online

Users browsing this forum: No registered users and 1 guest