Skip to content

Cross-resource calls go only through a dependency-gated dlmp.import ​

Status: Accepted (2026-07-07)

Context ​

ADR 0025 defines how one resource calls another's exports: lazy by-name resolution, marshalled plain data, reload-safe proxies. The public entry to that mechanism decides whether the dependency contract in the manifest means anything. A global table of every running resource's exports would let a resource call any other one without declaring it in [server] dependencies; dependencies would then only order the start, not say who calls whom, and an internal registry detail would look like public SDK.

Decision ​

  • dlmp.import("<resource>") is the only public entry to another resource's exports. It is allowed only for a resource listed in the caller's [server] dependencies; any other name raises a Lua error at the call site. It returns a proxy whose functions resolve lazily by name at call time.
  • import checks only the static manifest contract. Whether the target is running, whether it exports the function and whether the callee fails are checked on each call through the proxy, with the loud errors of ADR 0025. If import captured the running state, the proxy would break when the dependency reloads; checking lazily keeps it working across reloads.
  • There is no global exports table. The registry and dispatch behind the proxies are internal.
  • Unbounded recursion between resources cannot be expressed. A resource cannot import itself (a manifest may not list itself as a dependency), and a -> b -> a would be a dependency cycle, which the start rejects. The internal nesting cap of ADR 0025 stays as a defensive backstop.

Consequences ​

  • The manifest states exactly which resources a resource calls; a call to an undeclared one fails immediately and visibly.
  • A misspelled dependency fails at import; a target that is down fails at the call and recovers after its restart.
  • Typed stubs for import proxies, permissions on cross-resource calls, optional dependencies and versions are not part of this decision.

Alternatives considered ​

  • Keeping a global exports table as a compatibility shim next to import. Rejected: any second, ungated path to another resource's exports voids the dependency gate. There were no external users to keep compatible.
  • Checking the dependency on every call instead of at import. Rejected: checking the static contract once at import gives an early, clear error for a manifest typo, while the dynamic checks stay lazy and reload-safe.
  • Gating cross-resource calls with an access-control list instead of declared dependencies. Rejected for now: the declared dependency is the minimal contract of who a resource calls, and the server has no access-control model.

Documentation licensed under CC BY 4.0. DarqlineMP is not affiliated with Rockstar Games or Take-Two Interactive. Grand Theft Auto is a trademark of Take-Two Interactive Software, Inc.