UE4 keeping LoadBalacing client alive during level change

Options
Hi,
I'm having a problem with the LoadBalancing client disconnecting when changing levels in UE4.
Since UE4 destroys actors in the old level it also destroys the actor holding the LoadBalancing client.
UE4 does have a seamless travel feature, but if I understand correctly it can only be used with the ServerTravel function.
One workaround might be to store the current GameID in a SaveGame object, then creating a new instance of the LoadBalancing client in the new level and then calling connect() and opJoinRoom().
Having to reconnect to the master server and then to the room on every level load seems more like a band-aid than an actual fix. Any suggestions?

Comments

  • Kaiserludi
    Options
    Hi @laz.

    UE4 does not destroy the Client instance directly. It only destroys the actor. Hence the key is to make sure that the Actor does not destruct the Client when the actor gets destructed itself.

    To achieve this you need to understand or remember how memory management and variable lifetimes work in C++ when it comes to class members:
    A member of a class can be a variable, a reference or a pointer.

    If you let your Actor hold a member variable of type Client, then this variable must be constructed in the constructor of the Actor class and destructed in its destructor and the lifetime of that variable is limited to the lifetime of the class of which it is a member, which is the Actor class. When the Actor gets destructed, then the lifetime of all of its members ends.

    Now if you instead let your Actor hold a member pointer to an instance of class Client, then only the pointer is a member of the Actor class with an according lifetime, but the instance to which this pointer points to is not in any way bound to the lifetime of the Actor. You neither need to construct the Client when you construct the Actor, nor do you need to destruct the Client when you destruct the Actor.
    Multiple pointers can point to the same object.

    The trick here is to use dynamic memory management:
    When you have not created a Client yet, then create one in dynamic memory (i.e. with operator new or with Common::MemoryManagement::allocate()) and store a pointer to it somewhere outside the current scene, where you can still access it when the scene is no longer existing. Store another pointer to it as a member inside the Actor so that the Actor can easily access the Client.

    When a new Actor gets created in a new scene and you already have a Client instance that got created in another scene, then just store a pointer to that existing instance in the Actor instead of creating a new Client instance.

    If you no longer need the Client instance, don't forget to destruct it and free its memory as this won't happen automatically and when you forget to do it, then your code will leak memory.

    Regarding how to store a pointer at a location where you can access it from multiple scenes in UE4 please see https://forums.unrealengine.com/development-discussion/blueprint-visual-scripting/22934-passing-variables-between-levels.
  • laz
    Options
    Thanks for the reply,
    Storing a pointer in GameInstance fixed my issues. :)