🗒️TMC 2.1
The release of TMC 2.1 on the 20th June 2025. Includes major overhauls of internal features to improve performance, usability and add some key features that have been missing.
Base
PlayerData Replication
Reworked how
PlayerData
is saved to player state bags.Reduced state bag sync frequency to avoid potential issues with high player counts.
Only essential or infrequently updated values are now replicated.
Configurable via:
core/config.server.lua > Config.Server.PlayerDataToSaveToStateBags
No changes are required for our internal scripts. However, if your external scripts rely on remote state bag access, you may need to adjust accordingly or enable replication for those values manually.
All original
PlayerData
remains accessible on the local client side.
💵 Cash Denominations System
See thread - https://discord.com/channels/1072182006584184843/1346952944251174962 Enabled via: (this is the new default behaviour for using cash as items)
TMCConfig.Money.UseCashAsItem = true
Configuration
Moved config:
core/config.gta5.lua > Config.Money.UseCashAsItem now in core/config.lua > TMCConfig.Money.UseCashAsItem
Toggle debugging:
/toggledenomdebugging [playerId] [0|1]
Enables server-side denomination logic debugging.
Must be run from the server console.
Denomination value setup:
core/config.lua > TMCConfig.Money.CashDenominations
Default: US coin denominations.
UK denominations included as commented examples.
You can expand this to include bills/notes.
cash
always equals the base unit (e.g. $1, £1).
Item configuration:
core/shared.gta5.lua > denomConfig
Matches the items to the defined denominations.
UK denominations included as commented examples.
Banking has been updated to accept fraction values in input dialogs. Enabled by default
Can be toggled in
Config.AllowFractions
Coin Exchange System
Added coin exchange and purchase prompt at all bank location
Players can now:
Pay a fee (
Config.CoinExchangeFee
) to convert all cash on hand into the largest denomination combination possible.Pay a separate fee (
Config.ChangePurchaseFee
) to purchase coin denominations (change).
This feature is enabled by default but can be toggled via:
Config.CoinExchangeEnabled
Wallet System
New item:
wallet
Only accepts denomination items as defined in the config.
Incoming cash goes into the wallet if the item exists.
If no wallet is present, cash is received in the standard inventory.
🧾 Command Updates
/cash
Displays total cash with decimal precision.
/cashb
newShows breakdown of denominations across inventory and wallet.
/givecash
Requires exact denomination match to complete transaction.
Example:
Player A has $1.23 (1x $1, 1x $0.20, 3x $0.01) Player A cannot give $1.13 unless they have the exact change.
⚙️ Inventory & Item Performance Optimizations
We're making an effort to improve on stability of processing large number of items, especially with stackable items.
Player weight calculation reworked for improved performance during player objection transactions.
Shop purchase/sell logic optimized for handling stackable item transactions.
Improved
AddItem
logic for inbound stackable items.Inventory syncs to the client are now throttled and batched. This reduces network load, especially during high volumes of add/remove item transactions.
Dead Player Tracking
Added:
TMC.Player.GetDeadCharacters
Returns a table of dead characters currently online:
{ [1] = "ABCDE123", -- serverId = CSN [5] = "FGHIJ123", }
You can reference it with:
if TMC.Player.DeadCharacters[source] then -- do something end
No longer necessary to manually loop through
TMC.Players
and check metadata.
Garages - Misc
Added stored procedure check in order to display warning when an invalid SQL setup is detected.
Item Display
Added a new client event for showing bulk item boxes.
Example usage:
local itemArray = {
{ name = "apple", amount = 2, info = { _label = "Some New Label" } },
{ name = "water_bottle", amount = 3 }
}
TriggerClientEvent("inventory:client:itemBoxBulk", source, itemArray, "add" or "remove")
Bundled Items
Added support for the
bundled_item
item type.When used, it gives the player multiple items specified in its metadata.
Example usage:
local player = TMC.Functions.GetPlayer(source)
player.Functions.AddItem("bundled_item", 1, nil, {
_label = "Packed Lunch",
items = {
{ name = "apple", amount = 2 },
{ name = "water_bottle", amount = 1 }
}
})
Can also be sold in shops using standard
buy
config with metadata for included items.
Shop System Enhancements
Added new fields for 'sell' shop configuration:
requireMetadata
requireRep
sellAmount
Example:
{
name = 'log',
price = 1,
sellAmount = 5,
info = { _label = "5x Douglas Log" },
requireMetadata = { species = "p_tree_douglasfir_snow_05" },
requireRep = { name = "lumberjack", amount = 10 }
}
These options allow conditional sales based on metadata, reputation, and required quantity.
Shop Access Conditions
Added support for
condition
functions to restrict shop access globally or per location.Example configuration:
['pawnshop'] = {
label = 'Pawn Shop',
blipInfo = {
type = 272,
color = 4
},
type = 'sell',
condition = function()
if TMC.Functions.HasJob("pawnshop") then
return true
end
return false
end,
locations = {
{ -- Southside
center = vector3(182.6522, -1319.378, 29.323),
length = 2.0,
width = 1.6,
options = {
heading = 333,
minZ = 28.0,
maxZ = 31.0
},
condition = function()
if TMC.Functions.HasItem("pawn_shop_key_southside") then
return true
end
return false
end
},
}
}
These conditions are optional but allow greater control over who can access shops.
Item Tagging
Introduced logic for
item_tag
items.Used to apply
_label
metadata to items.Displays in inventory as a uniquely named item.
Not applicable to weapons or currency items.
Usage is logged under the
itemtag
category.
Carriable Item Metadata Requirements
Config.CarriableConfig
now supportsMetadataRequired
.Example:
['sand_sack'] = {
ObjectModel = `p_sandbags03x`,
MetadataRequired = { full = true }
}
Item Exchanges
Added
Config.ItemExchanges
for trade-based interactions.Example: 20x water bottles for 2x apples.
Supports reputation requirements and per-character limits.
Character limits reset on script/server restart.
Internal Events
Added internal server-side events:
AddEventHandler("inventory:server:itemAdded", function(stashId, itemName, slot, itemInfo, amount, originSource) end)
AddEventHandler("inventory:server:itemRemoved", function(stashId, itemName, slot, slotIndex, amount, originSource) end)
Stash Restrictions
New system to apply whitelist/blacklist restrictions on stashes.
Also allows setting a maximum item amount per slot.
Example usage:
exports.inventory:SetStashItemRestriction("food_stash", "whitelist", { "bread", "water" }, 10)
exports.inventory:SetStashItemRestriction("safe_stash", "blacklist", { "gun", "ammo" })
New exports:
GetStashItemRestriction(stashId)
ClearStashItemRestriction(stashId)
Example:
local restriction = GetStashItemRestriction("food_stash")
if restriction then
print("Type:", restriction.type)
print("Items:", table.concat(restriction.items, ", "))
if restriction.maxAmount then
print("Max:", restriction.maxAmount)
end
end
ClearStashItemRestriction("food_stash")
Player Shops & Market Stalls
Updated player shops to support multiple stackable items per stock slot.
Menus now support decimal value prices for items.
Added feedback when updating market stalls to improve user clarity.
Additional general improvements made to stock management logic
Misc
Added
TMC.Functions.StopNotify
for server-side use.Works similarly to
SimpleNotify
.Usage:
TMC.Functions.StopNotify(source, "perist_notify_id")
Improved the logic within the core
playerDropped
function.TMC.Common.FormatCashString
newFormats a number to a readable string with 2 decimal places.
TMC.Common.RoundToPenny
newRounds a number to 2 decimal places.
Gangs
Gang Member Management
Added two new exports for better gang management:
GetOnlineGangMembers
IsPlayerInGang
Refer to the
README.md
for usage examples and documentation.Removed unused debug print statements.
Territories
Actioned Influence Enhancements
Added radius-based influence gain for actioned influence.
Example provided in:
serverConfig.lua > ActionedInfluenceConfig > example_radius_action
Influence gain is scaled down the further it gets from the center hexagon. The scaling is configurable
Each action in
ActionedInfluenceConfig
now supports anenabled
toggle.Ensure you update your config:
serverConfig.lua > ActionedInfluenceConfig
Influence System Improvements
Added influence gain through player presence in zones.
Configurable via:
serverConfig.lua > ActionedInfluenceConfig > player_in_zone
Note: For balance reasons, players will only gain influence through presence in zones that already exist
To create a new zone, one of the other influence actions must be performed first
Once a zone is created, players can then begin earning influence in it simply by being at that location
Refactored passive influence loss to streamline performance.
Improved
ModifyZoneInfluence
to prevent repeated save/sync calls on failed attempts.Added logs for zone contest and claim timeouts.
General Updates
Improved debug output for overdue upkeep and zone discovery.
Updated permission sync for staff view access to reduce network load.
Removed unnecessary debug prints.
Changed Files
Base
banking/
|- client.lua
|- config.lua
|- server.lua
|- html/
|- |- REPLACE EVERYTHING
core/
|- config.gta5.lua
|- config.lua
|- config.server.lua
|- shared.gta5.lua
|- client/
|- |- events.lua
|- common/
|- |- functions.lua
|- server/
|- |- events.lua
|- |- functions.lua
|- |- main.lua
|- |- player.lua
core_game/
|- server/
|- |- server.lua
inventory/
|- client.lua
|- config.lua
|- inventories.lua
|- server.lua
garages/
|- proc.sql
|- server/
|- |- main.lua
tmc_queue/
|- server.js
Addon
gangs/
|- server.lua
|- README.md
playershops/
|- client.lua
|- server.lua
|- marketstalls/
|- |- server.lua
territories/
|- serverConfig.lua
|- server.lua
|- utils.lua
Last updated