Search code examples
lualove2d

Why does it say: "Bad argument #1 to 'remove' (table expected, got nil)'"


I'm trying to spawn random bullets from the side of the screen that the player has to dodge. When I try to do this, I get this error:

Error

main.lua:69: bad argument #1 to 'remove' (table expected, got nil)


Traceback

[C]: in function 'remove'
main.lua:69: in function 'update'
[C]: in function 'xpcall'

I've tried to look around and see what I can do, but I can't find much. Sorry, if this is a newbie question, I'm REALLY new to Lua and Love2D.

Here is my entire code: (Error on line 69)


    function love.load()
        p = {}
        p.x = 330
        p.y = 330
        p.score = 0
        -------------
        b = {}
        b.size = 10
        b.cooldown = 150
        b.bullets = {}
        b.shoot = function()
            if b.cooldown <= 0 then
                b.cooldown = 50
                bullet = {}
                bullet.x = 0
                bullet.y = love.math.random(0, 690)
                table.insert(b.bullets, bullet)
            end
        end

    end


    function love.update(dt)
        p.score = p.score + 1
        b.cooldown = b.cooldown - 1
    -- movement of player (and the border)
        if love.keyboard.isDown("w") then
            if p.y <= 0 then
                p.y = 0
            end

            p.y = p.y - 3
        end

        if love.keyboard.isDown("s") then
            if p.y >= 680 then
                p.y = 680
            end

            p.y = p.y + 3
        end

        if love.keyboard.isDown("a") then
            if p.x <= 0 then
                p.x = 0
            end

            p.x = p.x - 3
        end

        if love.keyboard.isDown("d") then
            if p.x >= 680 then
                p.x = 680
            end
            p.x = p.x + 3
        end



    -- cooldown wait and shoot
        if b.cooldown <= 0 then
            b.shoot()
        end

    -- removes bullet when out of sight or moves bullets forward
        for i, b in ipairs(b.bullets) do
            if bullet.x >= 0 then
                table.remove(b.bullets, i)
            end
        bullet.x = bullet.x + 5
        end
    end

    function love.draw()
        love.graphics.setBackgroundColor(153, 76, 0)
        love.graphics.setColor(255, 0, 0)
        love.graphics.rectangle("fill", p.x, p.y, 20, 20)
        love.graphics.print("p.x:" .. p.x .. " p.y:" .. p.y .. "    SCORE: " .. p.score .. "Cooldown: " .. b.cooldown, 0,0,0, 1, 1)

        --draw bullets
        love.graphics.setColor(255,0,0)
        for _,b in pairs(b.bullets) do
            love.graphics.rectangle("fill", bullet.y, bullet.x, bullet.size, bullet.size)
        end

    end

Solution

  • The error message tells you that you have an error in line 69. The Lua interpreter complains that you put a nil value into the table.remove function instead of the expected table value.

    So let's have a looik at your code:

    -- removes bullet when out of sight or moves bullets forward
    for i, b in ipairs(b.bullets) do
      if bullet.x >= 0 then
        table.remove(b.bullets, i)
      end
      bullet.x = bullet.x + 5
    end
    

    You iterate over table b.bullets and store the current value in a variable b, local to the for loop. That means inside the for loop you no longer have access to your global table b, which contains the table bullets.

    As your local b does not have any member named bullets, b.bullets is a nil value inside the for loop.

    Using table.remove on a table you're iterating over with ipairs is also not going to work. Let's say you have a table like this:

    a = {1,2,3,4,5}
    

    and you do this

    for i,v in ipairs(a) do
      table.remove(a, i)
    end
    

    In the first run using index 1 you'll remove 1 which will result in a new table {2,3,4,5}. In the next cycle using index 2 you'll remove 3 instead of 2 as 3 is now your second element. After removing 3 your table is {2,4,5}. Next round with index 3 you'll remove 5 from the table. As this was the last element in your table the loop is done after 3 iterations instead of 5 and you'll end up with 2 elements left in the table instead of 0.

    There are various other issues with your code but I suggest you first make sure that you understand the scope of variables in Lua befor you continue.