Skip to content

Contracts

A contract is an interface — a named set of methods that a module promises to provide. Contracts are the language modules use to talk to each other.

Why Contracts

Without contracts:

  • Module A directly requires Module B's code
  • Module B changes → Module A breaks
  • You can't swap Module B without touching Module A

With contracts:

  • Module A depends on a contract (IEconomy)
  • Module B declares it provides IEconomy
  • You can replace Module B with any other module that provides IEconomy

Defining a Contract

Contracts are Lua tables that define a method signature (used for documentation and optional runtime checking):

lua
-- shared/contracts/IEconomy.lua
---@class IEconomy
local IEconomy = {}

--- Get a player's balance for an account
---@param playerId number
---@param account string
---@return number
function IEconomy:getBalance(playerId, account) end

--- Add money to a player's account
---@param playerId number
---@param account string
---@param amount number
---@return boolean
function IEconomy:addMoney(playerId, account, amount) end

--- Remove money from a player's account
---@param playerId number
---@param account string
---@param amount number
---@return boolean
function IEconomy:removeMoney(playerId, account, amount) end

return IEconomy

Implementing a Contract

lua
-- server/services/EconomyService.lua
---@implements IEconomy
local EconomyService = {}

function EconomyService:getBalance(playerId, account)
    return DB:scalar('SELECT amount FROM accounts WHERE player_id = ? AND account = ?', playerId, account) or 0
end

function EconomyService:addMoney(playerId, account, amount)
    -- implementation...
    return true
end

function EconomyService:removeMoney(playerId, account, amount)
    -- implementation...
    return true
end

return EconomyService

The Core Contracts

These contracts are defined in shiva-core and implemented by the default modules:

ContractDefault ProviderPurpose
IPlayershiva-playerPlayer data, characters
IEconomyshiva-economyCash, bank accounts
IJobsshiva-jobsJobs and grades
IGangsshiva-gangsGang membership
IInventoryshiva-inventoryItems, stashes
IVehiclesshiva-vehiclesOwned vehicles
IWeaponsshiva-weaponsOwned weapons
ICommandsshiva-commandsChat commands
INotificationsshiva-notificationsPlayer notifications

Replacing an Implementation

Provide the same contract in your module's manifest.lua:

lua
return {
    name = 'my-custom-economy',
    provides = { 'IEconomy' },
    requires = { 'IPlayer' },
}

Shiva will use your module's binding instead of shiva-economy.

See Also

Released under the MIT License.