Invalid Argument #1 to 'pairs' (table expected, got nil)

Hello, I am creating a fighting game that has fighting moves be based upon a random selection out of a table of them, chosen on the server. When I first created my script for this system, I would send the current ability to the server, have the ability be ran, and have the server return the next ability to be used. However, the server sometimes returned the ability that was just used, and I attempted to create a system that fixes this. When I attempted to fix this however, I got a strange error message that I couldn’t fully understand, the one in the title.

This is my local script

if input.KeyCode == Enum.KeyCode.E then
			local returnAbility = useAbilityEvent:InvokeServer(damageCardName, "Damage") --this is where the error is coming from
			canKeyPress = false
			wait(returnAbility)
			script.Parent.Card2.Text = returnAbility
			damageCardName = returnAbility
			canKeyPress = true
		end

this is my server script

local function getItemIndexByName(itemName, itemTable)
	for i, item in pairs(itemTable) do
		if item == itemName then
			return(i)
		end
	end
end

useAbilityFunction.OnServerInvoke = function(player, abilityName, abilityType)
	if abilityType == "Damage" then
		local randomVal = math.random(1, #DamageAbilities)
		local itemIndex = getItemIndexByName(abilityName)
		table.remove(DamageAbilities, itemIndex)
		for num, value in pairs(DamageAbilities) do
			if num == randomVal then
				table.insert(DamageAbilities, itemIndex, abilityName)
				return(value)
			end
		end
	end
end

if you need any more info to help with this, let me know. Thank you!

you are only passing abilityName to getItemIndexByName, so itemTable is nil

pairs expects a table, not nil

.

1 Like

This worked, but created another problem. Now, it’s sending “Nil” back the to client instead of a text string, for the next ability to be used. I did some testing and the server actually has a value but the client still is receiving “Nil”. If you could help with this that would be great, thanks!

it looks like the only way it would return nil is if when you are looping through DamageAbilities, num never equals randomVal. for example, if the randomVal is the last index in the table, after removing the itemIndex, table will not have a value for the randomVal, then returning nil. It may also be something else, but I would suggest refactoring this code or adding prints to make sure everything is hat you think it is, for example adding a print(num, randomVal) before if num == randomVal then, then seeing in the output if all of the values are what you are expecting.

some options for refactoring,

  1. instead of getItemIndexByName, you can use table.find() (eg. table.find(itemTable, itemName))

  2. instead of looping through DamageAbilities and checking if num == randomVal, just return(DamageAbilities[randomVal])

note: sorry if this did not make sense, I am tired and had to try and make some guesses on what you are trying to do.

1 Like

thanks, I used table.find and i’m getting less error messages but the problem is still occurring. Thank you for your help, i’ll try to figure out the rest on my own. I’ll mark your original solution as the solution for anyone with the same problem finding this as it did solve my initial problem. Thanks again.

after getting some coffee and rereading your post, I have a better answer for you

use this as pseudo code

local testAbilities = {
	'ability1',
	'ability2',
	'ability3',
	'ability4'
}

--the function picks a random ability, if the ability is the lastAbility,
--then it will pick a new one, one thing to note is you need to make sure
--you always have 1 more ability that is not your last one, or you will get
--a stack overflow error
local function pickRandom(abilityTable, lastAbility)
	local rVal = math.random(1, #abilityTable)

	if abilityTable[rVal] == lastAbility then
		rVal = pickRandom(abilityTable, lastAbility)
	end

	return rVal
end


useAbilityFunction.OnServerInvoke = function(player, abilityName, abilityType)
	if abilityType == "Damage" then
		return testAbilities[pickRandom(testAbilities, abilityName)]
	end
end

note: sorry for posting after you already marked a solution

1 Like

Thank you for continually helping. I figured out what the problem was. When I remove a value from the table to prevent picking the same item again, I chose a random variable BEFORE doing it, so I chose a number that doesnt exist in the table. It’s fixed now and there are no more problems occurring. Thank you.