Custom Methods (A Follow-Up to My First Tutorial)

Welcome back,

haha, it’s me again. Now if you haven’t seen it already, yesterday last night, or whatever time it was for you, I created a custom temp-ban command tutorial, and since the code wasn’t as clean, which I really like my coding to be clean, I’m going to be following that tutorial up with creating your own methods.

WHAT ARE METHODS?

Now, if you don’t know what methods are, they’re basically things like :Clone(), or :Destroy(), basically things that take action. They’re basically functions, but you don’t use them like GetBan(player) at all. But really, there’s no reason to be creating your own method other than because of the fact that it seems fun and that it’s time-consuming and that it’s what we’d want in quarantine, so let’s get started.

INTIALIZATION

I’ll be starting it off with creating a module which I’ll be naming ‘goldenWind’, and then putting that anywhere suitable. I’d put it in ReplicatedStorage, but nah, I’m gonna put it in ServerScriptService, they can’t stop us.

Oh, I’m assuming you’ve placed your ModuleScript and opened it.

We’ll start off by indexing some values.

local PlayerClass = {};
PlayerClass.__index = PlayerClass;
PlayerClass.BanDataStore = game:GetService("DataStoreService"):GetDataStore("Bans_2q321124");
PlayerClass.Players = {};

And before you ask, yes, we’ll be using metatables for this tutorial.

Once that that’s done, let’s now make some functions, which will be methods, of course.

I’ll start off by making a :Kill() method.

function PlayerClass:Kill()
    self.Character.Humanoid.Health = 0;
end

After that you now have your very first own custom method. But wait, we’ll need to make data or else it wouldn’t really recognize “Model”, “Player”, or “Character”. So let’s get straight into that.

DATA

Of course, we wouldn’t be able to really create our own methods and use them on Roblox’s core/built-in functions, so we’ll be creating our own built-in functions. Get it yet?

We’ll be creating a function that builds up data of the player, and its own events.

function PlayerClass.Create(Player_Instance)
    local Player = {};
    Player.Model = Player_Instance;
    Player.Character = Player.Model.Character;
    Player.Name = Player.Model.Name;
    --empty
end

Do you see it? We’re basically creating our own Player instance that should be compatible with our own custom methods. And then adding its properties, but for more fun, we should probably add our own custom events.

function PlayerClass.Create(Player_Instance)
    local Player = {};
    Player.Model = Player_Instance;
    Player.Character = Player.Model.Character;
    Player.Name = Player.Model.Name;
    --// EVENTS
    Player.Messaged = Player.Model.Chatted;
    Player.CharacterCreated = Player.Model.CharacterAdded;

    setmetatable(Player, PlayerClass);
    return Player;
end

Now it’s done, we have data of the player. Of course, as a result, we’ll be calling this function every time a player is added, but let’s focus on the main functions and the ModuleScript here.

Of course, we’ll be focusing on the :GetBan() method, after, :SetBan(), so let’s get on with it.

(Don’t forget to set an ID property for the player, and add a Player_Instance to the PlayerClass module like this:)

PlayerClass.Players[Player_Instance] = Player;

Since we already have the BanStore in the module, we should then be able to easily search for the player’s ban.

CUSTOM "GETBAN" METHOD

We have our own custom ‘Player’ instance, we have our own first method, awesome. Now let’s make another method which checks for the player’s data.

function PlayerClass:getBan()
	local Success, Result = pcall(function()
		return PlayerClass.BanDataStore:GetAsync(tostring(self.ID), "TempBan");
	end)
	
	if Success then
		if Result then
			if Result.BanStartTime + Result.BanDuration < os.time() then
				print("Player's 'ban has been lifted.");
			else
				self.Model:Kick(Result.BanReason);
			end
		end
	end
end

Easy, and with that, we finally have another method that checks for a ban. I won’t be going too much into detail about the code, as I’ve already (I think, haha) explained that in the last tutorial. Now we’re gonna come up with :Ban, of course. A stronger :Kick().

:BAN() METHOD

We have a custom method that checks if a player is banned or not, but do we have a custom method that can ban a player? Of course not, duh, we haven’t even made one yet!

function PlayerClass:Ban(reason, duration)
	PlayerClass.BanDataStore:SetAsync(tostring(self.ID),{BanStart = os.time(), BanDuration = (duration * 86400), BanReason = reason});
	self.Model:Kick(reason);
end

Uh, yeah, it’s that easy, summarized in only a few lines. Looks clean, does it? (I hope it does)

