OPX//77
opx_infinityConcepts

Events and channels

Last updated on

The three event prefixes opx_infinity uses (opx:net, opx:on, opx:in), who can hear each one, and how to build a name with OPX.Event.

Every event name starts with one of three prefixes, which say who may raise it and who can hear it. Build names with OPX.Event(channel, module, verb) instead of typing them, so a typo fails at load.

The three prefixes

PrefixOPX.ChannelTravelsUse it for
opx:net:<module>:<verb>NETacross the network, client ↔ serverrequests from a client, answers and pushes from the server
opx:on:<module>:<verb>LOCALinside one runtime, publicannouncing something other modules may react to
opx:in:<module>:<verb>INTERNALinside one runtime, privateone module's own halves, or core to modules
local SAY = OPX.Event(OPX.Channel.NET, 'chat', 'say')   -- 'opx:net:chat:say'

Each module lists its names in module.lua as M.Event; each module's events page lists its opx:net: and opx:on: names.

Why three prefixes

The host matches handlers on the name only. A local TriggerEvent on a name that also has a RegisterNetEvent handler would run the network handler too. Separate network and local names make that impossible.

Who can hear what

Raised withOn the serverOn the client
TriggerEvent (opx:on:, opx:in:)every running server resource that handles the namethis resource only
TriggerClientEvent (opx:net:)—the opx_infinity client of that player
TriggerServerEvent (opx:net:)the server handler, source set by the platform—
  • A separate client resource cannot hear opx_infinity's opx:on: events: on the client, TriggerEvent stays inside one resource.
  • A separate server resource hears server-side events. The public ones are raised with OPX.Publish and listed on Public server events.

Server opx:in:* events are visible to every server resource

Server TriggerEvent is host-wide, so the private opx:in:* events also reach other resources, and another resource can raise them. Treat a server opx:on: or opx:in: handler as callable by any resource on the server, and never put a secret in an opx:in: payload. Outside code should use only the opx:on:* names.

On the server, raise a public event with OPX.Publish(name, playerId, payload), never a bare TriggerEvent: it checks the opx:on: prefix and never raises.

Network events are requests

  • A RegisterNetEvent handler gets source from the authenticated connection. Everything else in the payload comes from a machine the player controls: re-check it (Server authority).
  • Platform limit: at most 32 arguments in a 48 KiB envelope.

Host events

Platform-owned names are listed once in OPX.Host (core/shared/channels.lua). The two runtimes use different names for resource start and stop.

OPX.Host keyName
PLAYER_CONNECTEDonPlayerConnected
PLAYER_DISCONNECTEDonPlayerDisconnected
PLAYER_READYonPlayerReady
CLIENT_RESOURCE_START / CLIENT_RESOURCE_STOPonClientResourceStart / onClientResourceStop (client)
RESOURCE_START / RESOURCE_STOPonResourceStart / onResourceStop (server)
WORLD_READYopen77:worldReady
GAMEPLAY_READYopen77:session:gameplayReady
VEHICLE_REMOVEDonVehicleRemoved
TUNABLE_CHANGEDonTunableChanged
KEYBINDS_CHANGEDopen77:keybinds:changed (client: a key mapping was registered, rebound, reset or removed)

Who uses each one: Runtime events.

Hooks: events that can say no

When another module must be able to veto something (for example money being added), use OPX.Hooks instead of an event. A hook runs in the same VM, in priority order, and any handler may refuse. The hooks the framework triggers are on the character page.

Page channels

The WebUI page talks to Lua on a separate set of names, such as menu:choose. They are not events — see The WebUI page.

On this page