I need help with the "Getting Started" developer guide Chapter 3.

Hello, I am an absolute beginner to Corona and Lua and I am going through the getting started developer guide Chapter 3. I have gotten to a point where the guide wants me to save my code and re launch the simulator and when I do I am confronted with the following error:

ERROR: Runtime error
                    main.lua:104: ERROR: table expected. If this is a function call, you might have used ‘.’ instead of ‘:’
                    stack traceback:
                        [C]: in function ‘addBody’
                        main.lua:104: in main chunk

I have proof read  the code, deleted all the code and started over from scratch, deleted just that line of code (which resulted in further error), and even deleted it all and copied and pasted all of the code from the guide itself.

Can someone please tell me what is going wrong, I have tried everything I can think of to fix it and all I want to do is continue to the next part of the guide so I can learn more about using Corona and Lua.

Thank you so much.

The code:

local physics = require( “physics” )
physics.start()
physics.setGravity( 0, 0 )

– Seed the random number generator
math.randomseed( os.time() )

– Configure image sheet
local sheetOptions =
{
    frames =
    {
        {   – 1) asteroid 1
            x = 0,
            y = 0,
            width = 102,
            height = 85
        },
        {   – 2) asteroid 2
            x = 0,
            y = 85,
            width = 90,
            height = 83
        },
        {   – 3) asteroid 3
            x = 0,
            y = 168,
            width = 100,
            height = 97
        },
        {   – 4) ship
            x = 0,
            y = 265,
            width = 98,
            height = 79
        },
        {   – 5) laser
            x = 98,
            y = 265,
            width = 14,
            height = 40
        },
    }
}

local objectSheet = graphics.newImageSheet( “gameObjects.png”, sheetOptions )

– Initialize variables
local lives = 3
local score = 0
local died = false

local asteroidsTable = {}

local ship
local gameLoopTimer
local livesText
local scoreText

– Set up display groups
local backGroup = display.newGroup()  – Display group for the background image
local mainGroup = display.newGroup()  – Display group for the ship, asteroids, lasers, etc.
local uiGroup = display.newGroup()    – Display group for UI objects like the score

– Load the background
local background = display.newImageRect( backGroup, “background.png”, 800, 1400 )
background.x = display.contentCenterX
background.y = display.contentCenterY

ship = display.newImageRect( mainGroup, objectSheet, 4, 98, 79 )

ship.x = display.contentCenterX
ship.y = display.contentHeight - 100
physics.addBody( ship, { radius=30, isSensor=true } )
ship.myName = “ship”

– Display lives and score
livesText = display.newText( uiGroup, "Lives: " … lives, 200, 80, native.systemFont, 36 )
scoreText = display.newText( uiGroup, "Score: " … score, 400, 80, native.systemFont, 36 )

– Hide the status bar
display.setStatusBar( display.HiddenStatusBar )

local function updateText()
    livesText.text = "Lives: " … lives
    scoreText.text = "Score: " … score
end

–part2

local function createAsteroid()

    local newAsteroid = display.newImageRect( mainGroup, objectSheet, 1, 102, 85 )

end

table.insert( asteroidsTable, newAsteroid )
physics.addBody( newAsteroid, “dynamic”, { radius=40, bounce=0.8 } )
newAsteroid.myName = “asteroid”

local whereFrom = math.random( 3 )

if ( whereFrom == 1 ) then
    – From the left
    newAsteroid.x = -60
    newAsteroid.y = math.random( 500 )
    newAsteroid:setLinearVelocity( math.random( 40,120 ), math.random( 20,60 ) )

elseif ( whereFrom == 2 ) then
    – From the top
    newAsteroid.x = math.random( display.contentWidth )
    newAsteroid.y = -60
    newAsteroid:setLinearVelocity( math.random( -40,40 ), math.random( 40,120 ) )

elseif ( whereFrom == 3 ) then
    – From the right
    newAsteroid.x = display.contentWidth + 60
    newAsteroid.y = math.random( 500 )
    newAsteroid:setLinearVelocity( math.random( -120,-40 ), math.random( 20,60 ) )
