🗒️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
PlayerDatais 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.PlayerDataToSaveToStateBagsNo 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
PlayerDataremains 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 = trueConfiguration
Moved config:
core/config.gta5.lua > Config.Money.UseCashAsItem now in core/config.lua > TMCConfig.Money.UseCashAsItemToggle 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.CashDenominationsDefault: US coin denominations.
UK denominations included as commented examples.
You can expand this to include bills/notes.
cashalways equals the base unit (e.g. $1, £1).
Item configuration:
core/shared.gta5.lua > denomConfigMatches 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.CoinExchangeEnabledWallet System
New item:
walletOnly 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
/cashDisplays total cash with decimal precision.
/cashbnewShows breakdown of denominations across inventory and wallet.
/givecashRequires 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
AddItemlogic 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.GetDeadCharactersReturns 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 endNo longer necessary to manually loop through
TMC.Playersand 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_itemitem 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
buyconfig with metadata for included items.
Shop System Enhancements
Added new fields for 'sell' shop configuration:
requireMetadatarequireRepsellAmountExample:
{
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
conditionfunctions 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_tagitems.Used to apply
_labelmetadata to items.Displays in inventory as a uniquely named item.
Not applicable to weapons or currency items.
Usage is logged under the
itemtagcategory.
Carriable Item Metadata Requirements
Config.CarriableConfignow supportsMetadataRequired.Example:
['sand_sack'] = {
ObjectModel = `p_sandbags03x`,
MetadataRequired = { full = true }
}Item Exchanges
Added
Config.ItemExchangesfor 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.StopNotifyfor server-side use.Works similarly to
SimpleNotify.Usage:
TMC.Functions.StopNotify(source, "perist_notify_id")
Improved the logic within the core
playerDroppedfunction.TMC.Common.FormatCashStringnewFormats a number to a readable string with 2 decimal places.
TMC.Common.RoundToPennynewRounds a number to 2 decimal places.
Gangs
Gang Member Management
Added two new exports for better gang management:
GetOnlineGangMembersIsPlayerInGang
Refer to the
README.mdfor 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_actionInfluence gain is scaled down the further it gets from the center hexagon. The scaling is configurable
Each action in
ActionedInfluenceConfignow supports anenabledtoggle.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_zoneNote: 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
ModifyZoneInfluenceto 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 EVERYTHINGcore/
|- 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.luacore_game/
|- server/
|- |- server.luainventory/
|- client.lua
|- config.lua
|- inventories.lua
|- server.luagarages/
|- proc.sql
|- server/
|- |- main.luatmc_queue/
|- server.jsAddon
gangs/
|- server.lua
|- README.mdplayershops/
|- client.lua
|- server.lua
|- marketstalls/
|- |- server.luaterritories/
|- serverConfig.lua
|- server.lua
|- utils.luaLast updated