Communicating between Modules?!

So i have started a new game project. This time around im trying to code my game in a better manner, having my game mechanic code in its own .lua file, and id like to have each level in its own .lua file. The problem im running into, is that i am able to communicate from 1 module to the other, but not vice versa.

for example. in my “level1” file, i do the following

[lua]local mechanic = require(“mechanic”)[/lua]

this allows me to call functions from my mechanics file, from the level 1 file. My question is, is it possible to call functions from my mechanics file that are in the level 1 file? I have tried adding
[lua]local level1 = require(“level1”)[/lua]
inside of my mechanic file, but i get an error that says something about a loop error…

anyways, any thoughts would be appreciated, i would rather not have my game logic have to be inside every level file of my game. i made that mistake last time around.

thank you [import]uid: 19620 topic_id: 15066 reply_id: 315066[/import]

I declare each module as a global variable in main.lua like the following:
g_menu = require(“g_menu”)
g_inst = require(“g_inst”)
g_play = require(“g_play”)

this way, you can call module g_menu’s function from module g_inst or vice versa. Or from any module to call any module’s funciton. script like the following:
g_menu.getLocalGroup() in module g_inst.

[import]uid: 42593 topic_id: 15066 reply_id: 55758[/import]

Great, thanks for the reply, ill give that a try right now! [import]uid: 19620 topic_id: 15066 reply_id: 55759[/import]

To get what you are after, you need to organise your files accordingly. You are after modular programming, where you want to add a particular module and get it to work. Right?

I will tell you the easiest way, the one that you have set out on. Your main file should have the logic of your game, the level related stuff can be in the level files.

If you were using plain lua, not the coronaSDK sandboxed version, you would have a few more commands that would give you a lot more flexibility.

If you also have a look at the sample from Johnathan Beebe’s Ghost Vs Monsters, it will show you a way, but I guess there each level file is the logic in itself.

You can also read up on how to use external modules/functions
Part #1 here
Part #2 here
Part #3 here
cheers,

?:slight_smile: [import]uid: 3826 topic_id: 15066 reply_id: 55824[/import]

Thank you so much for your post, i was still kind of unsatisfied on making this work how i wanted, but your tutorials seem to be just what the doctor ordered, ill read them over and let you know how it goes, thank you again. [import]uid: 19620 topic_id: 15066 reply_id: 55906[/import]

consider to setup your modules without

module(…,package.seeall)

there are some problems with that…
When you require a module, all functions become global.
and that is bad in several ways.
it’s easy to set up your “modules” without making the functions global and risk memory leaks and crashes you can not fix.

—> http://blog.anscamobile.com/2011/09/a-better-approach-to-external-modules/

cheers
-finefin
[import]uid: 70635 topic_id: 15066 reply_id: 55908[/import]

Yea i actually began this whole process by running across john beebees recent blog post that you put there. Ive been trying to use his method that he explains, and like i stated in my first post, using his method, im able to communicate from my level file to functions in my mechanic file, but i cant call functions from the level file in my mechanic file ( hope that makes sense ) Everyone else must just have way more coding experience than me, because everyone on that blog post just says " oh yea thats perfect ". Ive had a hard time implementing, but ill keep trying! [import]uid: 19620 topic_id: 15066 reply_id: 55909[/import]

everyone says “oh yeah perfect” because they know that they have to try to keep everything “local” - and the module function creates global objects.

so basically, you index all your functions inside a table and “return” that table to any other module that asks for it (via “require”).

in that way your functions won’t fly around in space (memory) and won’t block variable names.

try this (bad code):

main.lua

require ( "mod1" ) -- require first module without function call   
require ( "mod2" ).myFunction () -- call the function of second module  

mod1.lua

module(..., package.seeall)  
function myFunction ()  
 print ( "MOD 1" )   
end  

mod2.lua

module(..., package.seeall)  
function myFunction ()  
 print ( "MOD 2" )  
 mod1.myFunction ()   
end  

when you start this, the output will be

MOD 2
MOD 1

mod2 is able to call the function of mod1 because mod1 is global.
you don’t really want that. It’s LUA-rule #1: keep things local.
change the mod.lua files

to this (good code):

mod1.lua

local M = {}  
function M.myFunction ()  
 print ( "MOD 1" )  
end  
return M  

mod2.lua

local M = {}  
function M.myFunction ()  
 print ( "MOD 2" )  
 mod1.myFunction () -- ERROR!!!  
end  
return M  

This will invoke an error, because mod1 isn’t global anymore.
If you want to call a function of mod1, you have to require it in.

mod2.lua

local M = {}  
function M.myFunction ()  
 print ( "MOD 2" )  
 require ( "mod1" ).myFunction () -- output: MOD 1  
end  
return M  

If you want to get some data from a module, return something:

mod1.lua

local M = {}  
function M.makeRandomNumber ( range )  
 local newNumber1 = math.random ( range )  
 print ( "MOD 1 newNumber1: "..newNumber1 )  
 return newNumber1  
end  
return M  

mod2.lua

local M = {}  
function M.myFunction ()  
 local newNumber2 = require ( "mod1" ).makeRandomNumber ( 10 )  
 print ( "MOD 2 newNumber2: "..newNumber2 )  
end  
return M  

output would be:
MOD 1 newNumber1: 4
MOD 2 newNumber2: 4

or any other number between 1 - 10…

I hope that clears anything up :slight_smile:

-finefin
[import]uid: 70635 topic_id: 15066 reply_id: 55921[/import]

Awesome, thanks for the in depth post. I did get it working how i would like by looking at your examples. My only question is on this line of code:
[lua]require ( “mod1” ).myFunction () – output: MOD 1[/lua]

just wondering if having it run that line of code that includes “require” is going to cause any memory leak issues? or is that normal to call it this way? ( if i am calling the function that contains this code several times )

thanks again. [import]uid: 19620 topic_id: 15066 reply_id: 55930[/import]

yeah, that was quick and dirty, I know
but I think you can do that without memory issues and everything is garbage collected… prove me wrong :slight_smile:

but sure, normally you would do something like this

local mod1 = require ( "mod1" )  
local modFunction = mod1.myFunction()  

[import]uid: 70635 topic_id: 15066 reply_id: 55940[/import]