end
newAsteroid:applyTorque( math.random( -6,6 ) )

local function fireLaser()
    local newLaser = display.newImageRect( mainGroup, objectSheet, 5, 14, 40 )
    physics.addBody( newLaser, “dynamic”, { isSensor=true } )
    newLaser.isBullet = true

end

newLaser.myName = “laser”
newLaser.x = ship.x
newLaser.y = ship.y
newLaser:toBack()

transition.to( newLaser, { y=-40, time=500,
    onComplete = function() display.remove( newLaser ) end
} )

ship:addEventListener( “tap”, fireLaser )
 

  1. When referring to a tutorial you are following, always post a link to it.  I’ve never used this tutorial so I don’t even know where to look to find it.  This makes comparing the tutorial to your work hard.

(_ You do get props for giving the name of the tutorial and page you are working on, but please give a link anyways. _)

 
2. Please format all code posts in the future.
formatyourcode.jpg
 
3. Also always be clear and point out what line we should be looking at. We can’t determine for certain what line 104 is from your code post.
 
 
4. Finally, to try to answer your question…
 
My guess is that this line is the problem:

physics.addBody( newAsteroid, "dynamic", { radius=40, bounce=0.8 } )

I think so, because it is clear that newAsteroid will be nil and cause this error.
 
You have this in your post:

local function createAsteroid() local newAsteroid = display.newImageRect( mainGroup, objectSheet, 1, 102, 85 ) end --- WRONG PLACE -- newAsteroid will always be nil from here on because it fell out of scope -- due to a (likely) misplaced end statement table.insert( asteroidsTable, newAsteroid ) physics.addBody( newAsteroid, "dynamic", { radius=40, bounce=0.8 } ) ... and so on

It should probably be this:
 

local function createAsteroid() local newAsteroid = display.newImageRect( mainGroup, objectSheet, 1, 102, 85 ) table.insert( asteroidsTable, newAsteroid ) physics.addBody( newAsteroid, "dynamic", { radius=40, bounce=0.8 } ) newAsteroid.myName = "asteroid" local whereFrom = math.random( 3 ) if ( whereFrom == 1 ) then -- From the left newAsteroid.x = -60 newAsteroid.y = math.random( 500 ) newAsteroid:setLinearVelocity( math.random( 40,120 ), math.random( 20,60 ) ) elseif ( whereFrom == 2 ) then -- From the top newAsteroid.x = math.random( display.contentWidth ) newAsteroid.y = -60 newAsteroid:setLinearVelocity( math.random( -40,40 ), math.random( 40,120 ) ) elseif ( whereFrom == 3 ) then -- From the right newAsteroid.x = display.contentWidth + 60 newAsteroid.y = math.random( 500 ) newAsteroid:setLinearVelocity( math.random( -120,-40 ), math.random( 20,60 ) ) end newAsteroid:applyTorque( math.random( -6,6 ) ) end

Here is the link to the tutorial: https://docs.coronalabs.com/guide/programming/03/index.html

Thank you for the constructive feedback despite my lack of knowledge of this forum’s etiquette.

As I said I am new to Corona and evidently the forums as well haha.

So I copied that code and pasted it as it is below:

local function createAsteroid() local newAsteroid = display.newImageRect( mainGroup, objectSheet, 1, 102, 85 ) table.insert( asteroidsTable, newAsteroid ) physics.addBody( newAsteroid, "dynamic", { radius=40, bounce=0.8 } ) newAsteroid.myName = "asteroid" local whereFrom = math.random( 3 ) if ( whereFrom == 1 ) then -- From the left newAsteroid.x = -60 newAsteroid.y = math.random( 500 ) newAsteroid:setLinearVelocity( math.random( 40,120 ), math.random( 20,60 ) ) elseif ( whereFrom == 2 ) then -- From the top newAsteroid.x = math.random( display.contentWidth ) newAsteroid.y = -60 newAsteroid:setLinearVelocity( math.random( -40,40 ), math.random( 40,120 ) ) elseif ( whereFrom == 3 ) then -- From the right newAsteroid.x = display.contentWidth + 60 newAsteroid.y = math.random( 500 ) newAsteroid:setLinearVelocity( math.random( -120,-40 ), math.random( 20,60 ) ) end newAsteroid:applyTorque( math.random( -6,6 ) ) end

