Loading Modules dynamically

The Situation
 
I am scripting actions of certain cards in my trading card game. Each card has there own Lua script that loads there scriptable behaviors for them (for special card effects that alter the rules of the game). Things like onTrash or onPlaced lie in the Lua script files. 
 
The project structure is like so:
    Root Folder
        ~ data
            > cards
                 * behaviors
                     - 011.lua
                     - 012.lua (The files are named after the id of the cards)
                     - etc…
                 * cards.json (Contains an array of data for the cards)
        ~ main.lua (For now we’ll say the cards are loaded in main.lua)
 
Cards are loaded the cards.json file. A for loop goes through the array in the json file and applies an effect using a script that is associated with the card.
 
The script looks like this:
[lua]local M = {}

function M.main(card)

    function card:onPlace(event)

    end

    function card:onTrash(event)

    end

    function card:onDraw(event)

    end

    function card:activate(event)

    end

end
[/lua]
 
The game is supposed to require the script and apply the functions you see to the card object passed through.
 
The Problem

The problem is the script works in the simulator if I run it from sublime and only from any other file besides the card script. When I build the app for android, it doesn’t work either.

Here is the code:

[lua]for k,v in ipairs(cards) do

    if v.type == “effect” then

        local behavior = require(“data.cards.behaviors.” … string.format("%03d", v.id))

        if behavior then 

            behavior.main(v)

        end

end[/lua]

I was wondering if it had something to do with my code, the simulator, or just Corona SDK?

Hi @arjay.yabut07,

My initial thought is that “id” is an invalid (nil) string (line 5 in the code block above). Shouldn’t it be something like “v.id” because it’s part of the “ipairs()” iteration just like “v.type”?

Best regards,

Brent

That was just a typo for when I was writing the code into the editor.

OK, in terms of file-related things that work in the Simulator but not on a device, that is usually (99%) a case mismatch issue, for example you write “data” (lowercase “d”) in your code but the project folder is “Data” (capital “D”). The Simulator is very forgiving on case matches folders/files, but devices are absolutely strict on the matter.

Can you please confirm that there’s no case mismatches in your setup/code?

Brent

I never use capitals in any of my directory names. It doesn’t seem to be a case problem. But there’s also the problem of the script not being loaded when you start the project in sublime while the script is in focus. If i change the focus of the window on a different file like main.lua, it works just fine.

I have tried moving the files to the root directory and there are still not changes. I have tried changing the name of the files, manually required the files instead of dynamically. Nothing.

It won’t even work when I run the Simulator through the actual program instead of Sublime. It only works when I run the project in Sublime apparently.

Would it be possible for you to send me your project as it currently is, so I can inspect? Or is it proprietary material you need to keep private?

I don’t need to keep it private at all. I can share the google drive folder with you if you’d like. 

Yes please. Email is brent (at) coronalabs (dot) com. Thanks!

Please let me know if you’ve found anything. Email me or reply here so we can help others that have this problem as well. Thanks!

Hi @arjay.yabut07,

I think I found one main issue. In your “card.lua” module, I’m seeing two places where you call “io.open()”, but it looks like you’re trying to directly open a file via its string name. This won’t work… you need to define the actual path where that file exists, using the “system.pathForFile()” API.

You’ve done that elsewhere in your project, just not in “card.lua”, so basically your conditional check for if “script” or “scriptFile” exists fails, and nothing inside the block executes.

See here:

https://docs.coronalabs.com/api/library/io/open.html

Let me know how it goes from here,

Brent

Thank you so much. I seemed to have overlooked that. I appreciate the help!

Hi @arjay.yabut07,

My initial thought is that “id” is an invalid (nil) string (line 5 in the code block above). Shouldn’t it be something like “v.id” because it’s part of the “ipairs()” iteration just like “v.type”?

Best regards,

Brent

That was just a typo for when I was writing the code into the editor.

OK, in terms of file-related things that work in the Simulator but not on a device, that is usually (99%) a case mismatch issue, for example you write “data” (lowercase “d”) in your code but the project folder is “Data” (capital “D”). The Simulator is very forgiving on case matches folders/files, but devices are absolutely strict on the matter.

Can you please confirm that there’s no case mismatches in your setup/code?

Brent

I never use capitals in any of my directory names. It doesn’t seem to be a case problem. But there’s also the problem of the script not being loaded when you start the project in sublime while the script is in focus. If i change the focus of the window on a different file like main.lua, it works just fine.

I have tried moving the files to the root directory and there are still not changes. I have tried changing the name of the files, manually required the files instead of dynamically. Nothing.

It won’t even work when I run the Simulator through the actual program instead of Sublime. It only works when I run the project in Sublime apparently.

Would it be possible for you to send me your project as it currently is, so I can inspect? Or is it proprietary material you need to keep private?

I don’t need to keep it private at all. I can share the google drive folder with you if you’d like. 

Yes please. Email is brent (at) coronalabs (dot) com. Thanks!