New Instance Streaming Feature: Multiple Replication Foci

Hi Creators,

We are excited to announce an improvement to StreamingEnabled, Multiple Replication Foci (MRF). Replication is how Roblox pushes content from our servers to your clients. Previously streaming has supported a single replication focus per player, typically the player character.

With Multiple Replication Foci you can now dynamically add and remove additional replication foci for each player. This enables more flexible streaming in the areas of the experience you need streaming to occur, rather than being limited to a single location. For some example uses cases see below in #useCases. Multiple Replication Foci is available today to start using in your experiences!

Current Capabilities

Streaming currently supports a single replication focus. This defaults to be the player’s character model, but it can be set to any part via Player.ReplicationFocus. The server sends regions around the replication focus to the client, attempting to stream out to a target radius.

Player.ReplicationFocus

Streaming also supports prefetch requests, which are short lived requests for streaming around a particular location. These are transient as the server will send the minimum radius around the requested location one time. The purpose of prefetch requests is to allow streaming around an area the game thinks the player may move to, so that they don’t have to wait for the server to send regions around that new location when they arrive there. After a short time interval (5 seconds) prefetch requests are subject to garbage collection (GC).

Player:RequestStreamAroundAsync

The physics simulation radius is enforced to be always less than or equal to the currently streamed radius around the replication focus (player if not set). This means that client physics simulation is limited to a single volume centered on the player. Mechanisms outside this volume will never be simulated on the client, even if the mechanism only exists on the client. Prefetch requests cannot be used to circumvent this constraint.

Current Behavior

The existing capabilities just described have some important implications on how streaming currently behaves. First, as already mentioned, client physics simulation is limited to a single volume around the player. This means that mechanisms outside that radius will not be simulated, even if the mechanism exists only on the client. Allowing simulation of local only mechanisms everywhere would be problematic since mechanisms could fall through the world due to missing terrain and server replicated parts.

Another implication of the current behavior is that if players are frequently CFraming around the game world the streaming system may always be streaming out one volume while streaming in a different volume. This is particularly problematic when used with opportunistic stream out, as far away regions will be streamed out even when there is sufficient memory. Consider a common spatial game layout such as:

Simulation games often have the player’s home base location, or the currently being explored area. Players often move between that location and a common/shared area such as a trading hub. Or consider a high school simulator where the home base would be the player’s house and the trading hub might be the school or work location. Creators currently have no way to indicate that these two areas are important and should be kept streamed in on clients.

MRF API

As with the current focus control, each focus is associated with a part so that the replication volume can be associated with a moving part if desired and the focus will automatically move as the part moves.

Player:AddReplicationFocus(part: BasePart) → ()

Player:RemoveReplicationFocus(part: BasePart) → ()

Similarly to the primary focus, additional replication foci will maintain instances within the minimum radius, and stream out to the target radius if client memory allows. Note that instances and terrain within the minimum radius will not appear instantaneously on the client once the focus is added, it may take some time for things to be streamed to the client. Once the minimum radius has arrived we will not stream it out, even under memory pressure.

This API is only callable server side. We don’t want to allow local scripts to be able to request replication around arbitrary areas, as creators may want clients to only have instances in certain allowed areas and be using streaming as a form of information hiding or fog of war. We also don’t want to allow clients to directly cause the server to have to do more work by requesting additional foci.

Use Cases

Physics Outside the Primary Focus Volume:

Client-side physics simulation only occurs in streamed areas, even for locally created instances and for persistent instances. This is by design, because if we allowed local instances to always simulate even when instances around them may be streamed out they could fall through the world or pass through missing instances they should have collided with when instances are streamed out.

If you have instances that you would like to keep simulating even when they are far away from the character then multiple replication foci may be useful. By creating a focus near the instances you want to keep simulating you can help ensure that simulation can still continue even after the player’s character moves away from the area.

Consider a simulation game a creator wants each player’s home base to continue simulating on their client even when the avatar is visiting the trading hub in the game:

local Players = game:GetService("Players")
local player = Players:WaitForChild("Player1")

local baseCenter = Workspace.HomeBases.Player1.BaseHub
player:AddReplicationFocus(baseCenter)

Frequent Movement Between Game Zones:

It is common in many types of experiences for players to move back and forth between the same areas frequently throughout the game. For example, between their home base and the trading hub, or between the team base and the combat zone. When the StreamOutBehavior is set to opportunistic the client will always stream out instances beyond a certain distance, meaning that as the player moves back and forth we may repeatedly stream the different areas in and out as the player moves back and forth.

For example, when the player is at their home base we stream out the trading hub, and when they move to the trading hub we stream out the home base. With Multiple Replication Foci you could add a focus at the home base for each player, and perhaps the trading hub for all players, helping to ensure that those areas are always present on the client devices.


Example of MRF in use: Dense Desert Dominion experience with two foci, one at the capital building on the left, the other at the base on the right.

Remote Views and Scenes/Spectator Cameras/Sniper Scope:

MRFs can also be used when creators want to be able to quickly switch between different views or see remote locations. Consider a spectate mode in a battle royale experience where a player who has lost might want to spectate the remaining players. A focus might be assigned to the player that is currently being spectated, with perhaps additional foci for the next and previous players in the spectate list.

