im making a game in which the main point is getting items from mario kart type boxes while dodging events that happen, rn im working on the item system
issue is idk how to properly structure the code on them, currently the way the system works is a folder which every item has that includes:
a module script that handles client through functions like module.click, which is connected to a local script on the player
a server script
a event
however this system is kinda fragile, it can break whenever the player dies, drops the item or anything
is there a better way of handling this? like handling scripts outside of the item, maybe even use module script on the server aswell
How is your script breaking exactly? Are there any errors thrown by your scripts? If your items are possibly getting deleted when you die, I think it’s breaking because the script will stop as soon as it’s destroyed. To solve this, I would create a callExternally utility, which would be a module that returns a function which takes a function along with a variable number of arguments. The module contains a BindableEvent and a server Script that it will pass it’s arguments to, then the script inside of the module would call the function. This should prevent anything from breaking, since the function is fired from the external server script and not from the item itself. I believe Roblox’s new FPS template includes something like this, specifically, bindToInstanceDestroyed. With all this in mind, I would write this utility like so:
-- In your module script "callExternally"
-- The bindable event to allow communicating to the external server script.
local CallEvent = script:WaitForChild("CallEvent")
return function(func, ...)
task.defer(function()
-- Send the function along with it's arguments to the server script through the CallEvent.
CallEvent:Fire(func, ...)
end)
end
-- In your server script "ServerCallHandler" within "callExternally"
local Root = script.Parent
local CallEvent = Root:WaitForChild("CallEvent")
-- Recieve the function along with it's arguments, then call it from within the server script.
CallEvent.Event:Connect(function(func, ...)
func(...)
end)
what exactly does task.defer do? my issue is like, on the server part mostly, i need stuff to not break upon player’s death or item changing parents
to make things more clear heres some snippets of my code
on the client:
function module.click(anims)
local result = sharedItem:processDebounce(item, "click")
if result == false then return end
if configuration.currentPlayer then
highlight:Destroy()
if configuration.cooldown then return end
configuration.cooldown = true
event:FireServer(configuration.currentPlayer)
task.wait(1)
configuration.cooldown = false
end
end
and on the server:
local function activateAbility(currentPlayer, hit)
if player and hit then
local status = items:setActive(player, item, "click", true)
if status == false then
return
end
task.delay(0.1, function()
items:setActive(player, item, "click", false)
end)
local vfx = item.BodyAttach.Effect:Clone()
local sfx = item.BodyAttach.Use:Clone()
sfx.Parent = hit.Torso
vfx.Parent = hit.Torso
vfx.Enabled = true
events.Cosmetic:FireAllClients("Sound", sfx)
task.delay(sfx.TimeLength, function()
sfx:Destroy()
vfx:Destroy()
end)
modifier:cast(hit, "AI Generated", player)
task.delay(0.1, function()
item.Parent = serverScriptService.Cache
end)
end
end
items:setActive detects and handles cooldowns btw, decided to put it all in one function, any ways lets suppose this instead had like a connection, and the player died while the connection was still running, it would just break, i wanted to fix that
So, the server script is inside the tool. Another question is what are you trying to bind a connection to, the tool, the owner, or another (possible opponent) player?
like, theres another item which i didnt send the script because it was too big, which set a modifier which stuns the player (modifers are a system in my game that can do any stat effects), and the way they work is it requires a module for each modifier that run a function or whatever, but lets suppose the modifier is called, and the player holding the item dies, the modifier will just stop and not run anymore, so when the stun is supposed to end, it doesnt
So, in other words, you are trying to effect another player which is not the tool owner. Are the player’s status effects (stun) stored within the character or the player? If the status effects (like stun) are stored in the player instance and not the player’s character, I would move the status effect from the player to the player’s character. This would make sure that all the player’s status effects are cleared once the player dies.
the status effects are stored on the targets character yes, but the issue is like, if the player dies the other pretty much gets stun locked, due to the stun effect never clearing, before i changed the runcontext to server just unequipping the tool was enough to stun lock the target
What could be happening is that the modifier is being called within the tool’s owner. Once the tool gets removed from the player, then the modifier gets disabled. What you could do instead is use a BindableEvent on the server to cast the modifier instead of using a ModuleScript. This would ensure that the modifier runs on an external script instead of running within the player’s tool, so the modifier will never get disabled upon the player’s death or upon the tool being unequipped.