Skip to main content
Element Labs products work with the resources listed on Supported server resources. If your server runs a framework, inventory or interface system that is not on that list, a product that needs it reports that no supported adapter was detected and stops. You can supply the implementation yourself, from the resource that provides it. Nothing to compile, no file from the SDK to include, and no separate resource to keep in sync with your framework. This page is the contract: what you write, and exactly what your resource must return.
You only need this page when a product stops on a missing adapter. If your resources are on the supported list, there is nothing to declare.

Declare it

One manifest line and one export.

Framework

The one contract with a shape you cannot guess.

Everything else

Notify, target, menu, input, progress, fuel, database, inventory.

Contract

1

Name the capability in the resource manifest

Add one line to the fxmanifest.lua of the resource that implements the capability:
fxmanifest.lua
The line is repeatable: one per capability the resource covers.
2

Export the implementation

Add one export, anywhere in that resource’s Lua:
domain is the value you wrote in the manifest, so one export can serve several capabilities.
3

Restart and read the console

The product calls the export the first time it needs the capability, and checks your table once against the whole contract. Every method that is still missing is printed on one line, naming your resource. Add them and restart until the line is gone.
There is no partial implementation. Either the table satisfies the whole contract, or the product does not run: a missing method stops the product on the server rather than failing later at the call that needed it.
A declared implementation wins over the supported list, for that capability only. Remove the manifest line to go back to the list.

Inputs

The value of element_adapter is the capability’s lowercase name, and the same value arrives as the export’s domain argument. A capability lives on one side of the server, or on both:

Covering several capabilities

The manifest line is repeatable, and the export branches on domain:
fxmanifest.lua
A branch that matches nothing returns nil, which the product reports as a returned-nothing error. See Errors.

Client and server sides of one capability

framework is one capability with two method lists. If a product uses it on the server too, your export is checked against the server list as well. The two sides read the export from separate Lua states. To give each side its own methods, register the export from that side’s own file (client/ and server/); registered from one shared file, the same table has to satisfy both contracts at once.

What to return: the framework

getSnapshot

One table describing the local player, or nil while no character is loaded:
On a framework without gangs, gang stays nil.

A job or gang group

The job and gang values share one shape, on both sides:

Client methods

Who the player is: What the player sees: What changed. Each of these returns a function that unsubscribes the callback:

Server methods

Players and identity: Jobs and duty: State and health: Money: Vehicles, items and commands: What changed. Unlike the client events, these return nothing: A player record is:

What to return: the other adapters

These contracts are short, and the values you return are the ones your resource already speaks. The tables below give the method names and the shapes that are not obvious.
Start from the error. Add the manifest line, return an empty table, restart, and the product names every method that side expects for your SDK version. Implement until the message is gone.

Notify

Help text

Progress

Fuel

Input

Target

Each option in an options array is { name?, label, icon?, distance?, items?, groups?, canInteract?, onSelect }, and onSelect receives the entity handle.

Database

Inventory

serverOpenInventory opens an inventory for a player from the server. Most inventory resources have no way to do that, and products treat it as optional, but a declared adapter is checked against the whole list, so define it even if it does nothing.

Outputs

The product reads your answers on the first use of the capability and keeps a copy. It re-reads the whole export when you trigger the change event with the capability name:
Without the event, the copy is used for five seconds and the next use after that re-reads the export. If your resource stops, the product forgets the implementation and chooses again the next time it needs the capability.

Errors

Each of these stops the product on the server and prints once, naming your resource. A client cannot stop its own resource, so when a client-side capability fails the product also prints that the capability is unavailable for the rest of the session, and stops on the server side the next time it needs the same capability.

Example

A complete starting point for a framework’s client side, ready to fill in. Every method is present, so the contract check passes and you can replace the bodies one at a time:
client/adapter.lua
Fill each method from your resource’s own data, restart the resource and the product, and read the console. The message lists exactly what is still missing, so the loop converges.