[Resolved] Tables / Sub Tables Enemy Data - HELP - Cant figure out whats wrong

Ok here is the issue I have tried to create a sub table for EnemyData[i].x but I get an error

Runtime error: …g\corona-mobile\beta - projects\test-tables\main.lua:51: attempt to index field ‘?’ (a nil value)

main.lua:51: in function ‘EnemyData’

local EnemyData = {Monster, Orc, Bird};  
  
-------------------------------------------------  
--Loop Thru and create sub-tables for EnemyData  
-------------------------------------------------  
for i = 1, #EnemyData do  
 EnemyData[i] = {};  
 EnemyData[i].x = {}; --Table for Random Start Positions  
 EnemyData[i].y = {}; --Table for Random Start Positions  
end  
  
function LoadEnemyData(Enemy, xx, yy)  
  
 EnemyData[Enemy].x = xx; ---- \<\< This is where I get the error  
 EnemyData[Enemy].y = yy;  
  
 --------------Load other data--------------  
  
end  
  
LoadInstrumentData("Monster", {150,280,420,550,690}, {205,275,340,415,490,560} )  
LoadInstrumentData("Orc", {150,280,420,550,690}, {205,275,340,415,490,560} )  
LoadInstrumentData("Bird", {150,280,420,550,690}, {205,275,340,415,490,560} )  

I have also tried to do a split and return a table like this.

[code]
function split(pString, pPattern)
local Table = {} – NOTE: use {n = 0} in Lua-5.0
local fpat = “(.-)” … pPattern
local last_end = 1
local s, e, cap = pString:find(fpat, 1)
while s do
if s ~= 1 or cap ~= “” then
table.insert(Table,cap)
end
last_end = e+1
s, e, cap = pString:find(fpat, last_end)
end
if last_end <= #pString then
cap = pString:sub(last_end)
table.insert(Table, cap)
end

return Table
end

function LoadEnemyData(Enemy, xx, yy)
EnemyData[Enemy].x = split(xx, “,”); ---- << This is where I get the error
EnemyData[Enemy].y = split(yy, “,”);
--------------Load other data--------------
end

LoadInstrumentData(“Bird”, “150,280,420,550,690”, “205,275,340,415,490,560” )
[/code] [import]uid: 11860 topic_id: 28141 reply_id: 328141[/import]

Hi there,

In the first example (I’m only looking at that one), you can’t just declare:

local EnemyData = {Monster, Orc, Bird};

This basically assumes that “Monster” (and “Orc” and “Bird”) are variables that have previously been declared. It’s not creating a “label” (name reference) that you can refer to later. Since you probably haven’t declared “Monster” or the others before this, that value is nil, and thus it doesn’t add anything to that table.

Try this:

local EnemyData = {Monster, Orc, Bird};  
print(#EnemyData)  

Notice that the count is 0… basically the table is empty, because you have tried to add “nil” values to it (Monster, Orc, Bird were never declared, they are nil, thus they are not added). So, when you attempt to access them (and add things to them) in the function, it does not succeed.

If you want to create explicit “labels” for these items, contained within the table “EnemyData”, you will need to write it like this:

local EnemyData = { Monster={}, Orc={}, Bird={} };

Then you must loop through by pairs, not my simple count, and manipulate them as you see fit.

Hope this helps!
Brent

[import]uid: 9747 topic_id: 28141 reply_id: 113708[/import]

Did you ever know that your my hero :slight_smile:

I almost tried that, really, But I thought naa that cant be it…

It’s the simple things that have been tripping me up.

thanks so much.

Larry

DoubleSlashDesign.com
[import]uid: 11860 topic_id: 28141 reply_id: 113746[/import]

Great to hear it’s working now! (or will be soon). Often the simple things in Lua (or any language) are the ones most overlooked or just assumed to be correct, then it compounds into everything else.

Let me know if this new method turns up any more questions, and I can probably help with those.

Brent
[import]uid: 9747 topic_id: 28141 reply_id: 113748[/import]

Ok here is another question.
I am using the following code, and it all works fine to pass in the EnemyType ( dictionary string )

In stead of hard coding the number of enemy’s I would like to be able to use either to get the total enemy count so I can use it randomly.

#EnemyData or #_G.EnemyType

They both seem to return 0 I guess because they are being used like a dictionary instead of a table or something. Is there a better way to get the number of items beside the # ?

\_G.EnemyType = {Monster="Monster", Orc="Orc", Bird="Bird"};  
local EnemyData = { Monster={}, Orc={}, Bird={} };  
  
function spanEnemy(EnemyType )  
 EnemyData[EnemyType].x .....ETC some other code   
end  

Thanks in advance :slight_smile:
Larry

[Resolved] I decided to just loop through a ForEach style loop and count the number of items.
Since this is only done once to set the size it’s small fast and works like a champ :slight_smile:

[code]
local numItems = 0
for k,v in pairs(_G.EnemyType) do
numItems = numItems + 1
end
_G.EnemyType.count = numItems

numItems = 0
for k,v in pairs(EnemyData) do
numItems = numItems + 1
end
EnemyData.count = numItems

[/code] [import]uid: 11860 topic_id: 28141 reply_id: 114330[/import]

Why not just make one function parameter to pass in a table rather than make the table global?

local EnemyType = {Monster="Monster", Orc="Orc", Bird="Bird"};  
local EnemyData = { Monster={}, Orc={}, Bird={} };  
   
function spanEnemy(EType, EData )  
 EData[EType].x .....ETC some other code   
end  
  
--call it  
spanEnemy(EnemyType, EnemyData) -- you can pass in any two tables from a local scope then  

As getting the amount of items in the table part, your idea is conceptually ok, but you can make your life easier:

How about this (working code), create a function to count the number of items in a key/pair table.

[code]
local test = {
[“1”] = {x = 100},
[“2”] = {x = 100},
[“3”] = {x = 100},
}

local function countPairs( tTable )
local count = 0

for k, v in pairs( tTable ) do
count = count + 1;
end

return count
end

local noOfTest = countPairs( test )
print(“No of items in table:”, noOfTest)
[/code] [import]uid: 84637 topic_id: 28141 reply_id: 114492[/import]

Thanks for the idea, I’ll look at that as well.

Larry [import]uid: 11860 topic_id: 28141 reply_id: 114497[/import]