director error: must have new() function

Hey everyone,

I’m having a bear of a problem with the Director class and I am stumped!

I’m attempting to switch to a “credits” screen from my menu screen. then menu screen works to start the game but when the button to switch to the “credits” screen is tapped. I get the following error:

-----------------------  
Director ERROR: Module 'credits' must have a new() function.  
-----------------------  
nil  
-----------------------  

I’m sure this is something simple that my exhausted brain is missing

here is the code for the credits.lua file

module(..., package.seeall)  
  
 function new()  
 local localGroup = display.newGroup();  
  
 local credits = display.newImage("credits.png");  
 credits.scene = "start";  
 localGroup:insert(credits);  
  
 function changeScene(e)  
 if(e.phase == "ended") then  
 director:changeScene(e.target.scene);  
 end  
 end  
  
credits:addEventListener("touch", changeScene)  
  
 return localGroup;  
end  
  

Thanks for the help. [import]uid: 10763 topic_id: 17066 reply_id: 317066[/import]

@joxenford, I don’t see any problem with your code, so I copied your credits.lua file to temp.lua file, which I placed in my project folder.

I also changed the “credits.png” to a png file that I already use in my project.

And then, I made a quick change:
[lua]-- in my main.lua file, I commented the director:changeScene(“menu”, “crossfade”);
–and added the following in its place
director:changeScene(“temp”, “crossfade”);

– in temp.lua file, I changed the credits.scene = “start” to:
credits.scene = “menu”[/lua]

The temp.lua (which is your credits.lua) launched without any problem. Touching the screen also changed screen from temp.lua to menu.lua.

So, I’d say there’s nothing wrong with the code you’ve posted. You either have some bug in your credits.lua file that you have not included in the code you posted, or… you don’t have the credits.png in your project folder. If you don’t have this png file that you’re telling your app to load, it can trigger an error too.

Naomi

[import]uid: 67217 topic_id: 17066 reply_id: 64075[/import]

Naomi,
Thanks for your reply. I KNOW it seems like it should be working but it’s not…

The png file exists. I thought that might be the problem so I swapped it with known files used elsewhere.

Here is the code for my “start” screen:

module(..., package.seeall)  
  
 function new()  
 local localGroup = display.newGroup()  
 -- Music  
 music.playOChristmasTree ()  
 --Background  
 local background = display.newImageRect( "TitlePage.png",320,480 )  
 background:setReferencePoint(display.CenterReferencePoint);  
 background.x = \_W/2; background.y = \_H /2;  
 localGroup:insert(background)  
  
 -- buttons  
  
 local g\_button = display.newImageRect ("GO\_button.png",320, 480)  
 transition.from(g\_button,{time=500, delay=3500, alpha=0, onComplete=RemoveObj})  
 g\_button.x = 160  
 g\_button.y = 331  
 g\_button.scene = "scene1";  
 localGroup:insert(g\_button)  
  
 local credit\_button = display.newImage("images/credit\_button.png")  
 credit\_button.x = 160  
 credit\_button.y = 430  
 credit\_button.scene = "credits";  
 localGroup:insert(credit\_button)  
  
 function changeScene(e)  
 if(e.phase == "ended") then  
 director:changeScene(e.target.scene, "crossfade");  
 end  
 end  
 g\_button:addEventListener("touch", changeScene)  
 credit\_button:addEventListener("touch", changeScene)  
  
 return localGroup  
  
end  

Here is the code for my “credits” screen

module(..., package.seeall)  
  
function new()  
 local localGroup = display.newGroup();  
  
 local credits = display.newImage("Tree\_Day\_scene.png");  
 credits.scene = "start";  
 localGroup:insert(credits);  
  
 function changeScene(e)  
 if(e.phase == "ended") then  
 director:changeScene(e.target.scene, "crossfade");  
 end  
 end  
  
credits:addEventListener("touch", changeScene)  
  
 return localGroup;  
end  

Thanks for taking a look. I appreciate it. [import]uid: 10763 topic_id: 17066 reply_id: 64081[/import]

@joxenford, I have a feeling the problem is with line 16 (transition). Try commenting it out and see what happens.

Naomi [import]uid: 67217 topic_id: 17066 reply_id: 64088[/import]

I think you might have a local and a global with the same name.