Now I am presented with this error:

ERROR: Runtime error
                    main.lua:104: ERROR: table expected. If this is a function call, you might have used ‘.’ instead of ‘:’
                    stack traceback:
                        [C]: in function ‘addBody’
                        main.lua:104: in main chunk

Line 104 is the  blank line below.

 table.insert( asteroidsTable, newAsteroid ) physics.addBody( newAsteroid, "dynamic", { radius=40, bounce=0.8 } ) newAsteroid.myName = "asteroid" local whereFrom = math.random( 3 )

I very much appreciate your help.

  1. Kudos to you.  You found the ‘start at this line’ option for code posts.  Excellent.

  2. I think the line numbers are off however, or you’re not running the code you modified, because it is still referring to ‘addBody’ in the error message.  (It is very suspicious to me that the error is still on line 104 after you cut-copy-pasted over your code.)

2a. To verify you are running the code you modified, put a error at the front of the file:

-- on line one bob()

Now save and re-run.  If you don’t see an error about ‘bob()’ you’re not editing the code you’re running.  Folks make this mistake some times.

2b. If you do get a ‘bob()’ error, then something is wrong.  Please quit Corona and restart it.  Then re-run.  The line number should line up with the error message and make sense which line 104 in this context does not.  

Note: This message indicates one of two problems:

ERROR: Runtime error main.lua:104: ERROR: table expected. If this is a function call, you might have used '.' instead of ':' stack traceback: [C]: in function 'addBody' main.lua:104: in main chunk
  1. You called physics.addBody() as physics:addBody() - Not the problem you called it with a dot which is correct.

  2. You passed a nil as the first argument.  Likely the problem.  i.e. If the ‘newAsteroid’ is nil, the add body function call will fail.

Try this:

table.insert( asteroidsTable, newAsteroid ) print("newAsteroid == " .. tostring( newAsteroid ) ) -- NEW CODE HERE physics.addBody( newAsteroid, "dynamic", { radius=40, bounce=0.8 } ) newAsteroid.myName = "asteroid"

Tell me what the console says. for the new line of code.

If that line prints:

newAsteroid == nil

, then this line is the problem:

local newAsteroid = display.newImageRect( mainGroup, objectSheet, 1, 102, 85 )

You can quickly verify that by replacing it with this:

local newAsteroid = display.newRect( mainGroup, 0, 0, 102, 85 )

This will just create a rectangle.  If the error goes away, there is a problem with the code associated with making the asteroid, its sheet, etc.  (Be sure your images and code use matching cases.  That is a common issue.)

Well after re starting Corona and making sure I was in the correct file I copied and pasted just how I did in the previous post and now the error has moved further down away from the newAsteroid entirely.

ERROR: Syntax error
                    main.lua:147: ‘<eof>’ expected near ‘end’

local function fireLaser() local newLaser = display.newImageRect( mainGroup, objectSheet, 5, 14, 40 ) physics.addBody( newLaser, "dynamic", { isSensor=true } ) newLaser.isBullet = true newLaser.myName = "laser" newLaser.x = ship.x newLaser.y = ship.y newLaser:toBack() transition.to( newLaser, { y=-40, time=500, onComplete = function() display.remove( newLaser ) end } ) ship:addEventListener( "tap", fireLaser ) end end

I basically edited the firelaser command from how it was in my original post to something more similar to your edit of my newAsteroid command.

Let me suggest you go through your code and carefully manually re-indent it from line 1 till the end of the file.

You will probably find that you’ve got an extra ‘end’ statement in  your program.

PS  -

Even if your editor supports auto-indenting or re-indent, don’t use it for this correction.  

It may fail to find the problem, and even if it doesn’t you may miss the extra ‘end’

