JSON error

I am using JSON files to store tile IDs which I use for rendering my game world.  I store my JSON files in a subfolder of my main project folder and I load the file with the function shown below. When I open my app in the simulator by double clicking main.lua directly from file explorer, it runs great, but when I open Corona Simulator and select my project from there or build my project and run it on my testing device, it gives me a null reference error when I attempt to use the data I loaded.

 

Here is the function to load a table from a JSON file:

function fileIO.loadJSONFile (fileName)  local path = fileName  local contents = ""  local loadingTable = {}  local file = io.open (path, "r")    if file then   local contents = file:read ("\*a")   loadingTable = json.decode (contents)   io.close (file)      return loadingTable  end    return nil end

Here is the usage (the way I render my tiles shouldn’t matter, so that part can pretty much be ignored.  I have marked the important lines in large letters :P):

function wr:renderChunkFile (path) &nbsp;local data = fileIO.loadJSONFile (path) --DATA IS LOADED HERE &nbsp;self:renderChunk (data) end function wr:renderChunk (data) &nbsp;local a, b = 1 &nbsp;if (self.img ~= nil) then &nbsp; a = #self.img + 1 &nbsp; self.img[a] = {} &nbsp;else &nbsp; self.img[1] = {} &nbsp;end &nbsp;if (self.chunks ~= nil) then &nbsp; b = #self.chunks + 1 &nbsp; self.chunks[b] = display.newGroup () &nbsp;else &nbsp; self.chunks[1] = display.newGroup () end for i = 1, #data do -- Y axis ERROR IS THROWN HERE &nbsp; self.img[a][i] = {} &nbsp; for j = 1, #data[i] do -- Z axis &nbsp; self.img[a][i][j] = {} &nbsp; for k = 1, #data[i][j] do -- X axis &nbsp; &nbsp;if (data[i + 1] ~= nil) then &nbsp; &nbsp; if (data[i + 1][j][k] \< self.transparentLimit) then &nbsp; &nbsp; &nbsp;self.img[a][i][j][k] = display.newImage ("images/tiles/"..data[i][j][k]..".png",&nbsp;k\*self.tileWidth, display.contentHeight -j\*self.tileDepth - i\*self.tileThickness) &nbsp; &nbsp; &nbsp;self.chunks[b]:insert (self.img[a][i][j][k]) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;elseif(data[i + 1] == nil) then &nbsp; &nbsp; &nbsp;self.img[a][i][j][k] = display.newImage ("images/tiles/"..data[i][j][k]..".png",&nbsp;k\*self.tileWidth, display.contentHeight -j\*self.tileDepth - i\*self.tileThickness) &nbsp; &nbsp; &nbsp;self.chunks[b]:insert (self.img[a][i][j][k]) &nbsp; &nbsp;end &nbsp; end &nbsp; &nbsp;end &nbsp; end &nbsp;end end

When it gets to the line “for i = 1, #data do” it tells me it is trying to access the length of a nil field. My initial thought was that maybe my file names are incorrect for the Android operating system, so I made all my folders completely alphabetical, but this had no effect.  I was also thinking that maybe APK files had a nesting limit on resource folders, so I brought all my resources to the root project folder and that still had no effect.  Where did I go wrong here?

Bump

are your assets named with all lowercase letters?

Yes, I have named all my assets with lowercase.  Is that a requirement for Android development?

It’s an operating system issue. See this thread for more info. Also, I just realized that wouldn’t matter at all, seeing as how you can’t even get to the rendering of the tiles.

Are you able to print out the contents of your json file before you even get to the rendering? It looks like your “data” variable is local to the wr:renderChunkFile, which is going to cause scoping problems, since any other part of your code won’t know what “data” is. I’d suggest making “data” global to the module (just for testing) and see if it works. If it does, you know your problem and can code around it.

I think maybe I didn’t do that great of a job of explaining the real issue I am having.  I am getting inconsistent results when running this project. When I select main.lua in file explorer and open it with Corona Simulator, it works. When I open Corona Simulator and open the project from inside the simulator, it does not work. When I build the project and test it on my device, it does not work. What I really need is some insight into Corona’s JSON library and APK internal directory structure requirements (directory nesting limits, naming restrictions, etc.).

Also, I just did some testing and where it actually goes wrong is in my JSON loading function.  In the first case (the one that works), the variable “file” does exist and the function DOES ENTER the if statement.  In the other two cases, file is nil at that point, so the function SKIPS the if statement and returns nil, which is why “data” is nil in the rendering function.

AHA!!!  I feel stupid!  When loading ANY FILE in your app you have to use the apps resource directory with system.ResourceDirectory!  I changed

local path = fileName

to

local path = system.pathForFile (fileName, system.ResourceDirectory)

and it works like a charm!

@Bam, it seems that I completely misunderstood your post, so I’m sorry about that.

Glad you got it sorted!

Bump

are your assets named with all lowercase letters?

Yes, I have named all my assets with lowercase.  Is that a requirement for Android development?

It’s an operating system issue. See this thread for more info. Also, I just realized that wouldn’t matter at all, seeing as how you can’t even get to the rendering of the tiles.

Are you able to print out the contents of your json file before you even get to the rendering? It looks like your “data” variable is local to the wr:renderChunkFile, which is going to cause scoping problems, since any other part of your code won’t know what “data” is. I’d suggest making “data” global to the module (just for testing) and see if it works. If it does, you know your problem and can code around it.

I think maybe I didn’t do that great of a job of explaining the real issue I am having.  I am getting inconsistent results when running this project. When I select main.lua in file explorer and open it with Corona Simulator, it works. When I open Corona Simulator and open the project from inside the simulator, it does not work. When I build the project and test it on my device, it does not work. What I really need is some insight into Corona’s JSON library and APK internal directory structure requirements (directory nesting limits, naming restrictions, etc.).

Also, I just did some testing and where it actually goes wrong is in my JSON loading function.  In the first case (the one that works), the variable “file” does exist and the function DOES ENTER the if statement.  In the other two cases, file is nil at that point, so the function SKIPS the if statement and returns nil, which is why “data” is nil in the rendering function.

AHA!!!  I feel stupid!  When loading ANY FILE in your app you have to use the apps resource directory with system.ResourceDirectory!  I changed

local path = fileName

to

local path = system.pathForFile (fileName, system.ResourceDirectory)

and it works like a charm!

@Bam, it seems that I completely misunderstood your post, so I’m sorry about that.

Glad you got it sorted!