Hey developers,
Some of the top feature requests we’ve gotten have been improvements to the way StreamingEnabled works and the amount of control that developers have over the feature in their own games. Well, you asked and we listened. We’ve made several improvements to StreamingEnabled to give developers more control and to improve gameplay in situations where players are experiencing poor network conditions. The main advantages of StreamingEnabled remain the same and recent improvements help address some of its challenges.
Advantages
- Faster load times: players can join a game and start playing without needing to wait for the entire place to be loaded.
- More complex places: many more parts and larger places can be created
- Support more devices: lower memory usage means games can be played even on devices without sufficient memory to store the entire place.
Challenges
- Clients on poor networks may be able to enter regions before they have been streamed in from the server. This can be mitigated using Streaming Pause Mode, as described below.
- Clients usually will not have the entire Workspace available locally. Developers must ensure that game functionality works when clients are missing parts of the world, such as by using Instance:WaitForChild (Please be aware that there is a chance WaitForChild will hang forever if the instance being waited for is never streamed in and that a timeout in WaitForChild is not specified).
API Additions:
Workspace.StreamingMinRadius (not scriptable)
The minimum radius property controls the minimum area around the player’s current replication focus that will always be sent with high priority. When a player no longer has the minimum radius around them, as a result of moving or CFraming to a new location, regions within the minimum radius will be sent first.
Care should be taken when increasing the minimum radius as this will result in more server time and bandwidth dedicated to streaming at the expense of other components. Avoid setting the minimum radius larger than needed to ensure the desired gameplay experience. Large values can also result in more time spent in streaming pause, leading to a player frustration. Avoid setting the minimum radius larger than the size of the world.
Workspace.StreamingTargetRadius (not scriptable)
Target radius properties control how far away from the player’s current replication focus where terrain and instances will be streamed to the player. Once terrain and instances within this target distance have been sent no additional terrain or instances will be streamed until that condition is no longer met. Note that clients may have more than the target radius available since as the player changes location previously streamed areas are only removed if the client has insufficient memory. As a result clients will continue building up a more complete subset of the place as they move around, memory permitting.
The target radius should be greater than the minimum radius. If the target is less than the minimum, then the minimum radius will be used as the target. Avoid setting the target radius equal to the minimum radius because this will prevent any additional areas beyond the minimum radius from being streamed in. As the player moves, this will result in the minimum needing to be sent repeatedly, possibly resulting in streaming pauses. Larger target radii result in more server time spent searching for instances and regions to stream; so care should be taken when increasing the target radius, especially for games with larger numbers of players per server.
Radius Notes
While these values are specified in units of studs, internally we search by predetermined increments, which is currently 64 studs at the time of this posting. So attempting to set fine stud level control will have no effect since it is effectively quantized to multiples of 64 during the region sweeping.
The search for unsent regions is performed in a rectilinear manner, not spherical as the name radius would imply. When the server is checking for regions in radius ‘r’ it will search from (-r, -r, -r) to (r, r, r).
Workspace.StreamingPauseMode (not scriptable)
Streaming pause is a new feature developers can use to prevent some challenges that arise when clients haven’t yet received regions. Developers can choose to have players in streaming enabled games pause when the minimum radius is not present around the player’s replication focus or the player’s character. The pause is a client-side physics pause, preventing the player’s character from moving and parts which the client owns from simulating. Only physics for parts that are owned by the player are paused. Networking and scripting is unaffected. Since scripting is not interrupted and scripts can query the pause state (Player.GameplayPaused) developers can alter gameplay and/or trigger UI for paused players if desired.
Local script CFraming of the player is more likely to cause streaming pause events because the player will be moved before the server has the chance to send regions around the new location. To avoid this server CFraming is preferred.
By default, a Roblox dialog is shown on the screen. This dialog informs the player that the game is currently paused while content is streamed in. Developers can disable this GUI via GuiService:SetGameplayPausedNotificationEnabled.
Players can also enter the paused state even when the minimum radius is present when the replication focus has been set away from the player’s character and the character enters a non-streamed region. Care should be taken when streaming pause is used in combination with setting the replication focus away from the player since streaming will occur around the focus, not the character. This can result in a player being paused but never unpausing since the region containing the player will not be sent if it is outside the target radius around the replication focus.
Player.GameplayPaused (read only)
This property indicates the player’s current pause state. Note that since the pause determination is made by the client the server could experience delay in seeing the current pause state, particularly if poor network conditions caused the pause in the first place.
GuiService:SetGameplayPausedNotificationEnabled(bool enabled)
This method allows developers to disable the built-in notification when a players gameplay is paused. They can then add in their own UI if they wish to customize it.
bool GuiService:GetGameplayPausedNotificationEnabled
Returns whether or not the notification has been disabled by the developer.
Engine Improvements:
We’ve improved how servers search for regions to be sent to clients, resulting in quicker streaming while using less time. We have made improvements to physics simulation to ensure that clients don’t simulate parts that overlap regions that aren’t streamed in on the client. Streaming enabled games will load faster and clients will receive streamed in regions more quickly than in the past.
We’re super excited to share these features with you! We look forward to seeing how the new-and-improved StreamingEnabled gets used.
Thanks,
Developer Relations