Is there a better way?

I made a simple module to abstract away those weird event instances, now I don’t need to create an entire roblox instance for every event, just one, and I don’t need to call waitforchild or whatever on the remote event anymore since I can just call Post now.

But there are some things I don’t like, will the extra handler (the handler that calls the callbacks when the remote is fired) impact the code (slow it down)?
Is there a better way to abstract away remote events?

What could be done differently?

local runService = game:GetService "RunService"

local rem = script:WaitForChild "RemoteEvent"
local rf = script:WaitForChild "RemoteFunction"

local _listeners = {}
local EventService = {}

if runService:IsClient() then
	local function handle(topic, ...)
		if not _listeners[topic] then return false end
		return _listeners[topic](...)
	end
	
	rem.OnClientEvent:Connect(handle)
	rf.OnClientInvoke = handle
	--equivalent of remote events
	function EventService:Post(topic: string, ...): ()
		rem:FireServer(topic, ...)
	end
	--equivalent of remote functions
	function EventService:Get(topic: string, ...): (boolean, any?)
		return pcall(rf.InvokeServer, rf, topic, ...)
	end
else
	local function handle(player, topic, ...)
		if not _listeners[topic] then return false end
		return _listeners[topic](player, ...)
	end
	
	rem.OnServerEvent:Connect(handle)
	rf.OnServerInvoke = handle
	
	function EventService:Post(topic: string, ...): ()
		local plr = ...
		if typeof(plr) == "Instance" and plr:IsA "Player" then
			rem:FireClient(plr, topic, select(2, ...))
		else
			rem:FireAllClients(topic, ...)
		end
	end
	
	function EventService:Get(plr: Player, topic: string, ...): (boolean, any?)
		return pcall(rf.InvokeClient, rf, plr, topic, ...)
	end
end

function EventService:BindTo(topic: string, callback: (...any) -> (...any))
	if typeof(callback) ~= "function" then return end
	_listeners[topic] = callback
end

function EventService:Unbind(topic: string)
	_listeners[topic] = nil
end
--equivalent of bindable events/functions
function EventService:Invoke(topic: string, ...): (...any)
	if _listeners[topic] then 
		return _listeners[topic](...)
	end
end

return table.freeze(EventService)

Thanks in advance!

1 Like

This is honestly a downgrade since all u did is lost the organization and clarity that can be achieved using folders with remote events. You also no longer have a visible list of the RemoteEvents and Functions. It lacks support for unreliable remote events. It is also probably not compatible with multithreaded coding. I have created a system that for the most doesn’t have all these isses except the multithreading one (you would have to have an external remotes folder for that). You can see the code under the VGF module in my game framework if you are interested: https://create.roblox.com/store/asset/13799392432/Voxels-Game-Framework

This is very bad way, one remote event increases bandwidth but same design

See, strings are 1 byte per character + 2 bytes overhead, this mean if you send topic like “DoThat” you send over 8 bytes! if you do it very often, which is most likely the case, the game will lag no matter how good internet you have

It’s best to have one remote per behavior, examples:

  • ReplicateTimer
  • FollowPlayerCursor
  • ReplicateVFX
  • StartRound