[Bug-Critical][Reproducible] Any Level Blueprint Multicasts with any Params Crash Unreal 4.16

Level Blueprints can no longer make any Multicast calls with any parameters in 4.16. Doing so will crash the engine in the following way:

Steps to reproduce from Blank Project:

1: Create a new empty 4.16 project with 2 levels. Call them LevelA and LevelB.

2: In LevelA, create a level blueprint that calls a reliable Multicast elsewhere in the same Level Blueprint. Make sure the Multicast has a parameter.

3: Enable Seamless Travel (Subclass the GameMode with a TestGameMode class with Seamless travel set to True. Make sure the Maps & Modes in the project settings are set to use your new custom game mode).

191242-seamless.png

TO REPRODUCE CRASH:

  1. Package this project
  2. On the server computer run console command: open LevelB?listen
  3. Have a remote client connect and join the game (i.e. open the IP address of the server)
  4. With the remote client connected, go back to your server computer use the console command: Servertravel LevelA
  5. Trigger the multicast call in the LevelA’s Level blueprint (in the example above, you press ‘H’). At this point LevelA is now ticking time-bomb ready to crash the engine.
  6. ServerTravel back to LevelB
  7. ServerTravel back to LevelA

If the multicast call was made on the server in the Level Blueprint (step 5), it should now hard-crash to desktop with the following error in the Log:

[206]LogWindows:Error: === Critical error: ===
[206]LogWindows:Error: 
[206]LogWindows:Error: Fatal error: [File:D:\Build\++UE4+Release-4.16+Compile\Sync\Engine\Source\Runtime\CoreUObject\Private\Serialization\AsyncLoading.cpp] [Line: 5431] 
[206]LogWindows:Error: Package /Game/LevelA was reloaded before it even closed the linker from a previous load. Seems like a waste of time eh?

Note:

  • For the crash to occur, the Multicast
    must have a parameter. The data-type
    of the parameter doesn’t seem to
    matter, and it doesn’t matter if you
    actually use it.
  • There must be at least 1 remote client connected for the bug to present itself
  • It doesn’t seem to matter what the multicast actually does (I just put debug text there to highlight the next point:)

It Gets Worse: Level Streaming Also Broken

This exact same issue also breaks Level Streaming, but in different, weird way: For example, in the case above you could Stream in LevelA (through blueprint nodes), trigger the multicast, unload LevelA, and then stream in LevelA again. Rather than crashing this time, a rather bizarre broken state is reached: LevelA will stream-in just fine, but all direct references to objects in the Level Blueprint (like the PlayerStart) in the example above will fail. The log will be filled with Warnings that it failed to find these objects, and all scripts will treat these objects as though they are all replaced with None. In most cases, this basically renders the Level Blueprint completely useless as it will fail to obtain a proper reference to any object in the Level. This almost deserves its own separate bug report to fully explain, but the cause is exactly the same, so it’s likely the same Engine bug just manifesting in a new way.

Related:

It’s possible this bug is the root cause of (or perhaps related to) a few other issues people have reported
[here][3] or
[here][4] or maybe even [here][5]

Sadly, my multiplayer game uses a lot of Level-streaming and Seamless ServerTravel. We’re having to hunt down and rip out any Level Blueprints that have a Multicast call with a parameter, and move them into replicated dummy actors. Needless to say, it’s kind of a disaster.

Hey nrosool,

Just wanted to update to let you know I’m aware of this thread and I’ll be looking into this soon.

Thank you for your patience

I’ve spent some time testing this, but I’m not seeing the same results on my end. It could be that I’m overlooking something. Would you mind providing a simplified test project that I could use to reproduce the issue?

Thanks

Sure, here’s a youtube video showing the steps above, and how they crash a packaged build:

Here’s a link to the packaged build used in the video:
https://drive.google.com/file/d/0B9BDRta7KXq2VktYU2wyLUYyWDA/view?usp=sharing
***NOTE: There is a remote client connecting over LAN at 0:35, (the bug requires at least one remote client connected). You can press ‘H’ on LevelA to trigger the multicast that will prepare the map for crashing.

A the bug can also be reproduced in the editor. Here is the Unreal Editor Project that produced the packaged build above:
https://drive.google.com/file/d/0B9BDRta7KXq2ZUpPVkpOYTI4V0E/view?usp=sharing

Here is a youtube video showing how to cause this bug in the Unreal Editor:

Note at the end of the video, the bug has caused all direct object references in the Level Blueprint to break, which is why it is printing “None” at that point, effectively rendering the Level Blueprint unusable.

Thanks for your patience, I’ve reproduced the issue and have entered a bug report, which you can track using the link below:

Have a great day

Thanks for sticking with it. I can also confirm that as a short-term work-around people can try to move any multicast calls (with parameters) from the level blueprint to a replicated actor that sits in the level instead (at a small performance cost). This worked for us.

Alternatively, disabling Seamless Travel in the game mode appears to avoid the issue for ServerTravelling (Blueprint level streaming remains broken). Although, as expected, this means it takes longer to load in the new level, and there are a lot of stutters and hiccups on the client as the server ServerTravels non-seamlessly.

I’m having an issue with the same symptoms ( async travel from levelA → levelB → levelA causes this error). Unfortunately, multicast events in the level blueprints do not seem to be the cause. I’ve tried stripping out all functionality from level blueprints, same issue.

The exact issue is in engine/source/runtime/coreuobject/private/serialization/AsyncLoading.cpp – basically, when we fast travel, the old level is not being “unloaded”. I’m trying to figure out where/when this all happens and seeing if I can maybe unload it explicitly. This is a pretty frustrating and game breaking bug. Turning off EventDrivenLoader breaks my game in other ways.

EDIT: Ok, I finally got it… Not an ideal fix, but it works… I edited AsyncLoading.cpp at the line where it was crashing. Basically, there’s a line where it says “Linker = FLinkerLoad::FindExistingLinkerForPackage(Package)” It complains if this linker exists. So if it exists, simply call “Linker->Detach()” to unregister it. Then comment out the block that checks with “if (Linker && GEventDrivenLoaderEnabled)” and comment the whole block out. And change “if (!Linker)” to “if(true)” to ensure that it always creates a new Loader.

Total hack, but at this point I’ll take it. It’s a bug though – there should be some code somewhere that unloaded the level already so traveling levelA->levelB->levelA doesn’t crash. As it is, it basically says “something is wrong!” and crashes when simply reloading the asset seems like a better solution even if it is wasteful. It wouldn’t need to be wasteful if the level was properly unloaded in the first place. FWIW.