[Moveset Loader] Function returning nil

I’m trying to create a moveset loader for different characters. Unfortunately, I’ve hit a road block because of this error I’m receiving.


Below is how my project is currently structured:

Here is what’s inside each script as of now.

--InputHandler: Client--
--Author: Butcher (@mrkimitsu)--

--/Service Variables\\--
local ContextActionService	= game:GetService("ContextActionService")
local ReplicatedStorage		= game:GetService("ReplicatedStorage")

--//Events Variables\\--
local Input_Ev = ReplicatedStorage:WaitForChild("Events"):WaitForChild("Input")

--//Player Variables\\--
local Players	= game:GetService("Players")
local Player	= Players.LocalPlayer
local Character	= Player.Character or Player.CharacterAdded:Wait()

--//Subroutines\\--
function Attack(ActionName, InputState)
	if ActionName == "M1" and InputState == Enum.UserInputState.Begin then
		Input_Ev:FireServer(Character, "M1")
	end
end

--//Main\\--
ContextActionService:BindAction("M1", Attack, false,
	Enum.UserInputType.MouseButton1,
	Enum.KeyCode.ButtonX
)
--Input Handler: Server--
--Author: Butcher (@mrkimitsu)--

--//Events Variables\\--
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Input_Ev			= ReplicatedStorage.Events.Input

--//Modular/Utility Variables\\--
local Modules_Folder = ReplicatedStorage.Modules
local Movesets_Folder = Modules_Folder.Movesets

local Cooldown_Util	 = require(Modules_Folder.Cooldown)

--//Miscellaneous\\--
local DefaultCharacter = "Peacekeeper"

function LoadMoveset(Character, Name: string)
	local Moveset = Movesets_Folder:FindFirstChild(Name)

	if not Moveset then error("[LoadMoveset]", Name.."'s moveset not found.") return end

	local CharMoveset = require(Moveset)
	return CharMoveset.new(Character)
end

--//Main\\--
Input_Ev.OnServerEvent:Connect(function(Character: Model, Action: string)
	local CurrentCharacter: string = Character:GetAttribute("Character") or DefaultCharacter
	
	local Moveset = LoadMoveset(Character, CurrentCharacter)
	Moveset_Action = ":"..Action
	Moveset[Moveset_Action]()
end)
--Base Moveset: Module--
--Author: Butcher (@mrkimitsu)--

local Moveset	= {}
Moveset.__index = Moveset

function Moveset.new(Character)
	local self	= setmetatable({}, Moveset)
	self.Character = Character
	return self
end

function Moveset:M1()		end
function Moveset:M2()		end
function Moveset:Block()	end
function Moveset:Evade()	end
function Moveset:Ability()	end

return Moveset
--Peacekeeper Moveset: Module--
--Author: Butcher (@mrkimitsu)--

--/Service Variables\\--
local ReplicatedStorage = game:GetService("ReplicatedStorage")

--//Modular/Utility Variables\\--
local Modules_Folder = ReplicatedStorage.Modules
local Cooldown_Util	 = require(Modules_Folder.Cooldown)

--//Parameters\\--
local Base_Moveset			= require(script.Parent.Base)
local Peacekeeper_Moveset	= setmetatable({}, Base_Moveset)
Peacekeeper_Moveset.__index = Peacekeeper_Moveset

--//Main\\--
function Peacekeeper_Moveset:M1()
	self.Character.Archivable = true
	
	if self.Character:GetAttribute("Character") ~= "Peacekeeper" then return end
	
	if self.Character:GetAttribute("DisableM1") then return end --For Cooldown
	
	if self.Character:GetAttribute("Stun") or self.Character:GetAttribute("Ragdoll") then return end
	
	local Humanoid = self.Character:FindFirstChild("Humanoid")
	if not Humanoid or Humanoid.Health < 0 then return end
	
	Cooldown_Util:SetCooldown(self.Character, "M1", 0.325)
	
	print("Test")
end

return Peacekeeper_Moveset

I’ve tried doing Moveset[Action](Moveset) but that didn’t seem to solve it. I could try doing selection statements for each individual action but that doesn’t seem to be efficient.

At the moment, I’m unaware of anyone else having a similar problem to mine but I’m unsure as to what to do right now.

first arg of OnServerEvent is always the player that fired the event

--//Main\\--
Input_Ev.OnServerEvent:Connect(function(Caller: Player, Character: Model, Action: string)
	local CurrentCharacter: string = Character:GetAttribute("Character") or DefaultCharacter
	
	local Moveset = LoadMoveset(Character, CurrentCharacter)
	Moveset_Action = ":"..Action
	Moveset[Moveset_Action]()
end)

I’ve added the first argument. I noticed that I forgot to define the Moveset_Action variable as a local variable :moai:

Input_Ev.OnServerEvent:Connect(function(Player: Player, Character: Model, Action: string)
	local CurrentCharacter: string = Character:GetAttribute("Character") or DefaultCharacter
	
	local Moveset			= LoadMoveset(Character, CurrentCharacter)
	local Moveset_Action	= ":"..Action
	
	Moveset[Moveset_Action]()
end)

Although, I’m not getting any different results.

You’re trying to access the Moveset in the moveset module script by doing this Moveset[":SomeAction"](), that wouldn’t work because the methods with a colon : are just syntactic sugar that do the same thing as Moveset.M1(self), so when youre doing a lookup in the dictionary of Moveset, you should look for just the name of move itself:

 Input_Ev.OnServerEvent:Connect(function(player: Player, Character: Model, Action: string)
	local CurrentCharacter: string = Character:GetAttribute("Character") or DefaultCharacter
	
	local Moveset = LoadMoveset(Character, CurrentCharacter)
	Moveset[Action]()
end)

also, off the top of my head, calling it this way, you may need to pass in Moveset as the first arg in the call because it might call it as a . rather than a : which passes self on its own:

Moveset[Action](Moveset)

Why are you trusting client to send the character? This can be exploitable

1 Like

The rough idea was to optimize this for NPC’s as well in case I decide to add bosses.

you should have two separate scripts for this, NPCs, and the actual character. Also maybe the currentCharacter value returns nil, access the players character using the first arg like this

 Input_Ev.OnServerEvent:Connect(function(player: Player, Character: Model, Action: string)
        local character: Model = player.Character
	local CurrentCharacter: string = character:GetAttribute("Character") or DefaultCharacter
	
	local Moveset = LoadMoveset(character, CurrentCharacter)
	Moveset[Action]()
end)

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.