I, once again, won’t be going too much into detail, since I’ve already explained in the last tutorial, which you can check up above, linked it up there.

And now we’ve created every method that we want, but we can’t really ban anyone yet, we haven’t used the functions yet, which we will be using, so let’s go!

MAKING IT ACTUALLY work

We’ll be creating a new script, placing it in ServerScreiptService, and then hopping into it. i’ll be calling it jojo.

Of course, since we have almost everything in the ModuleScript, the only things we need are the Players service, and the ModuleScript itself.

After that, we’ll be using the PlayerAdded event to create our very own Player instance.

Basically if you don’t get it, we can create our own custom methods, but our own custom methods won’t really be compatible or can even be used with Roblox’s built-in functions, which is why we’ll be creating our own built-in functions, with its own set properties, and custom data.

-------------
--- INDEX ---
-------------

local PlayerClass = require(game.ServerScriptService.goldenWind);
local Players = game:GetService("Players");

Players.PlayerAdded:Connect(function(plr)
	PlayerClass.Create(plr)
end)

And remember, our Create function accepts player instances, so we’ll be putting that, and it should create a load of data. But wait, we’ll want to check for the player if they have any bans first.

Players.PlayerAdded:Connect(function(plr)
	local Player = PlayerClass.Create(plr)
	
	Player:getBan()
end)

Easy, just a few lines. That’s the power of custom methods, we aren’t consuming much lines in our script and it makes it more clean! Now let’s use our own custom events, no?

Players.PlayerAdded:Connect(function(plr)
	local Player = PlayerClass.Create(plr)
	
	Player:getBan()
	Player.Messaged:Connect(function(message)
		if string.sub(message, 1, "/ban"):lower() == "/ban" then
			local args = string.split(message, " "); --split message with spaces
			local playerToBan = Players:FindFirstChild(args[2]);
			local d = "%d" or "%d%d"
			local duration = string.sub(message, string.find(message, d));
			local reason = string.sub(message,  string.len("/ban " .. args[2] .. " " .. duration));
			if playerToBan then
				print(playerToBan.Name);
				if duration then
					print(duration);
					if reason then
						print(reason);
						playerToBan:Ban(reason, duration);
					end
				end
			end
		end
	end)
end)

And now we have used two things in this scenario: Our own custom messaged event, and our own custom Ban method. How magnificent. Maybe we should use off our remaining event?

Player.CharacterCreated:Connect(function(char)
		Player.Character = char;
	end)

And then… we. are. done.

Hope I made it look easy for you, now we have our own custom methods, custom built-in instances, and all that, now don’t abuse your power, muahahahhaha!

please message me if i missed anything or there is something wrong, or ask it here

5 Likes

Yah but you should add this thing I showed you in discord

function PlayerClass.GetPlayerByInstance(i)
    return PlayerClass.Players[i]
end


local PlayerClass = {}
PlayerClass.__index = PlayerClass
PlayerClass.BanDataStore = game:GetService("DataStoreService"):GetDataStore("Bans_2q321124")
PlayerClass.Players = {}

function PlayerClass.Create(Player_Instance)
    local Player = {}
    Player.Model = Player_Instance
    Player.Name = Player_Instance.Name
    PlayerClass[Player_Instance] = Player
    
    setmetatable(Player, PlayerClass)
    return Player
end

With this.

The reason is the class isn’t that useful without actually having a way to refer to the player instance.

Oh yah and this:

function PlayerClass:Remove(Player)
    PlayerClass.Players[self.Model] = nil
end

when the player leaves to prevent memory leaks.

1 Like

Why did you mark this as solution? It’s a good tutorial, and thank you for making it, but please don’t farm solutions or mark your own stuff as solution if nothing was solved.

What? I Didn’t even make this tutorial …?


https://gyazo.com/1cd2462db2b48fc6d86df2907207591b

Stop making up false claims, it’s annoying. Did you even bother to look at who made this post? Next time don’t post for the sake of posting, don’t farm posts.

Nevermind. It was a mistake.

1 Like

I made this tutorial, not 0Shank. 0Shank only corrected something that was wrong with the coding which is why I marked it as a solution in case anyone gets errors.

Jesus guys calm down. I scrolled down a bit too far and thought that the end of the post which @0Shank made was what @xxIamInevitable posted. Simple and honest mistake. You don’t need to dm me and accuse me of false claims. I’m sorry for my mistake.

We should probably stop now and get back on track; it’s not really a good thing to go off-topic, thus let’s retract our replies and set this off, shall we?

2 Likes