It is a real shame the completed code for this example isn’t available for download and comparison.

Alright now it is showing no errors in the code, however there are no asteroids nor laser functions in the simulator.

Full code:

----------------------------------------------------------------------------------------- -- -- main.lua -- ----------------------------------------------------------------------------------------- local physics = require( "physics" ) physics.start() physics.setGravity( 0, 0 ) -- Seed the random number generator math.randomseed( os.time() ) -- Configure image sheet local sheetOptions = { frames = { { -- 1) asteroid 1 x = 0, y = 0, width = 102, height = 85 }, { -- 2) asteroid 2 x = 0, y = 85, width = 90, height = 83 }, { -- 3) asteroid 3 x = 0, y = 168, width = 100, height = 97 }, { -- 4) ship x = 0, y = 265, width = 98, height = 79 }, { -- 5) laser x = 98, y = 265, width = 14, height = 40 }, } } local objectSheet = graphics.newImageSheet( "gameObjects.png", sheetOptions ) -- Initialize variables local lives = 3 local score = 0 local died = false local asteroidsTable = {} local ship local gameLoopTimer local livesText local scoreText -- Set up display groups local backGroup = display.newGroup() -- Display group for the background image local mainGroup = display.newGroup() -- Display group for the ship, asteroids, lasers, etc. local uiGroup = display.newGroup() -- Display group for UI objects like the score -- Load the background local background = display.newImageRect( backGroup, "background.png", 800, 1400 ) background.x = display.contentCenterX background.y = display.contentCenterY ship = display.newImageRect( mainGroup, objectSheet, 4, 98, 79 ) ship.x = display.contentCenterX ship.y = display.contentHeight - 100 physics.addBody( ship, { radius=30, isSensor=true } ) ship.myName = "ship" -- Display lives and score livesText = display.newText( uiGroup, "Lives: " .. lives, 200, 80, native.systemFont, 36 ) scoreText = display.newText( uiGroup, "Score: " .. score, 400, 80, native.systemFont, 36 ) -- Hide the status bar display.setStatusBar( display.HiddenStatusBar ) local function updateText() livesText.text = "Lives: " .. lives scoreText.text = "Score: " .. score end --part2 local function createAsteroid() local newAsteroid = display.newImageRect( mainGroup, objectSheet, 1, 102, 85 ) table.insert( asteroidsTable, newAsteroid ) physics.addBody( newAsteroid, "dynamic", { radius=40, bounce=0.8 } ) newAsteroid.myName = "asteroid" local whereFrom = math.random( 3 ) if ( whereFrom == 1 ) then -- From the left newAsteroid.x = -60 newAsteroid.y = math.random( 500 ) newAsteroid:setLinearVelocity( math.random( 40,120 ), math.random( 20,60 ) ) elseif ( whereFrom == 2 ) then -- From the top newAsteroid.x = math.random( display.contentWidth ) newAsteroid.y = -60 newAsteroid:setLinearVelocity( math.random( -40,40 ), math.random( 40,120 ) ) elseif ( whereFrom == 3 ) then -- From the right newAsteroid.x = display.contentWidth + 60 newAsteroid.y = math.random( 500 ) newAsteroid:setLinearVelocity( math.random( -120,-40 ), math.random( 20,60 ) ) end newAsteroid:applyTorque( math.random( -6,6 ) ) end local function fireLaser() local newLaser = display.newImageRect( mainGroup, objectSheet, 5, 14, 40 ) physics.addBody( newLaser, "dynamic", { isSensor=true } ) newLaser.isBullet = true newLaser.myName = "laser" newLaser.x = ship.x newLaser.y = ship.y newLaser:toBack() transition.to( newLaser, { y=-40, time=500, onComplete = function() display.remove( newLaser ) end } ) ship:addEventListener( "tap", fireLaser ) end

I’d go back and review my code step-by-step versus the tutorial.

I’m looking at the code (not the tutorial) and a couple things seem wrong.

  1. This line should not be in the fireLaser() function definition:

    ship:addEventListener( “tap”, fireLaser )

  2. I don’t see you calling ‘createAsteroid()’  and I don’t think you are supposed to call it manually.  There must be more to the tutorial.

