Attempt to index upvalue

Before everything was fine, but now I am getting this error:

attempt to index upvalue ‘weapon’ (a nil value)

This line is causing error:

if weapon.removeSelf then
  --some code
end

weapon is probably out of scope.

But there is local weapon about 300 lines above that function

Try this simple debugging method to see what’s wrong:

print (weapon)
print (weapon.removeSelf)

if weapon.removeSelf then
  --some code
end

it outputs only one nil

If print (weapon) is nil then you may have a scope issue or weapon is destroyed before that code snippet is called. For more information on scope - http://lua-users.org/wiki/ScopeTutorial

If print (weapon.removeSelf) is nil then it means there’s something wrong with removeSelf attribute.

From your first post it is clear that weapon is nil, i.e not assigned any value. It can be nil due to one of three reasons:

  1. It is declared out of scope
  2. You never assign a value to it
  3. You explicitly set it to nil after assigning it a value

So, I wonder where do you assign a value to weapon? Just declaring it as local weapon is not enough, even if it is within scope.

I guess you must have something like this somewhere in your code, right?

weapon = display.newImageRect(...)

If you’re not familiar with the term “scope”, this is an example when weapon would be out of scope:

if (a > b) then
  local weapon = display.newImageRect(...)
end

[[--
weapon is out of scope here, because it was declared as a local inside of the if block above.
Therefore it will only exist within that if block.
--]]
weapon.removeSelf()

As @bgmadclown says, debugging using simple print statements should tell you pretty quickly where the problem is. If weapon is nil when you try to print it, then it is not within that scope or it has not been assigned any value.

my code is something like that:

local weapon
function equipWeapon()
  weapon = display.newImage(...)
end

...

function move()
  if weapon.removeSelf then
    weapon.x = display.contentCenterX - 30
    weapon.y = display.contentCenterY - 50
    weapon.rotation = 270
  end
end

And error happens before equipWeapon function fires(I have to press button to fire equipWeapon function). And move function is in my control, too(joystic)

Ok, well I don’t see an assignment to weapon anywhere… Is it done within equipWeapon()? You’re not really giving us the whole picture here so it’s hard to help.

I’m looking for something like:

weapon = ...

Also, you got it wrong with the meaning of variable declaration.

--[[ THIS is where weapon is declared --]]
local weapon

that weapon = … is in the equipWeapon function end error happens before equipWeapon function fires(I have to press button to fire equipWeapon function)

What you’re saying is basically that you already know what the problem is then: You’re trying to use the weapon variable before assigning it a value.

Not sure why you want to do that, but you can’t expect it to work…

The thing is what I frequently remove and re-add weapon, because player can equip and unequip weapon weapon doesn’t need to show until player equips it(presses button).
Maybe I just need to hide it without removing it?

Yes, there is a big difference in creating the weapon and equipping it. You can create a weapon and then equip/unequip it as you wish.

Example: player.weapon = weapon

There is no way to index the weapon object (for example weapon.removeSelf) unless you first create it.

What you’re doing in your code, step by step, if you just look at the parts regarding the weapon and remove the functions is this:

local weapon
-- Weapon is nil here, so it crashes as soon as you try to index it
if weapon.removeSelf then
  weapon.x = display.contentCenterX - 30
  weapon.y = display.contentCenterY - 50
  weapon.rotation = 270
end
-- This has to be done before you try to index weapon
weapon = display.newImage(...)
1 Like

Ok, thanks