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 IEconomyImplementing 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 EconomyServiceThe Core Contracts
These contracts are defined in shiva-core and implemented by the default modules:
| Contract | Default Provider | Purpose |
|---|---|---|
IPlayer | shiva-player | Player data, characters |
IEconomy | shiva-economy | Cash, bank accounts |
IJobs | shiva-jobs | Jobs and grades |
IGangs | shiva-gangs | Gang membership |
IInventory | shiva-inventory | Items, stashes |
IVehicles | shiva-vehicles | Owned vehicles |
IWeapons | shiva-weapons | Owned weapons |
ICommands | shiva-commands | Chat commands |
INotifications | shiva-notifications | Player 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.