Download

(SOLVED) Messaging System with FMessageEndpoint doesn't work in Shipping Build

I’m making a simple UE4 C++ project that tests UE4’s messaging system and it doesn’t work in the shipping build. It works on the developer build and the editor though.
Some extra details: I tried this in both 4.24 and 4.25 and it doesn’t work with either of them.

I’ve found this problem easy to reproduce so if you want to try it yourself, simply create a new C++ project and add the code below for your C++ game mode class (and set it as the default game mode). here is the complete code for MyGameModeBase.h and MyGameModeBase.cpp:

MyGameModeBase.h:


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "MyGameModeBase.generated.h"

class FMessageEndpoint;
class IMessageContext;

USTRUCT()
struct FEventCustom
{
    GENERATED_USTRUCT_BODY()
};

/**
 *
 */
UCLASS()
class MYPROJECT2_API AMyGameModeBase : public AGameModeBase
{
    GENERATED_BODY()

public:
    AMyGameModeBase();

    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

    // Called every frame
    virtual void Tick(float DeltaTime) override;


private:
    // Messaging system callbacks:
    void HandleEventCustom(const FEventCustom& Message,
        const TSharedRef<IMessageContext, ESPMode::ThreadSafe>& Context);


    // Variables:

    // The message endpoints for sending and receiving messages.
    TSharedPtr<FMessageEndpoint, ESPMode::ThreadSafe> MessageEndPointEventCustom;
};



MyGameModeBase.cpp


// Fill out your copyright notice in the Description page of Project Settings.


#include "MyGameModeBase.h"

// For the messaging system.
#include "MessageEndpoint.h"
#include "MessageEndpointBuilder.h"

// For error messages for the user to see.
#include "Misc/MessageDialog.h"

AMyGameModeBase::AMyGameModeBase()
{
    // Set this to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bStartWithTickEnabled = true;
    PrimaryActorTick.bCanEverTick = true;

    // Set up the Message End Points.
    MessageEndPointEventCustom = FMessageEndpoint::Builder("A2GameModeBase").
        Handling<FEventCustom>(this, &AMyGameModeBase::HandleEventCustom).
        ReceivingOnThread(ENamedThreads::GameThread);

    // Subscribe to the message types.
    if (MessageEndPointEventCustom.IsValid())
    {
        MessageEndPointEventCustom->Subscribe<FEventCustom>();
    }
    else
    {
        // The message title.
        FText Title = FText::FromString("Error");
        FMessageDialog::Debugf(
            FText::FromString("Custom Event Event could not be subscribed to by class AMyGameModeBase."),
            &Title);
        FGenericPlatformMisc::RequestExit(true);
    }
}

void AMyGameModeBase::BeginPlay()
{
    Super::BeginPlay();

    MessageEndPointEventCustom->Publish(new FEventCustom());
}

void AMyGameModeBase::Tick(float DeltaTime)
{

}

void AMyGameModeBase::HandleEventCustom(const FEventCustom& Message,
    const TSharedRef<IMessageContext, ESPMode::ThreadSafe>& Context)
{
    // The message title.
    FText Title = FText::FromString("Success");
    FMessageDialog::Debugf(
        FText::FromString("The event was reached!"),
        &Title);
    FGenericPlatformMisc::RequestExit(true);
}


If anyone knows what is wrong, or if I simply forgot some build dependency to add to the Build.cs file, please let me know. I’m surprised I haven’t heard other people having this same issue. Am I really the only one? Please test this out for yourself and let me know.

Update (still not fixed): After doing some further testing, I found that the default bus isn’t being found in shipping mode.


// The default bus.
    TSharedPtr<IMessageBus, ESPMode::ThreadSafe> CurBus =
        IMessagingModule::Get().GetDefaultBus();

    if (CurBus.IsValid())
    {
        ... do messaging stuff.
    }
    else
    {
        Error message.
    }
    

I’m also guessing that the messaging module might not be loaded. In the Get() function it shows that it is trying to load the module “messaging”. However even after adding it to the build.cs file in the PublicDependencyModuleNames or PrivateDependencyModuleNames array as “messaging”, it still doesn’t work. Maybe I’m adding it wrong?

I really don’t like having to bump topics but this is a big issue and I really need somebody to help me on this. In the mean time I will be creating my own custom messaging system from scratch. Please let me know if you manage to find a solution. I’d really appreciate it.

I’m pretty certain that the MessageBus system is for tools/development only, it’s not something meant for use in a live product. If you look in MessagingModule.cpp, right at the top:



#ifndef PLATFORM_SUPPORTS_MESSAGEBUS
    #define PLATFORM_SUPPORTS_MESSAGEBUS !(WITH_SERVER_CODE && UE_BUILD_SHIPPING)
#endif


No message bus is created (See StartupModule()) unless that define is true. The only platform that seems to overrides this is Hololens, but even that looks like a temporary solution based on the code comments in HoloLensPlatform.h:



//@todo.HoloLens: Fixup once sockets are supported
#define PLATFORM_SUPPORTS_MESSAGEBUS                        1


EDIT: There is a TCPMessagingModule and a UDPMessagingModule that seems to not care about that define.

Ah, I figured as such. That’s very unfortunate because it seems like a very necessary feature. Most modern game engines generally have some sort of message/event system in place. I’ve managed to successfully create my own simple messaging system though. It works like a charm. If anyone needs any help on creating one, please let me know.

Thank you!

What do you mean exactly by messaging and event system exactly? That’s a very broad term and could cover a range of things. The message bus system isn’t something you would use for gameplay code, and Unreal already has it’s own reflected delegates and event types.

Basically the ability for objects to call each-other’s functions without knowing about each other’s class type.

For example, lets say you want some game objects to freeze when the player hits the pause button. When using a messaging system, those objects could have their freeze methods subscribed to a pause event as delegates, so when the player presses pause, the messaging system would iterate through them and call them one by one, freezing the objects.

Aside: I know UE4 already has a pausing mechanism; this was just an example.

Yeah okay, so what you really want is delegates. Dynamic Delegates have full blueprint/reflection support and are used extensively all across the engine (look at the primitive component collision callbacks for example).

https://docs.unrealengine.com/en-US/…tes/index.html

Thank you ^^. I have implemented lists of delegates with unique actor IDs to identify them in my custom messaging system.