PS - I’m taking off for the rest of the day and I think you’re on the way to getting this.  So, if you post again, be aware I won’t be posting back till at least Monday.  -Cheers.

I removed the event listener out of the firelaser function and I manually called the createasteroid command and now it seems to be working as intended. I am going to continue with the tutorial and see where that takes me. Thank you so much for your replies and help!

Also, upon reading further, I discovered that we later create a game loop so the asteroids weren’t supposed to be spawning yet.

Problem solved! :slight_smile:

  1. When referring to a tutorial you are following, always post a link to it.  I’ve never used this tutorial so I don’t even know where to look to find it.  This makes comparing the tutorial to your work hard.

(_ You do get props for giving the name of the tutorial and page you are working on, but please give a link anyways. _)

 
2. Please format all code posts in the future.
formatyourcode.jpg
 
3. Also always be clear and point out what line we should be looking at. We can’t determine for certain what line 104 is from your code post.
 
 
4. Finally, to try to answer your question…
 
My guess is that this line is the problem:

physics.addBody( newAsteroid, "dynamic", { radius=40, bounce=0.8 } )

I think so, because it is clear that newAsteroid will be nil and cause this error.
 
You have this in your post:

local function createAsteroid() local newAsteroid = display.newImageRect( mainGroup, objectSheet, 1, 102, 85 ) end --- WRONG PLACE -- newAsteroid will always be nil from here on because it fell out of scope -- due to a (likely) misplaced end statement table.insert( asteroidsTable, newAsteroid ) physics.addBody( newAsteroid, "dynamic", { radius=40, bounce=0.8 } ) ... and so on

It should probably be this:
 

local function createAsteroid() local newAsteroid = display.newImageRect( mainGroup, objectSheet, 1, 102, 85 ) table.insert( asteroidsTable, newAsteroid ) physics.addBody( newAsteroid, "dynamic", { radius=40, bounce=0.8 } ) newAsteroid.myName = "asteroid" local whereFrom = math.random( 3 ) if ( whereFrom == 1 ) then -- From the left newAsteroid.x = -60 newAsteroid.y = math.random( 500 ) newAsteroid:setLinearVelocity( math.random( 40,120 ), math.random( 20,60 ) ) elseif ( whereFrom == 2 ) then -- From the top newAsteroid.x = math.random( display.contentWidth ) newAsteroid.y = -60 newAsteroid:setLinearVelocity( math.random( -40,40 ), math.random( 40,120 ) ) elseif ( whereFrom == 3 ) then -- From the right newAsteroid.x = display.contentWidth + 60 newAsteroid.y = math.random( 500 ) newAsteroid:setLinearVelocity( math.random( -120,-40 ), math.random( 20,60 ) ) end newAsteroid:applyTorque( math.random( -6,6 ) ) end

Here is the link to the tutorial: https://docs.coronalabs.com/guide/programming/03/index.html

Thank you for the constructive feedback despite my lack of knowledge of this forum’s etiquette.

As I said I am new to Corona and evidently the forums as well haha.

So I copied that code and pasted it as it is below:

local function createAsteroid() local newAsteroid = display.newImageRect( mainGroup, objectSheet, 1, 102, 85 ) table.insert( asteroidsTable, newAsteroid ) physics.addBody( newAsteroid, "dynamic", { radius=40, bounce=0.8 } ) newAsteroid.myName = "asteroid" local whereFrom = math.random( 3 ) if ( whereFrom == 1 ) then -- From the left newAsteroid.x = -60 newAsteroid.y = math.random( 500 ) newAsteroid:setLinearVelocity( math.random( 40,120 ), math.random( 20,60 ) ) elseif ( whereFrom == 2 ) then -- From the top newAsteroid.x = math.random( display.contentWidth ) newAsteroid.y = -60 newAsteroid:setLinearVelocity( math.random( -40,40 ), math.random( 40,120 ) ) elseif ( whereFrom == 3 ) then -- From the right newAsteroid.x = display.contentWidth + 60 newAsteroid.y = math.random( 500 ) newAsteroid:setLinearVelocity( math.random( -120,-40 ), math.random( 20,60 ) ) end newAsteroid:applyTorque( math.random( -6,6 ) ) end

