(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.

@SolDirix - hey, no - you are not the only one.

You mention you knocked out a simple solution yourself using the underlying interfaces, which is where I first looked. Are you able to share a repo?

@Jambax - not sure you understand the concepts of the pub/sub pattern and why we would want to have it, given your response that delegates should be used.

Don’t get me wrong, Delegates are great - but they are not what we are referring to here.

A pub/sub pattern implementation that we are looking for is something like the RXJS implementation available for javascript, or the same used in c# etc.

Why would we want that?
A correct implementation gives you the ability to create a shared reference between components and modules, without them having an explicit reference added. So for example, a central co-ordinator could receive incoming messages from anywhere - and then act on those messages to push them out to subscribers who have no idea about the originator of the message - they dont even have to be the same types or implement the same interfaces etc.

The reason why Hololens uses it, is because a lot of the patterns underlying the code base are based on the MVVM pattern, common in enterprise software solutions.

A correctly implemented library with the pub/sub pattern such as RXJS would be really great.

Thanks

It’s the same thing in UE terminology - the only implementation detail missing is the idea of the central object which manages them, but that’s very simple to implement yourself.

In UE, ANY class can Bind (subscribe) to a delegate/event, and any class can Broadcast (publish/call) a delegate. Events restrict the caller/publisher to the owning class, delegates do not, that’s the only different between them.

The engine does this in at least two ways I can think of:

  • static members (easily accessible from anywhere)
  • easily-accessible class instances (such as subsystems), which hold delegate members. These class instances are usually statically accessible in some way.

Making them accessible cross-module is as easy as tagging them for dll export.

This is extremely common practice in UE to allow game-level code to push out events that user-interface can respond to, or in multiplayer where you may have race conditions between actors etc. Ultimately it’s the same thing - unrelated classes can find and bind to events, and other unrelated classes can broadcast them, and neither object at either end has to know about implementation details of the other.

Hi,

I’m exactly looking for something like RXJS as @brennongwilliams mentioned or just anything that resembles PUB/SUB.

@Jambax Do you mind giving an example of how you’d send an event to a HUD from PlayerCharacter, where HUD doesn’t know about PlayerCharacter and PlayerCharacter doesn’t know about HUD?

Every example that I’ve seen where you can bind to a delegate requires you to have access to an instance of that class. For example, if I want to bind to a player event such as “HealthUpdated”, I’d have to have a reference to PlayerCharacter inside the HUD class, and then I’d bind to that event on that class on BeginPlay for example.

You can put the delegate in PlayerController, GameState, or PlayerState, or maybe even GameInstance (I’m not too familiar with that one).
Those objects are always present and easily reachable from anywhere (HUD or PlayerCharacter).

In your specific example, I understand binding to PlayerCharacter from HUD can be problematic due to life span issues. HUD lasts as long as the game, while pawn/character might die and respawn several times. However you could easily do it the other way around? HUD is always accessible from the PlayerCharacter, you could simply call something like GetPlayerController()->GetHUD()->OnHealthUpdated(Health) from character code.

Thanks for chipping in @Chatouille.

I’ve been playing around with that idea but I’m liking the approach of creating a separate subsystem which has a list of delegates that describe my world/player events.

I like it because;

  1. Easy to get access to it from player controller or the UI components
  2. Has managed lifetime
  3. Completely independent

I have it now so I’m caching pointer to that subsystem (especially useful if you have an event where player gets hit a lot and other systems of the game like the UI needs to know about it) and just calling specific delegates from it. Works like a charm so far. Will explore it more.

Thanks

For anyone having trouble getting two projects to communicate with each other in a packaged build with FMessageEndpoint, create a shortcut of your EXE and add the extension -Messaging to the target field in the shortcut’s properties.

Adding this should enable your EXE to construct the endpoint properly.

1 Like