Call missing method of table; problem with metatable

I’m trying to create a move system for my battlegrounds game, but every time I try to call a move I get the same error:

ServerScriptService.Script:39: attempt to call missing method 'movePerform' of table  -  Server - Script:39

Here’s my script:

local Players = game:GetService("Players")
local ServerScriptService = game:GetService("ServerScriptService")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GetSignalCS = ReplicatedStorage:WaitForChild("SendSignalCS")

local MoveModule = require(ServerScriptService.MoveModule)

local PlayerList = {}

Players.PlayerAdded:Connect(function(Player)
	local Char = Player.Character or Player.CharacterAdded:Wait()
	local Tool = Char:FindFirstChildWhichIsA("Tool") or Player.Backpack:FindFirstChildWhichIsA("Tool")
	local CharSet = MoveModule.new(Char:WaitForChild("Humanoid"), Tool)
	table.insert(PlayerList, CharSet)
	Player.CharacterAdded:Connect(function(Character)
		Tool = Character:FindFirstChildWhichIsA("Tool") or Player.Backpack:FindFirstChildWhichIsA("Tool")
		CharSet = MoveModule.new(Character:WaitForChild("Humanoid"), Tool)
		table.insert(PlayerList, CharSet)
	end)
	print(getmetatable(CharSet)) --returns the MoveModule, expected
	
	Player.CharacterRemoving:Connect(function(Character)
		for i, CharGet in pairs(PlayerList) do
			if (CharGet.ReferredUser).Parent == Character then
				table.remove(PlayerList, i)
			end
		end
	end)
end)

GetSignalCS.OnServerEvent:Connect(function(plr, signalType : string)
	local getPlayerChar
	for _, player in pairs(PlayerList) do
		if player.ReferredUser.Parent == plr.Character then
			getPlayerChar = player
			print(getPlayerChar) --returns the table created by MoveModule, expected
		end
	end
	getPlayerChar:movePerform(signalType, 5, 2, {"Hitbox", false})
end)

and here’s the MoveModule:

local Players = game:GetService("Players")

local ParryEnabled = {}

--Hitbox Setup
local Hitbox = require(script:WaitForChild("HitboxRaycast"))

--AOE Setup
local AOE = require(script:WaitForChild("AOESystem"))

local charDetails = {}
charDetails._index = charDetails

function charDetails.new(user : Humanoid, wpn : Tool)
	local newChar = {}
	setmetatable(newChar, charDetails)
	newChar.ReferredUser = user
	newChar.Weapon = wpn
	local plrChar = user.Parent
	local getHitbox = wpn:WaitForChild("Hitbox")
	print()
	newChar.PlayerHitbox = Hitbox.new(plrChar:WaitForChild("Hitbox"), 0, false, user)
	newChar.WeaponHitbox = Hitbox.new(wpn:WaitForChild("Hitbox"), 0.5, false, user)
	if wpn:FindFirstChild("HitboxAlt") then
		newChar.AltWeaponHitbox = Hitbox.new(wpn:WaitForChild("HitboxAlt"), 0.5, false, user)
	else
		newChar.AltWeaponHitbox = newChar.WeaponHitbox
	end
	newChar.AOEBase = AOE.new(plrChar:WaitForChild("Hitbox"))
	return newChar
end

function charDetails:movePerform(animName : string, dmgOutput : number, hitCheckStamp : number, specParams : table)
    --insert code that isn't necessary
end

return charDetails

Truthfully, I can just barely grasp the concept of metatables, so any help would be much appreciated.

Try this on your server script instead:

local Players = game:GetService("Players")
local ServerScriptService = game:GetService("ServerScriptService")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GetSignalCS = ReplicatedStorage:WaitForChild("SendSignalCS")

local MoveModule = require(ServerScriptService.MoveModule)

local PlayerList = {}

local function _characterAdded(player : Player, character : Model)
	if PlayerList[player] then
		table.clear(PlayerList[player])
		PlayerList[player] = nil
	end

	local humanoid = character:WaitForChild("Humanoid", 1)
	local Tool = character:FindFirstChildWhichIsA("Tool") or player.Backpack:FindFirstChildWhichIsA("Tool")
	local CharSet = MoveModule.new(humanoid, Tool)
	PlayerList[player] = CharSet
end

local function _playerAdded(Player)
	Player.CharacterAdded:Connect(function(character)
		_characterAdded(Player, character)
	end)

	Player.CharacterRemoving:Connect(function(Character)
		if PlayerList[Player] then
			table.clear(PlayerList[Player])
			PlayerList[Player] = nil
		end
	end)
end

local function _playerRemoving(Player)
	if PlayerList[Player] then
		table.clear(PlayerList[Player])
		PlayerList[Player] = nil
	end
end

GetSignalCS.OnServerEvent:Connect(function(plr, signalType : string)
	local getPlayerChar
	for _, player in pairs(PlayerList) do
		if player.ReferredUser.Parent == plr.Character then
			getPlayerChar = player
			print(getPlayerChar) --returns the table created by MoveModule, expected
		end
	end
	getPlayerChar:movePerform(signalType, 5, 2, {"Hitbox", false})
end)

Players.PlayerAdded:Connect(_playerAdded)
Players.PlayerRemoving:Connect(_playerRemoving)
for _, player in Players:GetPlayers() do
	_playerAdded(player)
end

Try changing this to charDetails.__index (note the double underscore)

1 Like

Didn’t know it was two underscores, thanks

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