Skip to content

Custom Bridges

Implement a custom adapter with the actual client/server and failure contracts.

This page is for a developer integrating an unsupported or modified provider. Standard server installations should use Standard Providers. Edit sources in 0r-restaurant/modules/bridge/ and restart the main resource and required providers safely after the integration is ready.

Entry points and results#

Only boolean enabled = true selects an optional custom adapter. false, missing values and strings such as 'true' do not select it. A selected custom provider's failure does not trigger a second attempt through a built-in provider.

File under modules/bridgeSideContract
textui/custom/client.luaClientshow(message: string) must return true after displaying it; hide() closes only its owned prompt
progress/custom/client.luaClientrun(options: table) waits and returns boolean true only on completion, false on cancellation; cancel() must stop/unblock the pending run
notify/custom/client.luaClientshow(options: table) forwards the formatted notification; false or a thrown error reports failure, while a normal non-false result is accepted
target/custom/client.luaClientaddZone(zoneId, zone) returns a removable handle; addLocalEntity(entity, options) returns true on success; matching remove methods clean only these registrations
vehicle_keys/custom/server.luaServergive(source, vehicle) and remove(source, vehicle) receive a player server ID and server entity handle; return boolean true only after success, otherwise the key operation fails
inventory/custom/server.luaServerImplement all required exact-slot, metadata, capacity, item-change and storage operations documented beside each method
effects/server.luaServerAdapt supported hunger/thirst and allowed numeric effects; report uncertainty rather than applying them again

Framework integrations live in the selected framework/ provider files. Keep identity, account changes and item ownership on the server. No adapter may turn client-supplied metadata into authority.

Small working TextUI example#

This example uses ox_lib to demonstrate the custom hook. The delivered Ox adapter already provides this behavior, so ordinary Ox installations do not need this replacement. In modules/bridge/textui/custom/client.lua:

lua
-- Demonstrates the custom TextUI contract with the installed ox_lib provider.
TextUIAdapters = TextUIAdapters or {}
local owned = false

TextUIAdapters.custom = {
    enabled = true,
    resourceName = 'ox_lib',
    show = function(message)
        if GetResourceState('ox_lib') ~= 'started' then return false end
        local ok = pcall(lib.showTextUI, message)
        owned = ok
        return ok
    end,
    hide = function()
        if not owned then return true end
        local ok = pcall(lib.hideTextUI)
        owned = false
        return ok
    end,
}

Restart main, then approach a published TextUI point as an allowed player. Check that the prompt appears and closes when you leave.

Inventory integration requirements#

A custom inventory must read the full item and metadata from the exact slot. Removing or restoring an item must use that slot. A space check must leave inventory unchanged. Return false from an item change only when you know no change occurred.

A slot read must distinguish an empty slot from a failed read. Check any item in that slot, including unrelated items, before restoring something into it.

Item-use callbacks must pass the actual slot and leave Restaurant in control of consumption. Supply purchases must charge the character who started the purchase and report the money change when it happens. Avoid adding a separate retry or refund system.

A custom inventory must support the required storage access checks. Restaurant keeps storage closed when it cannot use them. Use Restaurant Storage rather than opening an old inventory stash.

Progress, targets and notifications#

Custom progress must return true only after completion and must cancel/unblock when asked. A non-boolean result is invalid. Visual completion never overrides the server timer.

Custom targets must report whether they were added and remove their own interactions when an object disappears. A custom TextUI must close its own prompt without closing another script's prompt.

Custom notification providers should honor supplied type, description, title, duration and sound options. New paid-order alerts use these sound options. Errors/warnings also print to F8 independently from notification delivery.

Consumption effects#

Use the effects adapter for the hunger/thirst system installed on your server. Custom status fields need a matching implementation in modules/bridge/effects/server.lua.

Apply each food effect once after consumption. If part of an effect fails, report the error rather than consuming, refunding or applying effects again. Ensure the original character is still active if the integration waits for another resource.

Verify a custom provider#

After restarting, check the feature connected by your adapter. If it fails, keep the first error and the provider version for support. Check the original money or item result before repeating a failed transfer.

See Inventory Setup, Public Exports and Recovery for the corresponding consumer and failure paths.

Where custom adapters live#

Use the matching files in the entry-point table above. Enable only the adapter you have implemented and checked; keep the standard provider selected otherwise.

Inventory method signatures#

The custom inventory methods run on the server. A receipt contains the provider item name, amount and full metadata. Keep the installed file's documented receipt fields.

MethodResult and failure meaning
getItems(playerId, itemName)Full live slot entries; {} confirms none, nil means read failure. A total count is insufficient
getSlot(playerId, slot)The item in that exact slot, false for a confirmed empty slot, nil for read failure
canCarryItem(playerId, receipt)Boolean capacity result, with no item mutation
addItem(playerId, receipt, slot?)true after success; false only if nothing changed. Honor an optional restoration slot and preserve metadata
removeItem(playerId, receipt, slot)Remove only the supplied slot; true after success, false only if nothing changed
Optional cashAccount(source, ownsCharacter)Bound read/debit/credit functions for Supply cash; each must check the original character and immediately reflect confirmed changes

Do not catch a possibly applied item write and report false as a definite rejection. Let unexpected write errors reach the owning transfer handler. Storage also needs the documented installStorageHooks, readStorage, openStorage, closeStorage and removeStorageHook methods; absent capabilities keep it closed. Its access hooks must check opens and moves/swaps, not only the visible menu.