Confusing table behavior

I am running into something that is confusing the heck out of me, so I am turning to all of you for a hopeful answer.

I have a data file I am loading in my composer framed scene.  It contains a table of info.

i load it in and then set another variable equal to it.  

local buildingData = require("buildings") local floorEnemiesTotal = {} floorEnemiesTotal = buildingData["building1"].enemies

Over the course of the game, enemies (which is itself a table with sub values) will decrease as the player kills enemies.

The confusing thing is that, when I reload the scene, I check to see the value of the relevant info in buildingData after loading it and it looks like that is decreasing as well, even though I never touch it after loading it in the game.

Does this make sense and, if so, does anyone have an idea as to what I am doing wrong here?

Any help if greatly appreciated.

Alan, did you ever get this sorted? I keep trying to visualize what you’re doing but I’m wondering what kind of data is being maintained in the “enemies” table? Is it coordinates and other static variables, or is it hit/exp points and so on? I’d also be curious what is taking place in the buildingData code as well, but maybe that’s irrelevant to this issue.

I did not get this sorted but found a different way to do this.

I can give an example of what I am/was doing.  I set up a separate file called buildingData.lua.  In it was code along the lines of the following:

buildingData = { building1 = { type1 = 3, type2 = 5, type3 = 2 }, building2 = { type1 = 3, type2 = 5, type3 = 2 }, building3 = { type1 = 3, type2 = 5, type3 = 2 }, } return buildingData

I then set a variable in my game equal to this as follows:

 

local buildingData = require("buildingData") local floorEnemiesTotal = {} floorEnemiesTotal = buildingData["building1"]

So far, everything works as expected.  I do this so that the original data is maintained and I can alter the values of each of the types as needed.  The problem is that when I alter a value in floorEnemiesTotal, the corresponding value in buildingData seems to be getting altered as well.

I worked around this using a utility.loadTable function.  I just don’t understand this behavior.  It seems counter-intuitive.

Yea, that does seem strange. I come back to this thread every couple of days and try to ponder, but I haven’t closed on anything substantial. I wonder if this is a feature and not a bug.

just a hunch, but require() does NOT “reload” code once previously loaded - suspect that’s the source of your problem.

if your “buildings.lua” functions as a “level definition” file, then you probably shouldn’t alter its values directly - assuming you might eventually want to get back to the original values next time this level is played.  instead, make a clone of the definition to operate on during each game play.

(or load your data from json, so you KNOW the resuling lua table couldn’t possibly be altering the original “source data”)

So, the require thing makes sense.  But, I was not altering the values directly.  Rather, I was assigning the values it contained to a different variable and then altering that.  Which is why I am confused as to why the values are being altered when I am only changing them in the second variable.

Regardless, I did wind up using json in the end which solved the whole problem, but I do still find this behavior puzzling.

has to do with how lua handles table references…  your “different variable” is just a new *reference* to the original table

floorEnemiesTotal = buildingData[“building1”]

the right-hand side of that statement evaluates to a table, and such a statement doesn’t create an entirely new copy of the table, just a new name for a “pointer” to the same table.  (also known as “aliasing” - a very useful technique, but can have this unexpected behavior if unfamiliar with it)  so modifying via floorEnemiesTotal will still affect original table buildingData[“building1”]

(you could google for lua code to do shallow or deep clone if ever needed, but json is often just as good / better-simpler / etc)

Thanks for the heads up on this.  That would explain it. 

Alan, did you ever get this sorted? I keep trying to visualize what you’re doing but I’m wondering what kind of data is being maintained in the “enemies” table? Is it coordinates and other static variables, or is it hit/exp points and so on? I’d also be curious what is taking place in the buildingData code as well, but maybe that’s irrelevant to this issue.

I did not get this sorted but found a different way to do this.

I can give an example of what I am/was doing.  I set up a separate file called buildingData.lua.  In it was code along the lines of the following:

buildingData = { building1 = { type1 = 3, type2 = 5, type3 = 2 }, building2 = { type1 = 3, type2 = 5, type3 = 2 }, building3 = { type1 = 3, type2 = 5, type3 = 2 }, } return buildingData

I then set a variable in my game equal to this as follows:

 

local buildingData = require("buildingData") local floorEnemiesTotal = {} floorEnemiesTotal = buildingData["building1"]

So far, everything works as expected.  I do this so that the original data is maintained and I can alter the values of each of the types as needed.  The problem is that when I alter a value in floorEnemiesTotal, the corresponding value in buildingData seems to be getting altered as well.

I worked around this using a utility.loadTable function.  I just don’t understand this behavior.  It seems counter-intuitive.

Yea, that does seem strange. I come back to this thread every couple of days and try to ponder, but I haven’t closed on anything substantial. I wonder if this is a feature and not a bug.

just a hunch, but require() does NOT “reload” code once previously loaded - suspect that’s the source of your problem.

if your “buildings.lua” functions as a “level definition” file, then you probably shouldn’t alter its values directly - assuming you might eventually want to get back to the original values next time this level is played.  instead, make a clone of the definition to operate on during each game play.

(or load your data from json, so you KNOW the resuling lua table couldn’t possibly be altering the original “source data”)

So, the require thing makes sense.  But, I was not altering the values directly.  Rather, I was assigning the values it contained to a different variable and then altering that.  Which is why I am confused as to why the values are being altered when I am only changing them in the second variable.

Regardless, I did wind up using json in the end which solved the whole problem, but I do still find this behavior puzzling.

has to do with how lua handles table references…  your “different variable” is just a new *reference* to the original table

floorEnemiesTotal = buildingData[“building1”]

the right-hand side of that statement evaluates to a table, and such a statement doesn’t create an entirely new copy of the table, just a new name for a “pointer” to the same table.  (also known as “aliasing” - a very useful technique, but can have this unexpected behavior if unfamiliar with it)  so modifying via floorEnemiesTotal will still affect original table buildingData[“building1”]

(you could google for lua code to do shallow or deep clone if ever needed, but json is often just as good / better-simpler / etc)

Thanks for the heads up on this.  That would explain it.