Page 1 of 1
dormant deactivate should be PostBeginPlay?
Posted: Tue Oct 10, 2023 6:39 am
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()
Re: dormant deactivate should be PostBeginPlay?
Posted: Tue Oct 10, 2023 10:36 am
by Graf Zahl
Please post a piece of demonstration. This is too abstract for a bug report.
Re: dormant deactivate should be PostBeginPlay?
Posted: Tue Oct 10, 2023 6:42 pm
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
Re: dormant deactivate should be PostBeginPlay?
Posted: Wed Oct 11, 2023 3:02 am
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.
Re: dormant deactivate should be PostBeginPlay?
Posted: Thu Oct 12, 2023 8:48 am
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.
Re: dormant deactivate should be PostBeginPlay?
Posted: Thu Oct 12, 2023 10:17 am
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?