You can write your topic however you want, but you need to answer these questions:
- What do you want to achieve? Keep it simple and clear!
A trading system exactly like the game 60 seconds. Players all share an inventory which is what is in the bunker.
- What is the issue? Include screenshots / videos if possible!
While the UI and randomized trades work fine, when I try to submit a trade, it gives me an error. Not sure why as there’s nothing in the output for me.
First, I’ll send my client-side script, then my server script.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TradeEvent = ReplicatedStorage:WaitForChild("TradeEvent")
local Player = game.Players.LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")
local ItemImages = ReplicatedStorage:WaitForChild("ItemImages")
-- GUI references
local TradeGui = PlayerGui:WaitForChild("Trading")
local Offer1Image = TradeGui.ImageLabel:WaitForChild("Offer1")
local Offer2Image = TradeGui.ImageLabel:WaitForChild("Offer2")
local Deal1Button = TradeGui.ImageLabel:WaitForChild("Deal1")
local Deal2Button = TradeGui.ImageLabel:WaitForChild("Deal2")
local StatusLabel = TradeGui.ImageLabel:WaitForChild("StatusLabel")
-- Current trades
local currentTradeIndex = 1
local trades = {
{ offer1 = {item = "Food", amount = 2}, offer2 = {item = "Water", amount = 1} },
{ offer1 = {item = "Water", amount = 2}, offer2 = {item = "Food", amount = 1} },
{ offer1 = {item = "Axe", amount = 1}, offer2 = {item = "Food", amount = 3} },
{ offer1 = {item = "Radio", amount = 1}, offer2 = {item = "Water", amount = 3} },
{ offer1 = {item = "Gun", amount = 1}, offer2 = {item = "Food", amount = 4} }
}
local function getImageForItem(itemName)
local value = ItemImages:FindFirstChild(itemName)
if value and value:IsA("StringValue") then
return value.Value
end
return ""
end
local function showTrade(index)
local trade = trades[index]
if not trade then return end
local offer1 = trade.offer1
local offer2 = trade.offer2
Offer1Image.Image = getImageForItem(offer1.item)
Offer2Image.Image = getImageForItem(offer2.item)
Deal1Button.Image = getImageForItem(trade.offer2.item)
Deal2Button.Image = getImageForItem(trade.offer1.item)
end
-- Handle trade requests
Deal1Button.MouseButton1Click:Connect(function()
TradeEvent:FireServer("RequestTrade", currentTradeIndex, 1)
end)
Deal2Button.MouseButton1Click:Connect(function()
TradeEvent:FireServer("RequestTrade", currentTradeIndex, 2)
end)
-- Handle server result
TradeEvent.OnClientEvent:Connect(function(success, message)
if success then
StatusLabel.Text = "Trade completed!"
else
StatusLabel.Text = "Trade failed: " .. (message or "Not enough items.")
end
task.delay(3, function()
StatusLabel.Text = ""
end)
end)
local currentTradeIndex = 1
local Trader = workspace:WaitForChild("Trader")
local Prompt = Trader:WaitForChild("ProximityPrompt")
local function openTradeGui()
TradeGui.Enabled = true
currentTradeIndex = math.random(1, #trades)
showTrade(currentTradeIndex)
end
Prompt.Triggered:Connect(function()
openTradeGui()
end)
-- Initialize GUI with first trade
showTrade(currentTradeIndex)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local TradeEvent = ReplicatedStorage:FindFirstChild("TradeEvent") or Instance.new("RemoteEvent")
TradeEvent.Name = "TradeEvent"
TradeEvent.Parent = ReplicatedStorage
local ItemConfig = require(ReplicatedStorage:WaitForChild("ItemConfig"))
local itemCategories = ItemConfig.itemCategories
local trades = {
{ offer1 = {item = "Food", amount = 2}, offer2 = {item = "Water", amount = 1} },
{ offer1 = {item = "Water", amount = 2}, offer2 = {item = "Food", amount = 1} },
{ offer1 = {item = "Axe", amount = 1}, offer2 = {item = "Food", amount = 3} },
{ offer1 = {item = "Radio", amount = 1}, offer2 = {item = "Water", amount = 3} },
{ offer1 = {item = "Gun", amount = 1}, offer2 = {item = "Food", amount = 4} }
}
-- Utility Functions
local function getItemCount(itemName)
local category = itemCategories[itemName]
if not category then return 0 end
local slotsFolder = workspace:FindFirstChild("Bunker")
and workspace.Bunker:FindFirstChild("Slots")
and workspace.Bunker.Slots:FindFirstChild(category)
if not slotsFolder then return 0 end
local count = 0
for _, slot in ipairs(slotsFolder:GetChildren()) do
for _, item in ipairs(slot:GetChildren()) do
if item.Name == itemName then
count += 1
end
end
end
return count
end
local function removeItems(itemName, amount)
local category = itemCategories[itemName]
if not category then return end
local slotsFolder = workspace.Bunker.Slots:FindFirstChild(category)
if not slotsFolder then return end
local remaining = amount
for _, slot in ipairs(slotsFolder:GetChildren()) do
for _, item in ipairs(slot:GetChildren()) do
if item.Name == itemName and remaining > 0 then
item:Destroy()
remaining -= 1
if remaining <= 0 then return end
end
end
end
end
local function findFreeSlot(category)
local folder = workspace.Bunker.Slots:FindFirstChild(category)
if not folder then return nil end
for _, slot in ipairs(folder:GetChildren()) do
if #slot:GetChildren() == 0 then
return slot
end
end
return nil
end
local function addItemToBunker(itemName)
local category = itemCategories[itemName]
if not category then warn("No category for item:", itemName) return end
local slot = findFreeSlot(category)
if not slot then warn("No free slot in category:", category) return end
local model = ServerStorage:FindFirstChild(itemName)
if model then
local clone = model:Clone()
clone:SetPrimaryPartCFrame(slot.CFrame)
clone.Parent = slot
else
warn("Missing model for item:", itemName)
end
end
local function tradeEquals(a, b)
return a.offer1.item == b.offer1.item and
a.offer1.amount == b.offer1.amount and
a.offer2.item == b.offer2.item and
a.offer2.amount == b.offer2.amount
end
TradeEvent.OnServerEvent:Connect(function(player, action, trade, dealNumber)
if action ~= "RequestTrade" or typeof(trade) ~= "table" or typeof(dealNumber) ~= "number" then
TradeEvent:FireClient(player, false, "Invalid request format.")
return
end
-- Make sure the trade matches one of the predefined trades exactly
local validTrade
for _, t in ipairs(trades) do
if tradeEquals(t, trade) then
validTrade = t
break
end
end
if not validTrade then
TradeEvent:FireClient(player, false, "Trade offer is invalid.")
return
end
local success = false
if dealNumber == 1 then
if getItemCount(trade.offer2.item) >= trade.offer2.amount then
removeItems(trade.offer2.item, trade.offer2.amount)
for _ = 1, trade.offer1.amount do
addItemToBunker(trade.offer1.item)
end
success = true
else
TradeEvent:FireClient(player, false, "Not enough " .. trade.offer2.item)
return
end
elseif dealNumber == 2 then
if getItemCount(trade.offer1.item) >= trade.offer1.amount then
removeItems(trade.offer1.item, trade.offer1.amount)
for _ = 1, trade.offer2.amount do
addItemToBunker(trade.offer2.item)
end
success = true
else
TradeEvent:FireClient(player, false, "Not enough " .. trade.offer1.item)
return
end
end
TradeEvent:FireClient(player, success)
end)