core and samp-node Bidirectional Bridge

core and samp-node Bidirectional Bridge A sequence diagram generated by Archify. Load(ppData) plugin export InitializeOncePerProcess + NewIsolate CreateEnvironment(bootstrap), then dynamic import of entry_file registerEvent + on(name, trigger) OnPlayerConnect(playerid) events[name]->call, AMX args to V8 calls trigger, running the middleware chain callNative(name, fmt, args) InvokeNativeArray into open.mp spins the event loop until the promise settles returns 0 or 1 to open.mp Plugin startup and bootstrap Native callback into JS Return value to open.mp open.mp · native callbacks · Sequence participant open.mp native callbacks samp-node · events.cpp · Sequence participant samp-node events.cpp libnode V8 · nodeimpl Tick · Sequence participant libnode V8 nodeimpl Tick global samp · functions.cpp · Sequence participant global samp functions.cpp @infernus/core · bus.ts trigger · Sequence participant @infernus/core bus.ts trigger Legend request return async trace default message

What bootstrap does

  • • LoadResource spins in while(esmLoading), calling Tick and yielding each ms until the module loads
  • • bootstrap sets ipv4first, imports entry_file, then __internal_esmLoaded ends the wait
  • • Afterwards ProcessTick drives Tick each frame: microtasks, uv_run(NOWAIT), DrainTasks

How core sits on this layer

  • • core's defineEvent calls samp.registerEvent and samp.on at import time
  • • A native callback first runs convertAmxParamsToV8 to turn AMX cells into V8 values
  • • beforeEach then builds the context, so the event system is middleware over that registry

Sync bridge and boundaries

  • • Same thread: no cross-thread queue, Tick runs JS on the server main thread
  • • An async listener returns a Promise; C++ cannot await, so it spins the event loop until settled (resolve takes the boolean, reject is 0)
  • • callNative passes i/f/s/a/v and retrieves I/F/A/V/S; callPublic walks every AMX