If you have a local display object or function named “credits”, and you have a credits.lua file that you are trying to switch to, I think that makes “credits” a global so director knows what file to load.

So, when director go looking for “credits” it’s getting your local instead of the global. Just change the name or one or the other and see if it works. [import]uid: 67839 topic_id: 17066 reply_id: 64096[/import]

Why not simplify things:

module(..., package.seeall)  
   
function new()  
 local localGroup = display.newGroup();  
  
 local credits = display.newImage("Tree\_Day\_scene.png");  
 localGroup:insert(credits);  
  
 function changeScene(e)  
 director:changeScene("start", "crossfade");  
 end  
  
 credits:addEventListener("tap", changeScene)  
  
 return localGroup;  
end  

You’re trying to use the event table in a way that could be used if there were multiple things calling changeScene() and you want the flexibility to do that. But in this case, your simply returning to your previous screen and you’re hard coding that name anyway.

I also changed it from touch to tap. You don’t need any information that touch gives you to do what you want, so why not just go the simple route (at least until you debug what’s wrong) [import]uid: 19626 topic_id: 17066 reply_id: 64114[/import]

ok…first of all, thanks for all your help…but nothing suggested is working.

I tried all three suggestions and my credits.lua file now looks like so:

module(..., package.seeall)  
   
function new()  
 local localGroup = display.newGroup();  
  
 local creditsScene = display.newImage("Tree\_Day\_scene.png");  
 localGroup:insert(creditsScene);  
  
 function changeScene(e)  
 director:changeScene("start", "crossfade");  
 end  
  
 creditsScene:addEventListener("tap", changeScene)  
  
 return localGroup;  
end  

I can’t thank you all enough for pitching in to help…any other ideas?

i also see this error in the console:

Runtime error .../director.lua:934: ERROR: table expected. If this is a function call, you might have used '.' instead of ':' stack traceback: [import]uid: 10763 topic_id: 17066 reply_id: 64124[/import]

Do you get a pop-up alert from Director saying that it failed or is it only showing in the console?

What frustrated me with Director 1.4 was I would get this popup alert type message in the simulator saying there was an error. I would go to the console and have nothing useful to go on.

But what I discovered is if I clicked that alert away, a couple of seconds later the real error would show up in the console log. I’m pretty sure this is a director 1.4 “feature”.

If you are looking at the console log before you click that alert away, then you might be missing the issue.

The only other thing I can see is that you’re using mixed case for the filename. The filesystem is case sensitive and your filename has to match exactly.

So if your file is tree_day_scene.png, Tree_Day_scene.png won’t match. I try to keep all filenames all lower case where possible.

You might want to make your “changeScene” function local in case you’re using that in other modules, it’s global and could cause a problem.

[import]uid: 19626 topic_id: 17066 reply_id: 64125[/import]

One more thing I see (in addition to what Rob noted above) is that, you seem to have a folder called “images”, but you also seem to have images outside of the folder:
[lua]-- image not in the “images” folder
local credits = display.newImage(“Tree_Day_scene.png”)

– image inside the “images” folder
local credit_button = display.newImage(“images/credit_button.png”)[/lua]

If all fails, I suggest adding print statements everywhere, and find out what line of code triggers the error.

Naomi [import]uid: 67217 topic_id: 17066 reply_id: 64127[/import]

Also, just in case… do you have showDebug set to true in director.lua?

Open the director.lua, and the first thing you see is TOGGLE DEBUG. If it’s set to false, change it to true. This will give you better error message.

Naomi [import]uid: 67217 topic_id: 17066 reply_id: 64129[/import]

@Naomi

Debug is enabled, I checked that earlier today :slight_smile:
[import]uid: 10763 topic_id: 17066 reply_id: 64131[/import]

@Naomi, Yes, I was in the process of moving images into the /images dir in an effort to clean up stuff. I would move the image, change the path in code and test…somewhere in the middle of all that I got inspired to work on the credits scene.
[import]uid: 10763 topic_id: 17066 reply_id: 64132[/import]

@robmiracle

Cases match an the error(s) I’m seeing are the same as what I communicated in this thread.

See screen shot of errors here:

http://cl.ly/0u0p1G0k2J1Z3e37343z

[import]uid: 10763 topic_id: 17066 reply_id: 64135[/import]

