Port → Creating Ports
Creating Ports
Call app:Listen(name, callback, settings?) to register a named port. The callback receives the port's own App-like instance — a fully isolated pipeline with its own RemoteEvent, Router, and TokenBucket.
Signature
app:Listen(name: string, callback: (port) → (), settings?: PortSettings) → Port
| Parameter | Type | Description |
|---|---|---|
name | string | Unique port identifier — must match the name used on the client |
callback | (port) → () | Called immediately with the port instance. Register routes inside. |
settings | PortSettings? | Optional TokenBucket configuration (see Port Settings) |
Port API
The port instance exposes the same routing interface as App:
port:Get(route, handler)
port:Post(route, handler)
port:Put(route, handler)
port:Delete(route, handler)
port:Use(id, fn) · port:Unuse(id)
port:Push(player, event, data) · port:PushAll(event, data) · port:PushTo(players, event, data)
Combat port example
local RoExpress = require(game.ReplicatedStorage.RoExpress)
local app = RoExpress.GetApp()
app:Listen("combat", function(port)
port:Post("shoot/:targetId=number", function(req, res)
res:Send(handleShoot(req.player, req.params.targetId))
end)
port:Post("reload", function(req, res)
res:Send(handleReload(req.player))
end)
end, {
maxTokens = 20,
refillRate = 10,
})
Getting a port reference later
If you need to add routes or call push methods from outside the Listen callback, use app:GetPort(name).
app:GetPort(name: string) → Port
local combatPort = app:GetPort("combat")
combatPort:Get("status", function(req, res)
res:Send("ok")
end)
Isolation. Each port creates its own RemoteEvent in ReplicatedStorage under a name derived from the port name. Requests to the "combat" port never share bandwidth or rate-limit tokens with the main App channel or other ports.
See also
← Port · Using Ports | client-side access · Port Settings | TokenBucket configuration · Router | route syntax available inside ports · Gun Example | combat port in full context