Range for RequestStreamAroundAsync is too small

I am working on a birds-eye placement system for my game. This system will be able to place the player’s camera in the sky, and then reposition itself around the map. The issue with this is that the player will be able to (should be able to) move their camera far enough that the camera is outside the streaming radius of their character. To fix this, I have the game request streaming around the camera once every 10 seconds while the system is active.

The issue with this is that the range is really small, and there is no argument in the function to specify how big we want the radius to be. I could in theory request a grid around the camera to get maximum coverage, but I’m concerned that this may cause performance issues for both the client and server. Is there a better way to do this? I would like to avoid simply teleporting the character itself if possible, as this would cause massive problems for the anticheat.


Edit: We came to a conclusion on the best way to handle this, this is the code below if anyone else has this issue:

Server:

--Services
local rs = game:GetService("ReplicatedStorage")

--Remotes (you need to create and name these in replicatedStorage. Anywhere inside is fine.
--StreamRequest should be a remoteEvent, getPos should be a remoteFunction)
local StreamRequest = rs.ClientCustomStreamRequest
local getPos = rs.RequestStreamLocation

--References
local StreamObjects = Instance.new("Folder")
StreamObjects.Name = "StreamObjects"
StreamObjects.Parent = workspace

--Runtime
local ActiveStreamers = {}


--Connections
StreamRequest.OnServerEvent:Connect(function(plr, status)
	if status then
		--dont double activate
		if ActiveStreamers[plr] then return end
		
		--insert streamer
		local focusPart = Instance.new("Part")
		focusPart.Size = Vector3.new(0.0001,0.0001,0.0001)
		focusPart.CanCollide = false
		focusPart.CanQuery = false
		focusPart.CanTouch = false
		focusPart.Anchored = true
		focusPart.Transparency = 1
		focusPart.CollisionGroup = "NoColProjectile"
		focusPart.Parent = StreamObjects
		
		--apply focus
		ActiveStreamers[plr] = focusPart
		plr.ReplicationFocus = focusPart
		
		--stream function
		task.spawn(function()
			while ActiveStreamers[plr] do
				task.wait(2)

				local pos = getPos:InvokeClient(plr)
				if typeof(pos) ~= "Vector3" then return end
				pos = pos * Vector3.new(1,0,1)
				focusPart.Position = pos

				print("updated stream")
			end
		end)
	else
		--remove streamer
		if not ActiveStreamers[plr] then return end
		ActiveStreamers[plr]:Destroy()
		ActiveStreamers[plr] = nil
		plr.ReplicationFocus = nil
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	if ActiveStreamers[plr] then
		ActiveStreamers[plr]:Destroy()
		ActiveStreamers[plr] = nil
	end
end)

Client:

--Remote (same one from before)
local RetrieveRequest = game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("RequestStreamLocation")

--References
local Camera = game.Workspace.CurrentCamera

--Connection 
RetrieveRequest.OnClientInvoke = function()
	return Camera.CFrame.Position
end

To toggle from the client, fire the ClientCustomStreamRequest remote with true or false, depending on if you want to turn it on or off

2 Likes

Unfortunately not at the moment from what I’ve seen and used since streaming is mostly dependent on client resources. I think your best bet would be to go with a transition that includes blurring, or a loading screen, etc.

Edit: after looking at robloxs replication foci, it seems you can combine the loading screen with ReplicationFocus to pre-stream the area before the camera moves to that area.

2 Likes

The issue is that the camera will be constantly moving with mouse movement. the camera starts out above the player (normal) then the player can move the camera to wherever they want via mouse movement (streaming issues when far away)

I need to constantly load the area around the camera at all times, pretty much exactly the same way the character works. It looks like ReplicationFocus could do the trick, but that means I need to set it on the server. I would need to create a script on the server, with the sole purpose of placing and repositioning a focus part based on client request.

Assuming this is my only viable option, i would need to:

  • Create a script on the server
  • have the server create a part on client request, then set the player’s replicationFocus to that part
  • ask the client every few seconds to reposition the part

This just seems like a really roundabout way to do this. Why do i need a part, why cant i just use a position? Why cant i request this from the client, why does it need to happen on the server? why cant i just have a distance parameter for the RequestStreamAroundAsync() function? I hope they fix these in the future. Im going to try to implement the above, but i wish there was a better way

2 Likes

I don’t exactly know how your game works and all of that, but depending on camera or character position, can’t you just weld constraint a massless non-collideable part to the camera or character instead of creating new parts on the server for every clients request? Scaling up it wouldn’t be too bad on performance, but it would be unnecessary I’d think.

The streaming functions are very limited yeah, I hope you’re able to find some way to do what you’re doing though. Could also just turn StreamingEnabled off and write your own culling module, that is if you’re not dealing with terrain

1 Like

I tried creating a part on the client and then setting the replicationfocus to that part, but all that did was force a content loading screen whenever the camera went outside of the regular streaming radius. Looking at the API, it seems that setting replicationFocus only works properly when set on the server. This means that a request has to be made to the server, a part has to be made on the server, and the part likely has to be in the workspace (ill test this). Overall not that great lol

Edit: While this method is not at all ideal, it is effective. The major issue with it is that it requires the existence of a part on the server, which makes it clear to all other clients where the client in question is looking (giving information to cheaters).

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.