Now I am presented with this error:

ERROR: Runtime error
                    main.lua:104: ERROR: table expected. If this is a function call, you might have used ‘.’ instead of ‘:’
                    stack traceback:
                        [C]: in function ‘addBody’
                        main.lua:104: in main chunk

Line 104 is the  blank line below.

 table.insert( asteroidsTable, newAsteroid ) physics.addBody( newAsteroid, "dynamic", { radius=40, bounce=0.8 } ) newAsteroid.myName = "asteroid" local whereFrom = math.random( 3 )

I very much appreciate your help.

  1. Kudos to you.  You found the ‘start at this line’ option for code posts.  Excellent.

  2. I think the line numbers are off however, or you’re not running the code you modified, because it is still referring to ‘addBody’ in the error message.  (It is very suspicious to me that the error is still on line 104 after you cut-copy-pasted over your code.)

2a. To verify you are running the code you modified, put a error at the front of the file:

-- on line one bob()

Now save and re-run.  If you don’t see an error about ‘bob()’ you’re not editing the code you’re running.  Folks make this mistake some times.

2b. If you do get a ‘bob()’ error, then something is wrong.  Please quit Corona and restart it.  Then re-run.  The line number should line up with the error message and make sense which line 104 in this context does not.  

Note: This message indicates one of two problems:

ERROR: Runtime error main.lua:104: ERROR: table expected. If this is a function call, you might have used '.' instead of ':' stack traceback: [C]: in function 'addBody' main.lua:104: in main chunk
  1. You called physics.addBody() as physics:addBody() - Not the problem you called it with a dot which is correct.

  2. You passed a nil as the first argument.  Likely the problem.  i.e. If the ‘newAsteroid’ is nil, the add body function call will fail.

Try this:

table.insert( asteroidsTable, newAsteroid ) print("newAsteroid == " .. tostring( newAsteroid ) ) -- NEW CODE HERE physics.addBody( newAsteroid, "dynamic", { radius=40, bounce=0.8 } ) newAsteroid.myName = "asteroid"

Tell me what the console says. for the new line of code.

If that line prints:

newAsteroid == nil

, then this line is the problem:

local newAsteroid = display.newImageRect( mainGroup, objectSheet, 1, 102, 85 )

You can quickly verify that by replacing it with this:

local newAsteroid = display.newRect( mainGroup, 0, 0, 102, 85 )

This will just create a rectangle.  If the error goes away, there is a problem with the code associated with making the asteroid, its sheet, etc.  (Be sure your images and code use matching cases.  That is a common issue.)

Well after re starting Corona and making sure I was in the correct file I copied and pasted just how I did in the previous post and now the error has moved further down away from the newAsteroid entirely.

ERROR: Syntax error
                    main.lua:147: ‘<eof>’ expected near ‘end’

local function fireLaser() local newLaser = display.newImageRect( mainGroup, objectSheet, 5, 14, 40 ) physics.addBody( newLaser, "dynamic", { isSensor=true } ) newLaser.isBullet = true newLaser.myName = "laser" newLaser.x = ship.x newLaser.y = ship.y newLaser:toBack() transition.to( newLaser, { y=-40, time=500, onComplete = function() display.remove( newLaser ) end } ) ship:addEventListener( "tap", fireLaser ) end end

I basically edited the firelaser command from how it was in my original post to something more similar to your edit of my newAsteroid command.

Let me suggest you go through your code and carefully manually re-indent it from line 1 till the end of the file.

You will probably find that you’ve got an extra ‘end’ statement in  your program.

PS  -

Even if your editor supports auto-indenting or re-indent, don’t use it for this correction.  

It may fail to find the problem, and even if it doesn’t you may miss the extra ‘end’