Load only certain parts of maps & players based on current Location?

Hello, I’m trying to make a system that loads in maps & players (to the most extent) based on map location loading, like games such as Adopt Me. They load locations in the world to only select players, while keeping objects concurrent across all machines.

Does anyone know how they achieve this? Are they sending objects over Remote Events? Are they replicating all objects but only keeping rendered objects in Workspace? (Note: This solution is not Streaming enabled).

Do not post here if you are not an experienced scripter. Thank you.

9 Likes

Capture

UPDATE: This looks to be how Adopt Me loads in characters from non-rendering. This looks easy enough to stop characters from rendering (and I assume the characters themselves stay updated), but if anyone has any extra info on how this works out all is helpful.

Still looking for answers on how to selectively load maps (Remember, they can’t be loaded on the client at all, because they would crash the memory. They also simultaneously replicate changes when finally loaded).

So, lets tackle this piece by piece.

First loading players. You can as it shows from Adopt Me, just store players in lighting when not in use. Lighting should keep track of positioning.

If you want specifics into how to do this, you’ll need to run a loop. Said loop runs on the client and keeps track of the distance from your player, to every other player. This is something known in Roblox as magnitude. It is quite literally as simple as (Vector3-Vector3).Magnitude

From there, use magnitude to decide your distance and move back and fourth between lighting accordingly.

As for loading parts of maps, this gets complicated. I would recommend just using Roblox’s streaming enabled feature. It’s getting very robust and it works.

Hey, thanks for the input on the characters.

When it comes to loading the Map, the solution has to be a bit more elegant. Streaming would work for a moment, but eventually it does not work correctly (for certain technical reasons I will not go into here). This won’t be a problem though, because Adopt Me has used their Modular Loading system without Streaming.

There must be a way where they selectively send maps to certain clients, no preloading replication, thus saving massive amounts of memory. (I ran a test where I preloaded a 50k+ part map into Replicated Storage, and the memory was out of control. Clearly, Adopt Me does not preload assets and hide them).

You could always divide your map into multiple small sections. Then have a LocalScript that checks the player’s position and loads only the sections that are close to the player. In other words, rather than trying to load a large map all at once from the client, (which you mentioned would crash the memory) try loading pieces of them based upon player position. If you do it seamlessly, it should give the impression that the entire map has been loaded in.

This is basically similar to what Streaming does, but since you’re handling it yourself you could potentially work around the technical issues you are having with Streaming

This is what my post was about, there is no way to send just section of the Map you want to send, you traditionally send the whole map and just keep the stuff you don’t want loaded in ReplicatedStorage or something. I’m looking for the method they use to literally send you the chunks one section at a time.

I say all this because it’s clear games with many pre-existing assets like Maps or Furniture do not download the Assets as a whole. I’ve seen in Adopt Me the replicate folder is empty (or so it looked), meaning they are only sending what is needed, to save memory on the mobile devices.

Would you mind explaining why you can’t divide the map? You could take a look at this forum post I found about loading in sections. It may be of some help to you.

When it comes to loading the map, a “rendering system” (as your probably thinking of) is more about unloading things from workspace to not render them. That is just a matter of loading thing already on the client. The problem I’m talking about is relating to how to replicate the maps to the clients when they teleport to that specific world (If the client receives all the maps at startup, like a normal roblox game, this will be too much memory for the client). This is selectively sending maps to save all clients memory space.

So if I’m understanding you correctly you want select maps to load only when they are supposed to, and not to take up client memory until it is necessary. In other words, not only do you not want them rendered, you do not want them anywhere on the client. This means that you will have to store them in ServerStorage. In order to get them onto the client, you can actually pass an object through a RemoteEvent. On its own this won’t do you much good, as the client still can’t access it while it is inside of ServerStorage. However, the solution lies in the post of one helpful individual from the thread linked in my last post:

If you look at the edit, there is actually somewhat of a duct-taped together solution. You can set the parent of an object as a specific player’s PlayerGui (from the server). You could then pass that object to the player through a RemoteEvent, and let it transfer the object into Workspace from the client.

1 Like

Thanks, that was essentially what I was asking about.

I’ve set up my download system, but unfortunately there are 2 downsides:

  • Downloads have to be Cloned on the server before being parented to the client (or object is nil, from serverstorage)
  • Local objects need to be cloned before being parented to Workspace (server deletes its server-copy moments after sending, which unfortunately deletes the memory address of the client as well)

System works for now, but will be looking for fixes on those problems.

Glad you have it working now! I suppose you could pass an integer through the remote event instead of the object. Then have the client search the PlayerGui for the map that matched the integer. I’m not sure if that would fix your issue or not, but if the server passing the location of the object in memory is what causes the issue, it might be worth trying.

Not sure which bullet point you mean, but with the server deleting the object, it has to do that after you download it (its sitting in your PlayerGui) because the copy is taking up memory on the server. It’s shared.

Right, you wouldn’t want it taking up space on the server after it has been transferred to the client. So your issue is that even after transferring it to the client, it deletes it on the client as well?

The system works now, so there are no problem, but there is only 1 downside to this system:

  1. Server clones to PlayerGui, Client clones (makes own copy) to Workspace, tells Server to delete Download from Player Gui. Meaning, there is unfortunately a lot of cloning (slow) and memory storage (during downloads, Server and Client can each have 2 copies of the same object).

I’m assuming Adopt Me does this more efficiently, but there is no obvious solution as of now. There are no easy ways to just simply "send’ the object. It’s not the worst thing ever, after all, the maps are only maybe 10k parts maximum at any time, so it’s not overbearingly slow.

2 Likes

Maybe you can do something like:

on server script - when a player enters a location, send him a message using “RemoteEvent” or anything else. The message will contain all cloned objects that are wished to be showed for the player in a table. All these objects should be stored in “ServerStorage”, so it’s not loaded for the clients.

on client script - when receiving a message from the “RemoteEvent”, get all objects from the table, and parent them to workspace, or in a folder.

When unloading, you can do the same thing, but just send the client a message that all objects should be deleted, and on the client side, just delete all objects. OR when sending objects from the new location, you can remove objects in the previous location.

!! I don’t know if this works or not. I didn’t test this. But it might actually work !!

– edit:
I forgot to look at the date of this post. It was like 2 years ago. Sorry for the wait :sweat_smile: