StreamingQueue - Queue changes to Instances that are affected by StreamingEnabled

StreamingQueue

Module | Documentation | Source Code

Introduction

StreamingQueue is the result of my need to make changes on the client from the server, even if the instance(s) I was making said changes to weren’t currently available on the client. My solution? Create a queue for each player on the server that contains instances to change, along with what property of said instance is being changed and the value of the property. Then, when the player is within the radius of the instance being replicated to the client, attempt to apply the changes. If they fail for whatever reason, just try again after a set period of time.

Use Cases (which were why I made this module)
  • I have an armory in my game. If a player has purchased a weapon, the ProximityPrompt’s text on that weapon’s display changes from “Purchase ${price}” to “Equip”. When a player joins (or when the weapon is purchased, I need to be able to change the text to reflect whether or not they own the weapon. However, the part is roughly 700 studs away from spawn. By adding it to my queue, once I get close enough the text is changed and all is good.

  • My game has customizable player rooms. In these rooms, players can purchase and place decor, walls, windows, etc. When a player enters build mode it kicks all other players out of the room and places a barrier at the entrance. This barrier is supposed to allow the room’s owner to walk through it freely while other players collide with it. However, if the barrier isn’t replicated, both the owner and other players collide.

  • My game has a crystal mining system. While one player is “harvesting” a crystal, the prompt should be disabled for all other players. However, if the prompt is not replicated to a player and then that player approaches the crystal while another player is harvesting it, they can also start interacting with it. While this does not cause any actual errors, it does mess with the gameplay. You get the idea, used the module, and now it’s fixed.

  • As you can imagine there are countless others but you get the idea.

Implementation

To start, go ahead and grab the module and place it in ReplicatedStorage. Next, create a RemoteFunction in ReplicatedStorage and name it “StreamingFunction”. Then, create a ServerScript in ServerScriptService and a LocalScript in StarterPlayerScripts.

ServerScript

local StreamingQueue = require(game:GetService("ReplicatedStorage").StreamingQueue)

StreamingQueue:Init(100) --100 is your StreamingMinRadius (see documentation for more info)

LocalScript

local StreamingFunction = game:GetService("ReplicatedStorage"):WaitForChild("StreamingFunction")

StreamingFunction.OnClientInvoke = function(object,property,value)
	local success, err = pcall(function()
		object[property] = value
	end)
	if (success) then
		return "success"
	else
		return true
	end
end

Now that we have implemented StreamingQueue, we can start using it. For example, if I wanted to disable a ProximityPrompt for every player except the one who triggered it, I would do the following:

local StreamingQueue = require(game:GetService("ReplicatedStorage").StreamingQueue)
local ProximityPrompt = workspace:WaitForChild("ExamplePrompt").Attachment.ProximityPrompt

ProximityPrompt.Triggered:Connect(function(player)
  for _, plr in game:GetService("Players"):GetPlayers() do
    if (plr ~= player) then  
      StreamingQueue:Add(plr,ProximityPrompt,"Enabled",false)
    end
  end
end)

And there we have it! The prompt will only be enabled for the player who triggers it first.

Documentation

StreamingQueue:Init(radius: number, refreshRate: number)

Init should be called once per server, most likely when the server is first created. If it is not called, the queue will never be initialized and instances added to the queue will never get changed. Init has two arguments: radius and refreshRate. Radius is your StreamingMinRadius, which is found in your workspace’s properties, under StreamingEnabled. By default, the radius is set to 100 studs. Do not make the radius larger than your StreamingMinRadius! If the radius is larger, the module will try to apply the changes before the instance exists, thus executing unnecessary code and invoking the function for no reason. However, if you want to make the radius smaller than StreamingMinRadius, that would simply mean that the module won’t apply the changes until the player is closer to the instances (which might be preferred depending on the use case). RefreshRate is how often the queue is actually checked and updated. By default, the refresh rate is set to 10.

StreamingQueue:Add(player: Instance, object: Instance, property: String, value)

Add can be called whether the module is initialized or not. However, it won’t actually take effect until the module has been initialized. Add has four arguments: player, object, property, and value. Player is which client the changes should take place on. Object is the instance that is being changed. Property is which property of said instance is being changed. Value is the new value of said property. Properties override each other out if Add is called while an instance is still in the queue. For example, if I were to set a parts transparency to 1 and then a few seconds later to 0.5 and the instance is still in the queue waiting for its transparency to be updated, then the 0.5 will override the 1.

Conclusion

In the end, I hope that others will find this module useful. I would love to add more features, please let me know if there is anything that you would like to see added. If you have any suggestions or changes, I would love to hear those as well. Thank you for reading.

Special thanks to @boatbomber and @Maximum_ADHD for their WindShake module. I used the structure of that module as an outline for this module.

Do you think this is a useful module?

  • Yes
  • No

0 voters

4 Likes

Funnily enough, just yesterday while doing some testing we shut some bulkhead doors, walked a little further and noticed that the ones further away “hadn’t closed”. They had, it just hadn’t replicated on our clients.
This is going to bail me out big time, thank you!

1 Like