Minimize memory usage for a larger loot-based game

Hello :slight_smile:

I am building a survival game that renders 3d models into viewport frames for the inventory GUI.
I am already aware of the potential performance issues of having lots of viewport frames rendering 3d objects, but so far it has not been an issue (even running the game on the cheapest laptop available with only a dual-core processor using TERRIBLE internet). The real memory thief is the extensive storage of these 3d image models in replicated storage, (at least I believe) along with duplicates of every image model as the actual item that you can find and interact with. The game is basically processing huge folders of models in replicated storage x2.

Is there any way I can eliminate storing the view models or items in the actual game? I think it would be much more efficient to store some of these assets somewhere else and import them via script whenever needed. I just don’t know how to do that…

You could probably store them in ServerStorage and then replicate them to the client as-needed.

1 Like

The only issue with trying to store assets server side is that the mechanics of the game primarily request these assets locally, so it becomes a headache of RemoteEvents trying to pass objects between the client/server, and that will likely not have much of a net-possitive impact on performance, at least for players running on a slower network. I’m thinking a good thing to try might be storing the objects as an asset links in a module and importing the assets as needed.

Headache in what way besides refusing to give it a try and making far-fetched assumptions? I use this method in a production build of an asset-heavy game, PWNED 3, and it has significantly improved our asset management for clients including reducing client memory use by over a gigabyte. I had the exact same problem as stated in the OP and resolved it with that post linked above.

It doesn’t matter if the mechanics of your experience rely on locally requesting assets. Your main issue is overloading ReplicatedStorage so the suggestion is moving the assets to ServerStorage and then managing replication and storage of them yourself. Nothing changes overall besides managing the replication of assets on your own instead of automatically. You will need to put in the work.

A lazy loaded (when-you-need-it) approach to ReplicatedStorage can relieve the client from consuming a large amount of memory to store these instances and initial replication burden when loading the DataModel. The goal is that you either find the asset existing in ReplicatedStorage or if not then request the server to pull it out from ServerStorage and give the client a reference to it. That’s it - all you’re doing is cloning an instance and giving the client a reference to parent it to ReplicatedStorage so it can use it in the future or destroy it when it no longer needs it.

There’s no performance or network bottleneck that’ll be experienced here besides replicating the instance when it’s handed to the client which is still an expense you need to pay regardless of now (static instance) or later (dynamic instance). In fact, all underlying expenses stay the same but the time at which you pay them differs. It is significantly better to only pay the expense when you need to instead of doing it all in bulk.

Using a MainModule to load your assets still does as the original suggestion says which is to store them on the server and only give them to the client when necessary. The only difference is that you lose maintainability. MainModules are gross in production builds.

5 Likes

Sounds like you need to do some testing.

I can vouch for this method as well, however we don’t replicate parts based on proximity, rather through an option that allows users to disable stage decorations but the same premise still applies; the method to replicate the instances is the method you put in your post.

Instead of loading all decorations by default, we gradually load them over time through cloning into the PlayerGui, if the user decides they want stage decorations to be enabled. We also don’t load them all at once as this could cause a large spike in data received as well as in memory usage. If users on low-end devices notice they crash, this gradual loading also has multiple uses, giving users several minutes as a grace period to turn off stage decorations.

For reference we have over 30,000 decorative instances IIRC, our memory usage was extremely high and it was causing crashes essentially 100% of the time for users with 1GB of ram (eg. 5s/6/6+/some older iPad models, and some lower-end Android/Amazon devices) and was sometimes even causing performance issues for users with medium-end devices. Since the implementation of this system as well as some other relatively minor optimizations, our crash rate has decreased significantly as well as our memory usage obviously, from well over a gigabyte to ~600MB for users who have decorations disabled.

I never really spoke publicly about my personal experience with this method so I guess this is my testimony. This method works wonders. I would highly suggest reconsidering implementing this method, the benefits significantly outweigh the drawbacks.

2 Likes