CanExecuteCosmeticEvents BP macro returns wrong result on dedicated server

We’re trying to use CanExecuteCosmeticEvents BP macro to prevent UMG widgets creation on dedicated server but fail. CanExecuteCosmeticEvents relies on World::GetNetMode() != DedicatedServer. However, World doesn’t know that is it a dedicated server one until it NetDriver is created (though world-creating code knows in advance what kind of world it is creating). It is really important bug because creation of UMG widgets on server results in many errors and even engine crashes.

I think it is a bug of CanExecuteCosmeticEvents. It should instead check if world has a local player or something like that. Also, care should be taken of dedicated server in PIE mode.

While this bug is not fixed, I wonder what is proper check for “should UMG widgets be created in current world or not”?

Hey Slonopotamus,

Currently there is no way to prevent UMG from being pulled into a dedicated server. Check this answer and see if it answers your questions:

According to Epic’s comment on my pull request here on Github, it looks like there’ll be some incoming changes (possibly to 4.6) that should alleviate issue somewhat.

In meantime you could always use a ‘switch has authority’ node which allows you to detect if current BP is executing server-side. My students are currently using this to avoid opening user widgets on server, though as points out this doesn’t prevent UMG module being present.

So to clarify, your use case is actually one where we may either be playing with or without a server at all, ie sometimes a client might have authority? I misunderstood you to mean that you always had a server.

Generally speaking cosmetic events require a viewport - this is what is causing UMG nodes to crash on a server, because a server has no viewport, at least in my own use case. Checking for a valid viewport could be a way to get functionality you require - there’s no GetViewport exposed to blueprint at present from what I can see, but you could fairly easily add it to PlayerController or similar though.

Usage of ‘switch has authority’ is incorrect, it will disable UMG on host client when no dedicated server is involved.

“Cosmetic events” is definitely a broader thing than just UMG. So even if UMG is fixed to automagically become noop on dedicated server, we still need a way to distinguish a world that user observes from a headless world. So no, I still claim CanExecuteCosmeticEvents macro is broken and needs to be fixed.

I’d like to make all modes work: both a headless dedicated server and a first-player-is-a-server mode. ‘switch has authority’ is enough for former but is incorrect for latter case.

Thanks for hint. I found UWorld::GetGameViewport (that’s what UserWidget::AddToViewport uses. GetGameViewport() == nullptr looks like a good check for UKismetSystemLibrary::IsDedicatedServer.

Thanks for reporting this, we will investigate fixing GetNetMode to return actual net mode earlier in startup process.

You can work around this issue by delaying creation of your UMG widgets until CanExecuteCosmeticEvents can return correct value. When I tested this locally, it was correctly returning false during GameMode PostLogin event. It also works during BeginPlay events, but there is a known issue where an actor’s Role and RemoteRole are not set until after BeginPlay. This means that functions like HasAuthority will not work as expected if called from within BeginPlay events.

So for now, I would recommend moving your UMG widget creation logic to PostLogin event.

Bug was fixed in commit 74378df5 (included in UE 4.6).