OPX//77
opx_infinityCore

Shared

Last updated on

The OPX.* runtime on both sides — module registry and lifecycle, contracts, event names, time, the scheduler, runtime values and the boot order.

The core is opx_infinity/core/. It loads before every module and gives them one shared OPX table. Everything on this page exists in both VMs. Server-only functions are on Server, client-only ones on Client; the lib/ helpers (OPX.Result, OPX.Storage, OPX.Hooks, OPX.Locale…) on Shared library.

Values

NameSideTypeNotes
OPX.VERSIONbothstringThe manifest version, read from the host (Open77.resource.version() on the client, the manifest metadata on the server). Falls back to the literal in core/shared/main.lua.
OPX.IsServerbothbooleantrue in the server VM (TriggerClientEvent exists).
OPX.IsClientbothbooleantrue in the client VM (TriggerServerEvent exists).
OPX.ConfigbothtableSHARED, MODULES, and SERVER (server only) or CLIENT (client only). See Configuration.
OPX.Channelbothtable{ NET = 'net', LOCAL = 'on', INTERNAL = 'in' }. Pass one to OPX.Event.
OPX.HostbothtableHost event names. See Host events.
OPX.Glyphsbothtable<string, true>The closed set of icon names the page can draw (interact, person, vehicle, lock, money, warning, …). Toasts, refusals and command notices only accept these.

Server-only values (OPX.Booted, OPX.BootError, OPX.Sessions): Server. Client-only OPX.Lib: Client.

Modules

A module declares itself in modules/<id>/module.lua and hangs Init, Api, Start and Stop on the table it gets back (Modules and contracts).

Module states: declared, started, failed, disabled, absent, unavailable, stopped.

OPX.Modules.Declare

Declares a module and returns its namespace.

OPX.Modules.Declare(spec)

Parameters

  • spec: table
    • id: string
    • side?: 'server' | 'client' | 'both' — default 'both'
    • requires?: string[]
    • optional?: string[]
    • fatal?: boolean

Returns

  • table — the module namespace (M)

  • Raises on a missing id, a duplicate id, an unknown side, or a call after the modules were resolved.

  • A module with enabled = false in its config is marked disabled; one for the other side is absent.

Example
local M = OPX.Modules.Declare{ id = 'thing', side = 'server', requires = { 'character' } }

OPX.Modules.Get

The module's namespace (what its files write into).

OPX.Modules.Get(id)

Parameters

  • id: string

Returns

  • table?

OPX.Modules.Record

The runtime's record of a module, separate from its namespace.

OPX.Modules.Record(id)

Parameters

  • id: string

Returns

  • table? — Id, Side, Requires, Optional, Fatal, Provides, Module, State, Reason

OPX.Modules.All

Every record, in declaration order.

OPX.Modules.All()

Returns

  • table[]

OPX.Modules.IsRunning

true only when the module's state is started in this VM.

OPX.Modules.IsRunning(id)

Parameters

  • id: string

Returns

  • boolean

OPX.Modules.Settings

OPX.Config.MODULES[id], read now.

OPX.Modules.Settings(id)

Parameters

  • id: string

Returns

  • table — never nil ({} when the module has no config)

OPX.Modules.Rebind

Points every module's Settings field at its live config. Called once by Resolve.

OPX.Modules.Rebind()

OPX.Modules.Resolve

Orders the modules by dependency. Memoised. Raises on a dependency cycle. Marks disabled and unavailable modules.

OPX.Modules.Resolve()

Returns

  • table[] — records in dependency order

OPX.Modules.Resolved

Whether Resolve has run.

OPX.Modules.Resolved()

Returns

  • boolean

OPX.Modules.Run

Runs Init, Api, Start over every runnable module. Yields between modules: call it from a thread. Boot calls it; a module never does.

OPX.Modules.Run(between)

Parameters

  • between?: function — runs after Api and before Start; if it raises, Run answers false, <error>.

Returns

  • ok: boolean
  • failure?: string — 'already ran' on a second call, or the id of a fatal module that failed

OPX.Modules.Stop

Calls Stop on every started or failed module, newest dependency first. A module is marked stopped before its Stop runs, so a second stop cannot run it twice. A Stop that raises is logged.

OPX.Modules.Stop(yielding)

Parameters

  • yielding?: boolean — true waits a frame after each Stop when the caller can yield, so each module gets a fresh instruction budget. The client passes true; the server passes nothing.

OPX.Modules.Report

One line per module: id, state, reason.

OPX.Modules.Report()

Returns

  • string[]

Contracts

OPX.Api.Provide

Publishes a contract. Call from a module's Api phase.

OPX.Api.Provide(name, version, implementation)

Parameters

  • name: string
  • version: integer
  • implementation: table

Raises on bad arguments, or if two modules provide the same name.

Example
function M.Api()
	OPX.Api.Provide('thing', 1, { DoIt = function(source) end })
end

OPX.Api.Get

Reads a contract. Use it for an optional dependency.

OPX.Api.Get(name, minimum)

