tw.fw (Framework Bridge)
Side: Shared (Client + Server)
Cross-framework abstraction layer. Auto-detects the installed framework and provides a unified API for player data, inventory, money, and jobs.
Alias: tw.fw is a shorthand for tw.framework. Both are interchangeable.
Supported frameworks: VORP, RSG v1/v2, QBCore RedM, QRCore, RedEM:RP (old and 2023), RPX, TPZ-CORE, FRP.
Framework Detection
tw.fw:get()
Returns the detected framework identifier string.
Returns: string (e.g. "vorp", "rsg", "qbcore", "redemrp", etc.)
tw.fw:is(name)
Checks if the current framework matches the given name.
| Parameter | Type | Description |
|---|---|---|
name | string | Framework identifier to check |
Returns: boolean
Player Data (Server)
tw.fw:getUser(source)
Returns a UserClass object for the player.
| Parameter | Type | Description |
|---|---|---|
source | integer | Player server ID |
Returns: UserClass (see UserClass Methods below)
tw.fw:getUserIdentifiers(source)
Returns the player's identifiers without creating a full UserClass.
| Parameter | Type | Description |
|---|---|---|
source | integer | Player server ID |
Returns: table — { identifier = string, charid = string|integer }
tw.fw:getJob(source)
Returns the player's current job name.
| Parameter | Type | Description |
|---|---|---|
source | integer | Player server ID |
Returns: string
tw.fw:getRPName(source)
Returns the player's roleplay name (first + last name).
| Parameter | Type | Description |
|---|---|---|
source | integer | Player server ID |
Returns: string (e.g. "John Smith")
tw.fw:getSteamIdentifier(source)
Returns the player's Steam identifier.
| Parameter | Type | Description |
|---|---|---|
source | integer | Player server ID |
Returns: string ("steam:xxxx" or "Unknown")
tw.fw:onCharacterSelected(cb)
Registers a callback fired when a player selects a character.
| Parameter | Type | Description |
|---|---|---|
cb | function(source) | Callback receiving the player server ID |
Player Data (Client)
tw.fw:getMyIdentifiers()
Returns the local player's identifiers.
Returns: table — { identifier = string, charid = string|integer }
Money (Server)
tw.fw:addMoney(source, amount, moneyType)
Adds money to a player.
| Parameter | Type | Description |
|---|---|---|
source | integer | Player server ID |
amount | number | Amount to add |
moneyType | integer | 0 = dollar, 1 = gold, 2 = rol |
tw.fw:removeMoney(source, amount, moneyType)
Removes money from a player.
| Parameter | Type | Description |
|---|---|---|
source | integer | Player server ID |
amount | number | Amount to remove |
moneyType | integer | 0 = dollar, 1 = gold, 2 = rol |
tw.fw:canUserBuy(source, amount, moneyType, removeIfCan?)
Checks if a player can afford a purchase. Optionally removes the money if they can.
| Parameter | Type | Default | Description |
|---|---|---|---|
source | integer | — | Player server ID |
amount | number | — | Price to check |
moneyType | integer | — | 0 = dollar, 1 = gold, 2 = rol |
removeIfCan | boolean? | false | If true, deducts the money when affordable |
Returns: boolean
tw.fw:canUserPayWith(source, prices, removeIfCan?)
Checks if a player can afford a multi-currency purchase.
| Parameter | Type | Default | Description |
|---|---|---|---|
source | integer | — | Player server ID |
prices | table | — | Array of { amount, moneyType } entries |
removeIfCan | boolean? | false | If true, deducts all amounts when affordable |
Returns: boolean, integer|nil — success flag, and the index of the first failed currency if not affordable.
tw.fw:refundUserWith(source, prices)
Refunds a multi-currency purchase.
| Parameter | Type | Description |
|---|---|---|
source | integer | Player server ID |
prices | table | Array of { amount, moneyType } entries (same format as canUserPayWith) |
Inventory (Server)
tw.fw:giveItem(source, item, quantity, meta?)
Gives an item to a player.
| Parameter | Type | Default | Description |
|---|---|---|---|
source | integer | — | Player server ID |
item | string | — | Item name |
quantity | integer | — | Amount to give |
meta | table? | nil | Item metadata |
Returns: boolean — false if the player has no room.
tw.fw:removeItem(source, item, quantity, meta?)
Removes an item from a player.
| Parameter | Type | Default | Description |
|---|---|---|---|
source | integer | — | Player server ID |
item | string | — | Item name |
quantity | integer | — | Amount to remove |
meta | table? | nil | Item metadata |
tw.fw:canUseItem(source, item, amount, meta?, remove?)
Checks if a player has enough of an item. Optionally removes it.
| Parameter | Type | Default | Description |
|---|---|---|---|
source | integer | — | Player server ID |
item | string | — | Item name |
amount | integer | — | Required amount |
meta | table? | nil | Item metadata |
remove | boolean? | false | If true, removes the item when available |
Returns: boolean
tw.fw:registerUseItem(item, closeAfterUsed?, callback)
Registers a usable item handler.
| Parameter | Type | Default | Description |
|---|---|---|---|
item | string | — | Item name |
closeAfterUsed | boolean? | false | Close inventory after use |
callback | function(data) | — | Handler called when the item is used |
tw.fw:createInventory(invName, name, invConfig)
Creates a custom secondary inventory.
| Parameter | Type | Description |
|---|---|---|
invName | string | Unique inventory identifier |
name | string | Display label |
invConfig | table | Configuration (see below) |
invConfig fields:
| Field | Type | Description |
|---|---|---|
maxSlots | integer | Maximum inventory slots |
maxWeight | number | Maximum weight |
acceptWeapons | boolean | Whether weapons can be stored |
shared | boolean | Whether the inventory is shared between players |
tw.fw:removeInventory(invName)
Removes a custom inventory.
| Parameter | Type | Description |
|---|---|---|
invName | string | Inventory identifier |
tw.fw:openInventory(source, invName)
Opens a custom inventory for a player.
| Parameter | Type | Description |
|---|---|---|
source | integer | Player server ID |
invName | string | Inventory identifier |
tw.fw:getItemData(item)
Returns metadata for an item from the framework's item registry.
| Parameter | Type | Description |
|---|---|---|
item | string | Item name |
Returns: table — { label = string, ... }
tw.fw:getItems()
Returns all items from the framework's item registry.
Returns: table
UserClass Methods
Object returned by tw.fw:getUser(source).
user:getMoney(moneyType)
| Parameter | Type | Description |
|---|---|---|
moneyType | integer | 0 = dollar, 1 = gold, 2 = rol |
Returns: number
user:addMoney(amount, moneyType)
| Parameter | Type | Description |
|---|---|---|
amount | number | Amount to add |
moneyType | integer | Currency type |
user:removeMoney(amount, moneyType)
| Parameter | Type | Description |
|---|---|---|
amount | number | Amount to remove |
moneyType | integer | Currency type |
user:getIdentifiers()
Returns: table — { identifier = string, charid = string|integer }
user:getJob()
Returns: string
user:getRPName()
Returns: string (e.g. "John Smith")
user:canBuy(price, moneyType, removeIfCan?)
| Parameter | Type | Default | Description |
|---|---|---|---|
price | number | — | Price to check |
moneyType | integer | — | Currency type |
removeIfCan | boolean? | false | Deduct money if affordable |
Returns: boolean
Examples
Basic player info
-- server.lua
local user = tw.fw:getUser(source)
local name = user:getRPName()
local job = user:getJob()
local ids = user:getIdentifiers()
print(name .. " (" .. job .. ") — char: " .. ids.charid)Purchase flow
-- server.lua
local price = 50
local user = tw.fw:getUser(source)
if not user:canBuy(price, 0, true) then
tw.notif.rightError(source, "Not enough money")
return
end
local success = tw.fw:giveItem(source, "bandage", 5)
if not success then
user:addMoney(price, 0) -- refund
tw.notif.rightError(source, "Inventory full")
return
end
tw.notif.rightSuccess(source, "Purchased 5x Bandage")Multi-currency purchase
-- server.lua
local prices = {
{ amount = 10, moneyType = 0 }, -- $10
{ amount = 2, moneyType = 1 }, -- 2 gold
}
local canPay, failIndex = tw.fw:canUserPayWith(source, prices, true)
if not canPay then
tw.notif.rightError(source, "Not enough funds")
return
endDetect framework
print("Running on: " .. tw.fw:get())
if tw.fw:is("vorp") then
-- VORP-specific logic
endRegister usable item
-- server.lua
tw.fw:registerUseItem("bandage", true, function(data)
local source = data.source
tw.fw:removeItem(source, "bandage", 1)
-- heal logic
end)Client-side identifiers
-- client.lua
local ids = tw.fw:getMyIdentifiers()
print("My char ID: " .. ids.charid)Notes
- Always use
tw.fwinstead of calling framework exports directly. This ensures your code works across all supported frameworks. - The
moneyTypevalues (0= dollar,1= gold,2= rol) are consistent across all frameworks. giveItemreturnsfalsewhen the player's inventory is full. Always check the return value and handle the failure (e.g., refund money).onCharacterSelectedfires once per character selection, including on reconnect.

