Скрипт: простой инвентарь на сервере

Инвентарь живёт на сервере: клиент только просит показать содержимое и использовать предмет. Список допустимых предметов задан на сервере, поэтому «выдать себе меч» не получится.

Куда положить

ServerScriptService, тип объекта Script

Что должно быть в проекте

  • В ReplicatedStorage RemoteEvent с именем InventoryUse
  • В ReplicatedStorage RemoteEvent с именем InventoryChanged

Код

ServerScriptService/Inventory.lua
  1. local Players = game:GetService("Players")
  2. local ReplicatedStorage = game:GetService("ReplicatedStorage")
  3.  
  4. local useEvent = ReplicatedStorage:WaitForChild("InventoryUse")
  5. local changedEvent = ReplicatedStorage:WaitForChild("InventoryChanged")
  6.  
  7. local ITEMS = {
  8. potion = { title = "Зелье", heal = 30 },
  9. apple = { title = "Яблоко", heal = 10 },
  10. }
  11.  
  12. local MAX_SLOTS = 12
  13. local bags = {}
  14.  
  15. local function give(player, itemName: string): boolean
  16. local bag = bags[player.UserId]
  17.  
  18. if not bag or not ITEMS[itemName] or #bag >= MAX_SLOTS then
  19. return false
  20. end
  21.  
  22. table.insert(bag, itemName)
  23. changedEvent:FireClient(player, bag)
  24.  
  25. return true
  26. end
  27.  
  28. useEvent.OnServerEvent:Connect(function(player, slot)
  29. if typeof(slot) ~= "number" then
  30. return
  31. end
  32.  
  33. local bag = bags[player.UserId]
  34. local itemName = bag and bag[slot]
  35. local item = itemName and ITEMS[itemName]
  36.  
  37. if not item then
  38. return
  39. end
  40.  
  41. local character = player.Character
  42. local humanoid = character and character:FindFirstChildOfClass("Humanoid")
  43.  
  44. if not humanoid or humanoid.Health <= 0 then
  45. return
  46. end
  47.  
  48. humanoid.Health = math.min(humanoid.MaxHealth, humanoid.Health + item.heal)
  49. table.remove(bag, slot)
  50. changedEvent:FireClient(player, bag)
  51. end)
  52.  
  53. Players.PlayerAdded:Connect(function(player)
  54. bags[player.UserId] = {}
  55. end)
  56.  
  57. Players.PlayerRemoving:Connect(function(player)
  58. bags[player.UserId] = nil
  59. end)
  60.  
  61. return { give = give }

Клиент присылает только номер слота. Что в этом слоте лежит и что оно делает — знает сервер.

На что обратить внимание

  • Список ITEMS — то, что меняют под свою игру; предмета нет в списке — выдать его нельзя
  • Инвентарь стоит сохранять вместе с остальным прогрессом через DataStore
  • Показывать содержимое удобно тем же интерфейсом, что в заготовке про UI