dormant deactivate should be PostBeginPlay?

Bugs that have been investigated and resolved somehow.

Moderator: GZDoom Developers

Forum rules
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.
Post Reply
User avatar
Sir Robin
Posts: 537
Joined: Wed Dec 22, 2021 7:02 pm
Graphics Processor: Intel (Modern GZDoom)
Location: Medellin, Colombia

dormant deactivate should be PostBeginPlay?

Post by Sir Robin »

I created a switchable decoration. It needs to stay synchronized with other switchable decorations, so it's activate() and deactivate() methods call level.executespecial() to activate and deactivate it's "child" associations. I want it to start out deactivated, so I give it the dormant flag. Probelm is that when the level loads, not all decorations are synchronized - some of it's children are dormant, while others are not. Some troubleshooting has led me to believe that internally there is a if (bDormant) Deactivate(null) line called in BeginPlay(). The reason my decorations are out of sync is that some of the children aren't loaded/placed on the map when the BeginPlay() executes, so they're not getting the deactivate() call.

My suggestion is to move that call from BeginPlay() to PostBeginPlay(). Or would that break other things?

The workaround is obviously simple, I don't use the bDormant bolean, I create my own called inactive, and throw a if (inactive) deactivate(null) into PostBeginPlay()
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49225
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: dormant deactivate should be PostBeginPlay?

Post by Graf Zahl »

Please post a piece of demonstration. This is too abstract for a bug report.
User avatar
Sir Robin
Posts: 537
Joined: Wed Dec 22, 2021 7:02 pm
Graphics Processor: Intel (Modern GZDoom)
Location: Medellin, Colombia

Re: dormant deactivate should be PostBeginPlay?

Post by Sir Robin »

Excuse me, let me simplify. Consider this code:

Code: Select all

class SwitchedMaster : actor
{
	default
	{
		//$Arg0 Child TID
		//$Arg0Type 14
		+Dormant;
	}
	
	override void deactivate(actor activator)
	{
		console.printf("["..level.time.."]["..GetCharacterName().."] Deactivated by "..(activator ? activator.GetCharacterName() : "[NULL]"));
		Level.ExecuteSpecial(131, activator, null, false, args[0], 0, 0, 0, 0);
	}
}

class SwitchedChild : actor
{
	override void deactivate(actor activator)
	{
		console.printf("["..level.time.."]["..GetCharacterName().."] Deactivated by "..(activator ? activator.GetCharacterName() : "[NULL]"));
	}
}
Create a new map, with player 1 start
Place a child, set TID 1
Place a master, set arg0 1
Place another child, set TID 1
run the map

master is dormant, so the deactivate fires immediately, tic 0
special "deactivate thing" is called for TID 1
One child reports deactivation
The other child never does
I believe because the master deactivation was fired before the second child was loaded in the map.
Therefore my conslusion is that the dormant deactivation is called from BeginPlay instead of PostBeginPlay
My suggestion is to move it into PostBeginPlay
Professor Hastig
Posts: 256
Joined: Mon Jan 09, 2023 2:02 am
Graphics Processor: nVidia (Modern GZDoom)

Re: dormant deactivate should be PostBeginPlay?

Post by Professor Hastig »

Sir Robin wrote: Tue Oct 10, 2023 6:42 pm I believe because the master deactivation was fired before the second child was loaded in the map.
Therefore my conslusion is that the dormant deactivation is called from BeginPlay instead of PostBeginPlay
My suggestion is to move it into PostBeginPlay
Instead of changing the engine, how about changing your setup?
You are correct about order of calls, so you simply cannot do it this way. You should override PostBeginPlay yourself and in there do the necessary things based on the master's state.
What you are doing here looks like an edge case that isn't worth sacrificing established behavior.
User avatar
Sir Robin
Posts: 537
Joined: Wed Dec 22, 2021 7:02 pm
Graphics Processor: Intel (Modern GZDoom)
Location: Medellin, Colombia

Re: dormant deactivate should be PostBeginPlay?

Post by Sir Robin »

That's why I posted it as a question - Is this behaviour undesired? If so is it worth fixing? If so does it break other established behaivor? Those are questions for the dev team, above my paygrade, I'm just bringing the quirk to their attention.

Yes I can work around this quirk, as mentioned in my original post. I'm posting here in the hopes that someone else who finds this quirk, assuming that it is not changed in the engine, will be able to search and find this thread and not spend the time trying to figure out why their code isn't working.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49225
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: dormant deactivate should be PostBeginPlay?

Post by Graf Zahl »

Since you found out yourself why your setup doesn't work it should be obvious that you have to find an alternative approach.
The initial deactivate call runs at a time when not all actors are present so you cannot use it to do stuff that affects other actors.
No, I won't consider changing this. Who knows how many mods depend on these actors starting fully deactivated that may break by the change?
Post Reply

Return to “Closed Bugs [GZDoom]”