An additional focus can also be used to help with sniper scope scenarios where you might want to have content available at far away locations without needing to set very large min/target radii. On the client we might determine a vector for where the player is looking when they use a sniper scope. On the server we can do a raycast to determine where that vector would hit, and set the position of an invisible, non-coliding part to be at that location. The result is that as the player looks around through the scope they get the world streamed in where they are looking.

Left: Without Additional Focus // Right: With Scope Focus

What’s Next

We are working on more flexible ways to trigger streaming in desired areas beyond just radially around a focus that should help with scenarios such as sniper scopes and cameras.

Resources

Please share any feedback with us below.

Thank you!

Known Issues

  • Using Add/RemoveReplicationFoci with a non-part results in a crash. Fix under development.

FAQs

How many foci can I use simultaneously?

  • Try to minimize the number of foci that are used, especially if they move around dynamically. Each focus requires CPU and networking bandwidth to maintain, and also increases the memory requirements on the client by causing more of the experience to be streamed in.

What do additional foci use for the minimum and target radius? Can that be changed per focus?

  • All foci use the same values for min and target radius that are specified in Workspace. Note that the currently streamed amount will vary per focus, and some foci may have larger volumes streamed around them than others.

Can I add a focus that is shared by all players?

  • Unfortunately you must add the focus to each player in this situation.
307 Likes

This topic was automatically opened after 10 minutes.

These seem to be from the C++ end, consider changing it to:

Player:AddReplicationFocus(part: BasePart) -> ()
Player:RemoveReplicationFocus(part: BasePart) -> ()

Besides that, this is a great feature!

39 Likes

This is honestly a godsend. W Update!

51 Likes

FINALLY I can enable streaming in my horror games (they don’t spawn you automatically)

15 Likes

Seems like a great update for open world games!

16 Likes

Ever since this update, I’ve noticed a critical bug with replication.

When entering one of my games, there’s a random (~5%) chance that models set to Atomic do not replicate as such — with Instances under them not existing at the time the model replicates.

12 Likes

Are you able to provide a simple repro place? When did this issue start occurring?

This update should have no effect on how atomic models behave.

6 Likes

Are the performance issues with many foci reduced with a smaller replication distance? This seems like it could be used to put together a custom “area loading” system by placing replication points along key areas, but those issues may inhibit that.

Having a method to more explicitly load specific sections of the workspace would be very useful for games that are a large majority indoors in a stacked layout (like an office building or underground facility). Something like a Player:AddReplicationRegion3() function would be great.

12 Likes

I’ll try creating one and I’ll DM you here in a few minutes.

According to our error logs, the error first appeared ~24h ago.

3 Likes

Looks like Roblox added multiple replication foci. It will get Laggier.

3 Likes

This. Why are the methods limited to just BaseParts? At least allow us to use other instances like Model and Folder with this API.

4 Likes

Is it that hard to loop through each BasePart in said instances

4 Likes

Wouldn’t this create multiple replication areas around the same point?

4 Likes

Oh, I was wondering about this. It would have made so much more sense if it was named AddStreamingFocus but okay. Now, you can’t undo it anymore.

This is very cool and very useful! I still don’t know if Streaming Service has a memory leak on mobile devices. :thinking:

 

How do you list up all of a Player’s current replication foci?

So, how did replication get affected when StreamingEnabled was disabled?

 

I hope that all this information is also in the docs. Unlike some places in the docs, information from their associated DevForum posts, is somtimes not included in the docs. :confused:

3 Likes

Would be great if the API also supported PVInstance and Attachment instances, as both have positions which can be acquired via GetPivot and WorldCFrame respectively.

12 Likes

Aw man this is awesome, I have a game idea that would require a huge map, currently I have 4x4 max size baseplates set up, I may go bigger depending on what all I can cram into it, but it is going to be a map of a big mountain region inspired by the Canadian rockies, Jasper National Park etc.

So I was going to use streaming enabled, but there are certain things like a home base location, there being multiple locations that you can pick, where you can go through and configure your gear and vehicle etc.
I was also thinking of some quick travel options possibly, to make going where you want, more easier.

Ill most likely be trying to do a setting that can be changed by the player if they have a good PC or something they can up the radius. However I want players to be able to say go up a mountain and see a far distance.

2 Likes

Yes, it is. I shouldn’t have to iterate through an entire instance tree just to stream one model. That’s bad UX.

Apparently if you use AddReplicationFocus on a child of a model it will stream in the entire model regardless of atomicity. I guess that’s good enough, but it would be more ergonomic to just allow any instance to begin with.

Edit: Trying to pass anything besides a BasePart currently crashes studio.

4 Likes

Is the Part Size taken into account or only Part Position?

I was thinking it be easier to manage if I have a Part covering the whole region and use that Part for focus

1 Like

This right here is really good and will get a lot more games using streaming.

I did have a game that used streaming enabled but I had to turn it off because the player would fall through map because the floor wasn’t replicated in time. This could be handy for loading places the player will be teleported to indeed.

I will consider in future projects too! :happy3:

1 Like