Load and unload areas of the map locally?

Hello,
I’m trying to make my game as compatible with mobile devices as possible. I want the client to load and unload areas of the map based on where they are, similar to meepcity when you enter the neighborhood from the main area. I have no idea how to do this.

Do I just remove the area of the map locally and place it back in later? As far as I know Streaming Enabled is not what I’m looking for, I’d rather create my own system as I will only be loading or unloading 3 “areas” of the map.

What’s the best way I can accomplish this?

Thanks so much,
korky5000

15 Likes

If you want it done dynamically, th first thing that pops into my head is to make a bunch of Region3s and divide the parts of the maps into chunk models. Leave those in ServerStorage (not rep cuz we don’t want them to fill client memory)

Then have the client stream chunks over a remote event.

2 Likes

I’m interested in this as well, I was using a vicinity based local script to make them invisible and non collidable if out of a certain range and greater than a certain size, storing original transparency and collide settings in the part. However scanning all the parts in the folder with a for i,v in pairs() caused more lag than it reduced. Anybody else have ideas?

The logic is easy. The implementation is difficult:

  1. Write a script that basically “compiles” your game into separate regions at the start of runtime
  2. Keep these regions in ServerStorage
  3. Load/unload them dynamically based on the player’s position

Here’s the really hard part: How do you load the region for the player? You can’t place it into ReplicatedStorage, because it will then replicate to all players. AFAIK, you can’t send the original or clone of the region in ServerStorage to the player, because it will come back as nil for the client.

This means that the only way to send a server-only model to a client is to first place it into the game hierarchy somewhere that will replicate…but unfortunately it will always replicate to all clients.

So you have to somehow replicate the model to only one client. I’m not sure how to do this. Anyone have a trick for this?

Edit: I asked on Twitter, and a bunch of people suggest throwing the models into the PlayerGui or Backpack. Clever trick.

36 Likes

You would need to create a method of saving instances to tables (not impossible) using the api dump and then sending those tables over a remote event. The end result is essentially custom replication.

This is part of a solution, but the big problem to solve when the client and server are completely separated like this is that you lose the concept of a shared state which Workspace and ReplicatedStorage provide. In this post I will assume that Workspace.StreamingEnabled is false.

For example, say you have some “door” game object which the client animates when the server fires a RemoteEvent - in a traditional Roblox game setup the server could just pass whatever instance is considered the door being triggered, and the client can take care of animating it without any additional steps or structuring. This works because in a traditional setup that instance exists on the server and the client where they both can see it, i.e. ReplicatedStorage or Workspace.

If the entire map only exists in ServerStorage and the server replicates parts of it selectively to each client, the client and server can no longer interface this way: the server now has no way of knowing exactly what objects exist on each client. There are a few solutions I can think of (there are probably many more) for this:

  • Keep all of your game objects that require a shared state in ReplicatedStorage or Workspace. This is the easiest, but least scale-able solution; all game objects will always be replicated to all clients.
  • Assign unique IDs to game objects which require replication; then, the server can just pass this ID to all clients, and each client can decide what to do based upon whether or not they have a game object loaded with a matching ID. This approach is also not very scale-able (although a bit better than the last one), because each client is still receiving data that it possibly doesn’t care about if the game object doen’t exist on this client (which is a big waste of bandwidth!).
  • Implement an entity system, and keep track of loaded entities for each client on the server. Then, when a game object requires a state change, the server can decide which clients actually need this update (i.e. if they have a corresponding entity) and fire an event to the clients in question. This approach is very scale-able; entities are just integers (so keeping track of them per-client won’t take up a huge amount of memory on the server), and clients aren’t receiving any data that they don’t care about. This is the most difficult approach, because entity systems are a pain to implement properly (at least, that has been my experience in creating one for Roblox)

It’d be great to hear from anyone else who has grappled with this problem - I’m always interested in how other people approach these things

13 Likes

Thanks so much for the information @Crazyman32 and @HaxHelper . I think that clears up my confusion and hopefully I’ll be able to tackle this :sweat_smile:

Sorry for bumping an old topic, but this is somehow viewed by many people

I’ve a suggestion for this

Create a folder named with player name or userid in Replicated Storage, whenever client has to load these back, you have to do ReplicatedStorage:FindFirstChild(playername) as thats where the client objects would be, I tried it with 3-4 people, it works fine

1 Like