Lua table gotcha
I recently was introduced to a bug in my game. I had 20 AI units and only 19 of them were actively doing something. Number 20 was just standing there. The problem eventually lied in using '#enemies' to get the amount of enemies.
Here is what happened:
A lua table index by default starts on index 1. This in contrary to many other languages where it starts at 0. However, you can assign a value to index '0' if you want. Since I use C# on a daily basis, I am more comfortable using the 0 index as a start. As a result this is my (simplified) code:
for i = 0, enemyCount-1, do
enemies[i] = new Enemy()
end
In the AI script I loop over the enemies like this:
for i = 0, #enemies-1, do
enemies[i]:DoStuff()
end
This is really basic lua scripting with one tiny gotcha: The '#' is used to get the amount of consecutive keyed items in the list. This I knew. What I did not know, is that there is also the requirement that this order starts at index 1 (or at least not on index 0). It simply ignores the 0 index!
Here is a full script to try
local enemies = {}
local enemyCount = 4
for i = 0, enemyCount-1, 1 do
enemies[i] = "I am enemy " .. i
System:Print(enemies[i])
end
System:Print("#enemiesCount: " .. #enemies)
for i = 0, #enemies-1 do
System:Print(enemies[i])
end
Output:
I am enemy 0
I am enemy 1
I am enemy 2
I am enemy 3
#enemiesCount: 3
I am enemy 0
I am enemy 1
I am enemy 2
Problem
So what was happening? I did get the amount of enemies back, except for the one enemy that was located on index 0. I quickly noticed the lower count of enemies, but since enemy number 20 wasn't doing anything I was also looking in the wrong place. It was actually enemy number 1 that was the culprit, even though it's AI was being executed.
Solution
It can be solved in numerous simple ways, but I guess best practice is to just stick to Lua's standard and not assign anything to 0. This can really prevent some time being wasted on absolutely silly issues like this.
- 1
- 1
8 Comments
Recommended Comments