Page 1 of 1

attempt to index local 'game' (a nil value)

Posted: Wed Oct 23, 2019 10:04 pm
by Accelerator
(Firstly, i barely understand how to fix errors in Love2D, so a little assistance in helping me solve this bug that completely OOFs my program would be a really nice treat for me. This is src (source) code for a copy of a game called 'Breakout' and this is the code for developing the bricks. Here's the line of code (4th line) that's causing the problem, as well as the function. (If the entire code is needed then say so.)

Code: Select all

function Brick:update(dt, game)
    self.psystem:update(dt)

    if (self.color == 6 and self.inPlay) then
       if(game.lockedBrick == false) then
            self.tier = 1
       else 
            self.tier = 0
       end
    end
end

Re: attempt to index local 'game' (a nil value)

Posted: Thu Oct 24, 2019 5:12 am
by zorg
Technically it's the 5th line if you cound the function line as well; wherever this function is called, the game parameter is either not passed to it, or it is, but it's empty.

Re: attempt to index local 'game' (a nil value)

Posted: Thu Oct 24, 2019 10:54 am
by Luke100000
So we need the full code, at least the lines from where you call the update function.

Also you do not need extra parentheses for the if statements in lua :)

Re: attempt to index local 'game' (a nil value)

Posted: Thu Oct 24, 2019 9:16 pm
by Accelerator
Here is the full Brick.lua code as requested in order to help me solve this error.

Code: Select all

Brick = Class{}

-- some of the colors in our palette (to be used with particle systems)
paletteColors = {
    -- blue
    [1] = {
        ['r'] = 99,
        ['g'] = 155,
        ['b'] = 255
    },
    -- green
    [2] = {
        ['r'] = 106,
        ['g'] = 190,
        ['b'] = 47
    },
    -- red
    [3] = {
        ['r'] = 217,
        ['g'] = 87,
        ['b'] = 99
    },
    -- purple
    [4] = {
        ['r'] = 215,
        ['g'] = 123,
        ['b'] = 186
    },
    -- gold
    [5] = {
        ['r'] = 251,
        ['g'] = 242,
        ['b'] = 54
    },
    -- black
    [6] = {
        ['r'] = 255,
        ['g'] = 255,
        ['b'] = 255
    }
}

function Brick:init(x, y)
    -- used for coloring and score calculation
    self.tier = 0
    self.color = 1
    
    self.x = x
    self.y = y
    self.width = 32
    self.height = 16
    
    -- used to determine whether this brick should be rendered
    self.inPlay = true

    -- particle system belonging to the brick, emitted on hit
    self.psystem = love.graphics.newParticleSystem(gTextures['particle'], 64)

    -- various behavior-determining functions for the particle system
    -- https://love2d.org/wiki/ParticleSystem

    -- lasts between 0.5-1 seconds seconds
    self.psystem:setParticleLifetime(0.5, 1)

    -- give it an acceleration of anywhere between X1,Y1 and X2,Y2 (0, 0) and (80, 80) here
    -- gives generally downward 
    self.psystem:setLinearAcceleration(-15, 0, 15, 80)

    -- spread of particles; normal looks more natural than uniform
    self.psystem:setAreaSpread('normal', 10, 10)

    -- CS50: used to determine if brick should spawn or not a powerup when destroyed
    self.isSpawner = false;
end

--[[
    Triggers a hit on the brick, taking it out of play if at 0 health or
    changing its color otherwise.
]]
function Brick:hit(game)
    -- set the particle system to interpolate between two colors; in this case, we give
    -- it our self.color but with varying alpha; brighter for higher tiers, fading to 0
    -- over the particle's lifetime (the second color)
    self.psystem:setColors(
        paletteColors[self.color].r,
        paletteColors[self.color].g,
        paletteColors[self.color].b,
        55 * (self.tier + 1),
        paletteColors[self.color].r,
        paletteColors[self.color].g,
        paletteColors[self.color].b,
        0
    )
    self.psystem:emit(64)

    -- sound on hit
    gSounds['brick-hit-2']:stop()
    gSounds['brick-hit-2']:play()

    -- if we're at a higher tier than the base, we need to go down a tier
    -- if we're already at the lowest color, else just go down a color
    if self.color == 6 then
        if(self.tier == 1) then
            self.inPlay = false
        end
    elseif self.tier > 0 then
        if self.color == 1 then
            self.tier = self.tier - 1
            self.color = 5
        else
            self.color = self.color - 1
        end
    else
        -- if we're in the first tier and the base color, remove brick from play
        if self.color == 1 then
            self.inPlay = false
        else
            self.color = self.color - 1
        end
    end

    -- play a second layer sound if the brick is destroyed
    if not self.inPlay then
        gSounds['brick-hit-1']:stop()
        gSounds['brick-hit-1']:play()

        -- CS50: When a brick is destroyed, roll a dice to check if a powerup is spawned or not
        if(rnd() <= POWERUP_SPAWNING_ODDS) then
            self.isSpawner = true;
        else
            self.isSpawner = false;
        end
    end
end

function Brick:update(dt, game)
    self.psystem:update(dt)

    if (self.color == 6 and self.inPlay) then
       if(game.lockedBrick == false) then
            self.tier = 1
       else 
            self.tier = 0
       end
    end
end

function Brick:render()
    if self.inPlay then
        love.graphics.draw(gTextures['main'], 
            -- multiply color by 4 (-1) to get our color offset, then add tier to that
            -- to draw the correct tier and color brick onto the screen
            gFrames['bricks'][1 + ((self.color - 1) * 4) + self.tier],
            self.x, self.y)
    end
end

--[[
    Need a separate render function for our particles so it can be called after all bricks are drawn;
    otherwise, some bricks would render over other bricks' particle systems.
]]
function Brick:renderParticles()
    love.graphics.draw(self.psystem, self.x + 16, self.y + 8)
end
One thing I notice about the error is that it occurs on when specific bricks are used in the game other than blue ones (bricks that disappear in one hit) so it may involve the different types of bricks?

Re: attempt to index local 'game' (a nil value)

Posted: Thu Oct 24, 2019 11:27 pm
by zorg
Luke (and i too, albeit less directly) requested the part of the code that -calls- Brick:update, since only there are you passing in anything to the game variable that becomes nil; After looking at it, Brick.lua does not have anything in it that helps.