Parameters

  • name: string
  • minimum?: integer

Returns

  • table? — nil when nobody provides it, or the version is below minimum
  • version?: integer
Example
local downed = OPX.Api.Get('downed')
if downed then ... end

OPX.Api.Require

Like Get but raises when absent. For a module that lists the provider in requires.

OPX.Api.Require(name, minimum)

Parameters

  • name: string
  • minimum?: integer

Returns

  • table

OPX.Api.Versions

Every published contract.

OPX.Api.Versions()

Returns

  • table<string, integer> — name → version

OPX.Api.Withdraw

Withdraws every contract a module published. Called by the lifecycle when a module fails.

OPX.Api.Withdraw(owner)

Parameters

  • owner: string — module id

Returns

  • string[] — names withdrawn

Events

OPX.Event

Builds opx:<channel>:<module>:<verb> (Events and channels).

OPX.Event(channel, module, verb)

Parameters

  • channel: 'net' | 'on' | 'in' — use OPX.Channel; anything else raises
  • module: string
  • verb: string

Returns

  • string
Example
local SAY = OPX.Event(OPX.Channel.NET, 'chat', 'say') -- 'opx:net:chat:say'

OPX.Publish (server) raises public events: Server.

Time

OPX.Now

Monotonic milliseconds: GetGameTimer() when present, else Open77.time.monotonic() * 1000. Not wall-clock time.

OPX.Now()

Returns

  • integer — ms

Scheduler

Same names on both sides, different behaviour (The scheduler). OPX.Scheduler.Start is client only: Client.

OPX.Scheduler.Every

Runs step repeatedly.

OPX.Scheduler.Every(name, intervalMs, step)

Parameters

  • name: string — for log lines, <module>.<purpose>
  • intervalMs: number | function
  • step: function

Returns

  • integer — handle

  • Server: one thread per job; intervalMs is a number or a function re-read every pass; floor 50 ms; first pass one interval after registration; a raising job is logged once per run of failures and never suspended.

  • Client: one shared loop, at most 4 due jobs per pass; intervalMs must be a number >= 0 (a function or bad value raises; 0 = every pass); a job that raises 3 times in a row is suspended.

Example
M.sweep = OPX.Scheduler.Every('thing.sweep', 1000, function() ... end)

OPX.Scheduler.Cancel

Stops a job. Safe on a handle already cancelled.

OPX.Scheduler.Cancel(handle)

Parameters

  • handle: integer

OPX.Scheduler.Report

One line per job: name, interval, state.

OPX.Scheduler.Report()

Returns

  • string[]

OPX.Scheduler.Stop

Stops every job and drops the list. Boot calls it on resource stop.

OPX.Scheduler.Stop()

Creator export gate

core/shared/exports.lua, both sides. The scaffolding the server and client creator exports share: who is calling, whether they are admitted, and the answer shape. One copy, so the two halves cannot disagree about who may call. Use it only if you add an export to core/*/exports.lua.

OPX.Export.Ok

OPX.Export.Ok(value)

Returns

  • { ok = true, value } — value may be nil

OPX.Export.Refuse

OPX.Export.Refuse(code)

Returns

  • { ok = false, error = code }

OPX.Export.Answered

A contract Result as the export answer: the value on success, the code on a refusal, error.unavailable for anything that is not a Result.

OPX.Export.Answered(result)

Returns

  • { ok, value | error }
Example
return OPX.Export.Answered(OPX.Api.Get('weather').SetWeather(name))

OPX.Export.Admits

Whether an allowlist admits a caller.

OPX.Export.Admits(list, caller)

Parameters

  • list: '*' | table — '*', a set ({ my_res = true }) or an array of names
  • caller: string

Returns

  • boolean

OPX.Export.IsResourceName

Whether a string could be a resource name: [%w_%-%.], 1 to 64 characters.

OPX.Export.IsResourceName(name)

Returns

  • boolean

OPX.Export.Caller

The calling resource as the host reports it (GetInvokingResource), or nil when that is not a valid name. Never take a caller name from an argument.

OPX.Export.Caller()

Returns

  • string?

OPX.Export.Available

Whether the host offers exports. On Open77 exports is a callable table, so a function, a table or userdata all count. (Before PR #58 only a function counted, and no creator export was published.)

OPX.Export.Available()

Returns

  • boolean

Boot order

SideSequence
serverPlacement-conflict warning → database probe (OPX.Storage.Ready) → Init → Api → OPX.Tune.Publish and OPX.Schema.Apply (skipped with no database) → Start → OPX.Booted = true → module report in the log. On resource stop: OPX.Scheduler.Stop, OPX.Modules.Stop, then every player is released from a selection bucket.
clientOn onClientResourceStart: OPX.UI.Surface, OPX.Toast.Attach → OPX.Modules.Run → OPX.Scheduler.Start → module report. Boot yields between the surface build and Modules.Run. On stop: OPX.UI.ReleaseAllFocus first, then OPX.Scheduler.Stop, OPX.Modules.Stop(true), OPX.UI.Teardown.

On this page