Understanding Unreal Engine’s DORM_Initial dormancy setting
This article is a collaboration with WizardCell and on it, you’ll learn how DORM_Initial works and why you should be careful with it.
Introduction
If we read the description of the DORM_Initial dormancy setting, we see what follows:
This actor is initially dormant for all connection if it was placed in map.
Which made me understand that this setting would work like DORM_DormantAll just with a couple extra optimizations. But it isn’t the case, let’s see what are the implications of using this setting.
DORM_DormantAll versus DORM_Initial
When an Actor becomes relevant to a connection, all the properties of said Actor are sent to the connection, no matter whether the Actor is DORM_DormantAll or DORM_Awake. That means that the state the client receives from the Actor will be consistent of what the server sees about it.
However, that is not the case of DORM_Initial Actors, as they will not send any C++ replicated property if a connection becomes relevant:

Watch out! Blueprint replicated properties ignore Actor dormancy settings.
How to use DORM_Initial
So shall I simply not use DORM_Initial? No, you should! DORM_Initial Actors won’t be considered for replication at all even under relevancy, and sometimes that can be a huge optimization.
To ensure incoming connections get the new values over DORM_Initial Actors, you should call FlushNetDormancy on them before updating their properties. This will make the Actor to become DORM_DormantAll but only when strictly needed.

What about calling ForceNetUpdate to also flush the dormancy?
Be very careful with this, as ForceNetUpdate also calls FlushNetDormancy but its guarded with a NetDriver check:
void AActor::ForceNetUpdate()
{
...
if (GetLocalRole() == ROLE_Authority)
{
// ForceNetUpdate on the game net driver only if we are the authority...
if (NetDriver && NetDriver->GetNetMode() < ENetMode::NM_Client) // ... and not a client
{
NetDriver->ForceNetUpdate(this);
if (NetDormancy > DORM_Awake)
{
FlushNetDormancy();
}
}
}
...
}So, if the NetDriver is Null at the moment you call ForceNetUpdate*, the Actor will never call FlushNetDormancy, causing it to stay in a DORM_Initial state. For that reason it is always recommended to explicitly call FlushNetDormancy when dealing with DORM_Initial Actors.
*Worlds don’t get a NetDriver until UWorld::Listen is called.
Conclusion
Thanks for reading!
Let’s hope everything is clear! Feel free to reach us out if there are questions! And I encourage every reader to check WizardCell’s articles.
If you want to know more about Dormancy, visit Epic’s official documentation!
Enjoy, WizardCell and vori.