Reducing Memory Usage

Hi! So I’ve been working on a large first-person shooter game and I have a pretty big inventory system with a lot of items in the game. I noticed that my player character was almost 3 GB of memory when looking at the size map. I realized a big spot where the memory usage was larger was from my data table. I tried changing all of my references from hard to soft references and it significantly reduced the size of the data table, however, I’m still sitting at over a GigaByte of memory usage for about everything that is out there because it’s referencing the player character at some point or the player controller. I’m using a blueprint interface as well for my character and for my controller and calling any interface from those BPIs, it will rack up my memory usage again. So overall what I’d like to know is is there a better way I should be managing my memory and is the soft reference method good in my data table? And if that’s the case, is there anywhere else I should be using soft references? Thank you in advance for your help :slightly_smiling_face:

My Player Character Blueprint:

My Weapon Blueprint:

My Player Controller BPI:

My Item Struct:

Could you show a call to the interfaces?
They should not impact the memory usage.

Check for casts, they can be a culprit of using up memory causing hard references.

Why is bpi player controller 1.1gb?
You should be calling the base get player controller and calling the interface function on it.

The interface is still a hard reference.but a lightweight reference.
make sure to prevent interfaces returning heavyweight variable like actual type of class/actor,meshes,etc…if the interface returns heavy stuff.it no longer lightweight.
you could also check the interface’s sizemap.

Since you didn’t show your BPI, I assume you have used a blueprint reference in your interface function as input to access the other blueprint. It is the same as casting. Just remove that input.

Now, if you have a BPI function that has no inputs and outputs, you are to add the interface to the target blueprint (the blueprint to which you want to access). And in that target blueprint, implement the interface. All the nodes that have that target blueprint’s variables, functions, events, macros etc. go there. Then, in your source blueprint, send a message to that BPI function after the nodes that belongs to your source blueprint. Then, the rest of the code in your source blueprint go after it.

To send a message to your blueprints, if it is the character blueprint you want to access, use the Get Player Character node as target. If your target blueprint is the controller, then use the Get Player Controller node instead.

I’m not casting anywhere in my BPI. I’ve been trying not to cast at all if I could help it. What I’m pretty sure is bulking up the BPI though is I have a return value of the player controller in there because I needed a reference to it because I was binding an event dispatcher and I’m not sure of another way to do that. And at the time I didn’t realize that making a call to a BPI will load in everything from that interface, even if the function I’m calling only returns a Boolean. So I guess to help solve my problem, is there a way to bind an event like that without a hard reference to the player controller or do I need one?

Why do you have to use an event dispatcher? Aren’t you already using an interface? Just make another interface function, and implement it in its stead.

You could have a base class that only exposes the dispatcher and then extend that class to the full heavy class.

The the cast would be to the barebone class (limiting memory usage)

So that dispatcher is for my quest system. Basically, when the player interacts with something, it fires an event and the quest actors that are in the world are listening for that call to know if their objective has been completed.

If you are accessing that same blueprint with the event dispatcher, than having an interface won’t matter. I can’t say much without seeing your graphs, but maybe you can funnel the child references through with an interface function, instead of the whole blueprint reference? Alternatively, can you, maybe, isolate the code that doesn’t require the event dispatchers, and put it in a different blueprint parented higher up, which you can then access with your interface? You may also consider turning your event dispatcher events into interface events, though I can imagine that might be a long endeavour.

Hi. So this is the begin play of my quest base for example:

I’m binding the event to a dispatcher from my bp_playerController. The only way that I know how to do that is to somehow get a reference to the bp_playerController The initial plan was just to use the BPI Player interface because I didn’t realize that loading in at least one function loads everything from that interface and I didn’t want to cast from the Get Player Controller Node.

Quest Log Component:


This is inside of my quest log component which is an actor component that I put inside of the player controller that spawns in the quest base actor.

Your output in the BPI player is the blueprint reference of the character, right? It is going to get the entire character blueprint, and you end up with a hard reference. I say, just remove that output. Then, in your character blueprint, implement it as an event (from the interfaces tab at the left, by right clicking on it, and clicking on Implement Event). Link your Bind Event to OnObjectiveIDCalled with your CreateEvent there. Delete them from your blueprint on the image.

In Player Controller Blueprint

In Quest Base Blueprint
image

I think I understand what you’re saying to do, I’m just confused on how to do it. Also I’m actually working in the player controller, not the player character. I had the wrong interface connected in the screenshot lol. But this is what I’m at now and I’m not sure how I would bind the event inside of the player controller for the quest base. I also may be completely misunderstanding what your saying haha. Thanks again for taking the time to help!

From the red event pin, create a custom event. And call your event in the Create Event as a function instead. Pull from your custom event, and search for your On Objective ID Heard by right clicking on the graph.