How do I use ROBLOX events with OOP?

I’m familiar with OOP, but I have not utilized as much as I wanted to in the past.

I know you can make custom events with OOP, but what about just using simple ROBLOX-built in events, like Humanoid.Died or Players.PlayerAdded?

For example, I am working on a bounty system for some of my games. I’ve created one(s) before that weren’t very organized. I want to use OOP to make creating/editing/organizing them far more efficient, but I’m not entirely sure how.

bounty = {}
bounty.__index = bounty

function bounty.new(victim, setBy, amount)
    local newBounty = {}
    setmetatable(newBounty bounty)
    newBounty.amount = amount
    newBounty.setBy = setBy
    newBounty.target = victim

    return newBounty
end

return bounty

After that, I am confused on how I should code the following into this:

  1. Humanoid death detection. Basically, detect when the victim/target dies, and see if there is a ‘creator’ tag (used for pinpointing who killed who) at time of death. If there is, and the killer is NOT who set the bounty, award the amount to the killer.
  2. Player leaves. If the victim/target leaves, and the player who set the bounty is still in game, return the amount to the person who set the bounty.
  3. The same would be done if the person who set the bounty leaves the game, the amount would be awarded to the victim/target; bounties would be indefinitely long until one specific party dies by combat of a third party or either party leaves the game.

In other OOP codes I’ve seen, typically functions were placed outside the whatever.new call, but usually these functions would get fired by a third party script, not called from within it? Would I have to throw an event call in the bounty.new function, and have it point to something called bounty:Death() or bounty:PlayerLeft()?

bounty = {}
bounty.__index = bounty

function bounty.new(victim, setBy, amount)
    local newBounty = {}
    setmetatable(newBounty bounty)
    newBounty.amount = amount
    newBounty.setBy = setBy
    newBounty.target = victim

    game.Players.PlayerRemoving:Connect(PlayerLeft)

    return newBounty
end

bounty:PlayerLeft(plr)
--- code
end

return bounty

Since ROBLOX events are just BindableEvent objects’ .Event property, you could just do newBounty.PlayerLeft = game.Players.PlayerRemoving and have the end-user run :Connect() on this variable.

local r = require(mod)
r.PlayerLeft:Connect(function() end)
1 Like

You can use bindable events to set up custom events (Its also possible to make ur own verison of bindable events which have things that are better then rbx bindables)

As to how to set it up, I’ll be using rbx bindables for example just cause its simple

local DiedBindable = Instance.new("BindableEvent")
DiedBindable.Parent = Character

-- Then whenever a character dies you just simply do
DiedBindable:Fire()
-- If you only want it to fire when there a tag then you just use a if statement

If you want to set up a custom listener then you just do
DiedBindable.Event:Connect(function()

end)

There not really enough information to give you more specific details then this but if you want more help you can DM Me on discord

Thedagz#4176

2 Likes

My question to that is, where would you place that code in relative to the one that would create said bounty?

I think they way you formatted it with the separate function for the events below the constructor is good; however, you should keep in mind that defining a function with a colon adds an extra argument called “self” to the method that automatically gets passed when you call it with the colon, but when it is passed to an event, that extra argument doesn’t get passed.
so instead of this:

function bounty:PlayerLeft(plr)
--- code
end

it should look more like this:

function bounty.PlayerLeft(plr)
--- code
end

also if you have this class in a module script and it is the only class inside that module script, I think it is perfectly acceptable to just a function for each event that isn’t part of the class. if you do have multiple classes in the module script tho, it can get kinda confusing figuring out which function goes to which class, so the safer option would be to go with the first way that was mentioned.