Click away that director error alert on the left, then look back at the console log for messages printed after the dialog goes away.
[import]uid: 19626 topic_id: 17066 reply_id: 64138[/import]

@robmiracle

-----------------------  
Director ERROR: Module 'credits' must have a new() function.  
-----------------------  
nil  
-----------------------  

That’s what appears when I click the “ok” button [import]uid: 10763 topic_id: 17066 reply_id: 64139[/import]

Okay I just conducted a test with this code:

menu.lua -----------------------------------  
  
module(..., package.seeall)  
  
function new()  
 local localGroup = display.newGroup()  
  
 function changeScene()  
 director:changeScene("testmodule", "crossfade");  
 end  
  
 local blah = display.newRect(0,0,10,10);  
 localGroup:insert(blah)  
 blah:addEventListener("tap", changeScene);  
  
 function localGroup:cleanUp()  
 localGroup:removeSelf()  
 localGroup = nil  
 end  
  
------------------------------------------------------------------------------  
------------------------------------------------------------------------------  
 return localGroup  
end  
  
testmodule.lua ---------------------------   
module(..., package.seeall)  
   
function new()  
 local localGroup = display.newGroup();  
  
 local creditsScene = display.newRect(100,100,100,100);  
 localGroup:insert(creditsScene);  
  
 function changeScene(e)  
 director:changeScene("menu", "crossfade");  
 end  
  
 creditsScene:addEventListener("tap", changeScene)  
  
 return localGroup;  
end  
  

of course main.lua calls menu.lua

This run with no errors. The only thing I changed is not loading the image and using a rectangle instead. And my module is called “testmodule” not “start”. Does start.lua exist? [import]uid: 19626 topic_id: 17066 reply_id: 64149[/import]

@robmiracle

Yes, start.lua exists. The entire game works EXCEPT for this credits screen.

start.lua below:

[code]
module(…, package.seeall)

function new()
local localGroup = display.newGroup()
– Music
music.playOChristmasTree ()
–Background
local background = display.newImageRect( “TitlePage.png”,320,480 )
background:setReferencePoint(display.CenterReferencePoint);
background.x = _W/2; background.y = _H /2;
localGroup:insert(background)

– buttons

local g_button = display.newImageRect (“GO_button.png”,320, 480)
–transition.from(g_button,{time=500, delay=3500, alpha=0, onComplete=RemoveObj})
g_button.x = 160
g_button.y = 331
g_button.scene = “scene1”;
localGroup:insert(g_button)

local credit_button = display.newImage(“images/credit_button.png”)
credit_button.x = 160
credit_button.y = 430
credit_button.scene = “credits”;
localGroup:insert(credit_button)

function changeScene(e)
director:changeScene(e.target.scene, “crossfade”);
audio.stop(1);
end
g_button:addEventListener(“tap”, changeScene)
credit_button:addEventListener(“tap”, changeScene)

return localGroup

end

[/code] [import]uid: 10763 topic_id: 17066 reply_id: 64251[/import]

I really don’t like that you’re not making “function changeScene”. That function is global yet in another module you’re using the same function name, in effect writing over top of each other. Find every place where you have:

function changeScene(e)

and change it to:

local function changeScene(e)

and see if it goes away.

on a side note, you should probably stop your audio before calling director:changeScene…

This is a problem due to something called “Scope”. Hetal wrote an excellent blog post about function scope a few weeks ago:

http://blog.anscamobile.com/2011/09/tutorial-scopes-for-functions/

I also wrote a post on scope for variables, but since function names are just variables it’s also applicable:

http://omnigeek.robmiracle.com/2011/10/14/understanding-scope-for-beginning-programmers/

Rob [import]uid: 19626 topic_id: 17066 reply_id: 64291[/import]

@robmiracle

I changed all the global function changeScence to locals and still no dice.

Same error.

Here’s the real gotcha. If I switch the change scene for the credits_button to “scene1” (the start of the game level) it works. Does this tell us the problem solely exists with the credits.lua file?

[import]uid: 10763 topic_id: 17066 reply_id: 64447[/import]

Ok…I fixed this by renaming the credits.lua file to cred.lua.

Thanks to everyone for all the help. Hopefully, I can returns the favor one day.

@robmiracle, I am reading the links you provided re: scope. Thanks. [import]uid: 10763 topic_id: 17066 reply_id: 64652[/import]