How can i add remotes to my OOP?

but wouldn’t storing remote inside every object/model not performant? i mean imagine that every player will build artillery, i need to handle about 20+ functions of controlling this artillery movement like 12 times per second, this is a lot

1 Like

they can, but objects that they create are different, soo there will be 2 remotes, one server sided and one client sided, you need one to send and receive messages

what about having 1 object value inside every artillery that will point to a remote?

That’s what remote functions are for.

still idk if you understand me, my problem is to how store remotes, if i should use one remote and determine which artillery player uses (for example by where player is sitting) or should i use multiple remotes in every OOP object

I use this remoting class, which constructs a new remote for each route.

Client

function AvatarEditorClient:PromisePromptBuyAll(outfitInst, assetsToPurchase)
	assert(typeof(outfitInst) == "Instance", "Bad outfitInst")
	assert(type(assetsToPurchase) == "table", "Bad assetsToPurchase")

	if #assetsToPurchase == 0 then
		return Promise.rejected("0 items in order")
	end

	return self._remoting.PromiseBuyAll:PromiseInvokeServer(outfitInst, assetsToPurchase)
end

Server

function AvatarEditor:_setupRemoting()
	self._remoting = self._maid:Add(Remoting.new(self._obj, "AvatarEditor", Remoting.Realms.SERVER))

	self._maid:GiveTask(self._remoting.EquipAssetId:Bind(function(player, ...)
		return self:PromiseEquipAssetId(player, ...)
	end))
	self._maid:GiveTask(self._remoting.PopupVisibleChanged:Connect(function(player, isPopupOpen)
		assert(player == self:GetPlayer(), "Bad player")
		self._data.PopupOpen.Value = isPopupOpen
	end))

	self._maid:GiveTask(self._remoting.EquipBundleId:Bind(function(player, ...)
		return self:PromiseEquipBundleId(player, ...)
	end))
	self._maid:GiveTask(self._remoting.UnequipAssetId:Bind(function(player, ...)
		return self:PromiseUnequipAssetId(player, ...)
	end))
	self._maid:GiveTask(self._remoting.UnequipBundleId:Bind(function(player, ...)
		return self:PromiseUnequipBundleId(player, ...)
	end))
	self._maid:GiveTask(self._remoting.SetBodyColorsData:Bind(function(player, ...)
		return self:PromiseSetBodyColorsData(player, ...)
	end))
	self._maid:GiveTask(self._remoting.SetOutfitFromUserId:Bind(function(player, ...)
		return self:PromiseSetOutfitFromUserId(player, ...)
	end))
	self._maid:GiveTask(self._remoting.UnequipInventorySlot:Bind(function(player, ...)
		return self:PromiseUnequipInventorySlot(player, ...)
	end))
	self._maid:GiveTask(self._remoting.UnequipAll:Bind(function(player, ...)
		return self:PromiseUnequipAll(player, ...)
	end))
	self._maid:GiveTask(self._remoting.PromiseBuyAll:Bind(function(player, ...)
		return self:PromisePromptBuyAll(player, ...)
	end))
end
1 Like

soo you create remote per every object class and you store it in replicated storage, model or somewhere else right?

Yup. In this case, each player gets their own.

image

This really helps with security because we can do very simple assertions at the top. There’s a very small perf cost, but it’s effectively neglectable.

1 Like

last question, where do you store those remotes soo both client&server can access them at the same time and know which is which?

That’s a Configuration object, but it’s literally just there so the remotes get sorted to the bottom of the explorer.

You can use a folder or anything else.

1 Like

But you name them with player UserId or smth to determine which is correct? sorry but i never worked with OOP replication and it’s kindof yk, new…

No, I construct a new “AvatarEditor” for each player, with the object referencing the player (well, actually that Folder named “AvatarEditor”.

Then the object just does the equivalent of self._myFolder.Remotes.MyRemote:FireServer()

Note that the remoting object I linked above abstracts all of that.

1 Like

Now i understand, soo create remote events storage on server that points to specific player,object,model or anything and use references & instances to fire remotes, thx for help Quenty :}

Yeah, good luck!

Note we also just store remotes in ReplicatedStorage and fire them, but we do this OOP trick a lot too. Just depends on the scenario we’re programming for.

1 Like

I think using multiple remotes will be better because if a lot of players are using artillery at the same time the server will process them one by one which will delay feature remotes (never tested this so not sure)

you can try both methods and see which one is more performant

Single RemoteFunction or Multiple? - Development Discussion - Developer Forum | Roblox

Is there any difference in performance between one single RemoteEvent for all players or a RemoteEvent for each player? - Help and Feedback / Scripting Support - Developer Forum | Roblox

All network throughput is ultimately trafficked through the same tunnel. Whether it’s one remote, or several remotes, generally speaking there will be no difference in latency. The server processes each request serially but I’ve had test sessions suggest that they are processed in parallel. The behavior in question was two different event requests being processed at the exact same time, leading to some errors I was getting. Putting the events in a sort of queue system to be scheduled with task.wait to run fixed the issue. I have not experienced it since.

The only time using one remote to network the entire game becomes a problem is in the hands of the developer. One event for everything sounds like a beautiful wonder, but that also means developers can’t get insight on what an event specifically handles at first glance. This can create confusion especially considering if you’re going to use one event, you will most likely have some sort of id argument at the receiving end to process which type of request is being…requested.


Performance hurdles or “throttling” only come into play when the requests themselves take a while to execute. For example, if you have an event that obtains every descendant in the DataModel that has a certain name (meaning there will be a for loop and a check for Name), this will take a while to execute and return a result.

From my testing, if an event is fired and literally just has a blank function or something really simple like to increment a server variable, I have never ran into the issue of throttling even when I hooked the event on RunService.PreRender (never do this without some sort of hardcoded throttle on your end lol, i only did this for testing).

2 Likes

Yhmmm, the problem here was more of an OOP reference kind of thing, but still it’s nice to know, soo in the end more remote events are the same as one? or is it different? ik there can be little bit more performance due to no need for id and stuff, but still?

In general, I would still use separate remotes for everything, and have some sort of Event library handle requests as if everything was just one singular event. For example,

If you had some sort of reference to your Event library like this,

local Event = require(script.Event)

…and you wanted to, say fire to topic FireWeapon,

Event:Fire("FireWeapon", ...)

…and on the libraries end, it can parse this request to figure out which event to use. Generally, for my work, I have the library fallback to a singular event with an id argument if the topic is not recognized as a specific event so the request can still be received by the client/server. If an event with a name matching the requested topic is found, it will use that event instead.


For consistency, you would also want to implement a way to listen for these topics, from the fallback event or from a specific event. Your specified Event library could handle this as well,

Event:Listen("FireWeapon", function(...: any?)
    -- Do sum work
end)
1 Like

yhmmm, still using invidual remote per player seems more performant in terms of organisation/references, anyways thx for help

1 Like

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