StreamingEnabled is infeasible to use even when it is working as intended

User Story:

As a ROBLOX developer, StreamingEnabled is not feasible enough to use in my games. StreamingEnabled has a negative stigma due to past bugs, but AFAIK these are fixed – this is not what the feature request is about. The way StreamingEnabled is designed to behave when it is fully working is the problem: my game has to support instances arbitrarily loading in/out.

Use Cases:

If this issue was resolved, it would improve my development experience by not having to worry about:

  • Having to change my entire codebase to support dynamically inserted/removed parts
  • Code that stores a part in a variable, yields, and then errors when it tries to access the part because it unloaded while the script was yielding
  • Having to manually ask the server for info on parts that aren’t loaded e.g. “I want to teleport to this player, but their parts are not loaded on my client. What is their position?”

A Solution:

Much like garbage collecting, a part should never unload if there is a Lua reference to it somewhere – this will prevent bugs with scripts indexing a stored part only for it to error. Also, the client should automatically stream in parts when accessed with WaitForChild. For instance, if I run the following code:

local otherPlayerPosition = workspace.Player2:WaitForChild("HumanoidRootPart").Position
myCharacter:MoveTo(otherPlayerPosition)

behind the scenes the client would say “Server, I’m waiting for this part. If it exists, please stream it to me”, the server would stream the HumanoidRootPart to the client, and then the client would finish executing the code.

Not only would this make StreamingEnabled more feasible to use, but it would be a mostly drop-in solution with no extra work required if the developer is using WaitForChild properly on the client.

Further Concerns:

There are also concerns with the parts StreamingEnabled selects to load/unload not being very pretty. If we ever get LOD, this could potentially be integrated with StreamingEnabled to provide for a better experience. Other than that, StreamingEnabled would only require behind-the-scenes changes to improve which parts are loaded.

24 Likes

As written, the post seems theoretical to me. We can only act on feedback like this if there’s significant evidence that this is a problem - which requires examples of code that you’ve written before (in a FE context) that breaks when you enable SE and that would not break if these changes were implemented.

5 Likes

I was using FE and SE in my game.

I had a scene placed underneath the map which I would move the camera to when a player opened a crate. Unfortunately this meant that the scene would often be unloaded when the player walked away from the centre of the map, causing the script to error.

I had to script around this by locally cloning the scene into the workspace every time a player opened a crate.

@Simbuilder (vehicle simulator) tried to use streaming the other day iirc and it was not feasible because the cars drove faster than regions could load.

4 Likes

I can create some repro files when I get home, but the mentioned issues in the OP were from real development cases. I was considering using StreamingEnabled for a few non-concurrent games, but I analyzed the nuances of StreamingEnabled and decided against it before implementation (wouldn’t want to waste development time on something that wouldn’t work). Are just the repro files fine, or do you also want me to list specific problems I identified it would cause in past games?

Perhaps roblox could try the halloween place, that had 100 player server.
that took forever to load, as it used SE.

I think repro files that illustrate specific code you used to write before SE that now fails would help. I’m interested in specific gameplay-related examples, such as what @AlgyLacey posted earlier.

I would absolutely use streaming enabled if it worked as intended. Intended behavior being I see everything around me depending on hardware only. A lot of internet connections are slow around 10-15 mbps.

As AbtractAlex said I tried using streaming enabled on a test place last night. This was the result with 8 people in my server.

After driving a bit longer I fell off the world as it was not loading in fast enough.

(Post streaming enabled client fix, it does not lag at all, which is fantastic)

After the fundamental streaming distance issue is resolved I think streaming enabled will become a no brainer for developers. A player should always see everything around them, they shouldn’t be seeing everything where they spawned when they’re on the other side of the map.
Hope this helps in some way, if you need any repo files at all, let me know.

4 Likes

I’d still have to keep streaming in mind whenever my code touches a part that’s in the workspace. “Am I okay with this part being streamed out? Am I holding a reference to a part that would have been streamed out, so holding it would no longer matter? Do I have a reference to this part to make sure it doesn’t get streamed out? Boy, it would be nice if I could just specify all of this directly rather than having to keep track of references in such a roundabout way.”

Also not a fan of screwing around with WaitForChild again. Other than the Name, WaitForChild has no knowledge of the object its waiting for, and the object can be added by means other than replication. Considering your example: what should happen if the client were to insert some non-part named HumanoidRootPart?

This would be solved better with an API that explicitly streams things in and out. Streaming is just complex enough that it requires predictability and control. As long as we keep pretending that the concept of streaming is capable of being toggled or “dropped-in”, there’s going to be a stigma.

4 Likes

Yeah this is why I’m asking for specific gameplay code that breaks currently - it’s not clear to me that the solutions proposed in the post are the right solutions.

A solution based on references makes doing stuff until a model unloads difficult. You won’t be able to keep a reference to the model if you want it to automatically unload. You’ll have to access it through another object as a child or through an ObjectValue. I can also see this behavior being confusing if the developer is not aware of it or are not aware of how references and garbage collection work.

I think a better interface would be an explicit lock/unlock. For tasks that need an object loaded the whole time, you lock the object first. For tasks that should work until the object unloads, you can check the object’s parent before you do anything to it.

I agree, if we could do something like workspace:StreamingLock(Instance, Boolean) to set an instance being locked from streaming in/out or maybe Instance:StreamingLock(Boolean) it would probably make more sense than the current implementation and life a bit easier.

5 Likes

I’ve created a fairly large game where StreamingEnabled would be perfect to improve gameplay, as it completely obliterates client-site rendering lag. Every script was created with this in mind.

Unfortunately, whenever there are two players or more in a server, any kind of PGS constraints can become sporadically unresponsive, refusing to update position/move when target values are set, such as the TargetAngle in a HingeConstraint, or TargetPosition in a PrismaticConstraint. This behavior does not happen in a non-StreamingEnabled server.

This sounds like bug report, not an issue with the way streamingenabled is intended to be used