Jim Howes
Jim Howes

Reputation: 61

Lua 'attempt to call a number value near for..in' error due to unrelated table index assignment -- why?

I'm writing some Lua scripts in Tabletop Simulator and seeing the error attempt to call a number value near for..in that has me completely perplexed. Here's the code snippet with the for loop that is causing the error:

function resetTurnOrder()
    local map = getObjectFromGUID(GUIDs.Map)
    local shift, center, points = map.getPosition(), map.getTable('MapData').center, map.getSnapPoints()
    local i, p = 0
    for nation, guids in pairs(GUIDs.Nations) do
        print('Resetting turn order for ' .. nation)
        if checkScenario(nation) then
            i = i + 1
            p = map.positionToLocal(shift - points[i].position)
            p[1] = p[1] * 0.75 + center[1] * 0.25
            p[3] = p[3] * 0.75 + center[3] * 0.25
            getObjectFromGUID(guids.turn_token).setPositionSmooth(map.positionToWorld(p), false, false)
            getObjectFromGUID(guids.turn_token).setRotationSmooth({0, points[i].rotation[2], 0}, false, false)
            print('Done resetting turn order for ' .. nation)
        else
            print(nation .. ' not in this scenario')
        end
    end
end

Okay, so first of all I will say that the error went away by commenting out the two lines that assign directly to p[1] and p[3], and when I replaced those lines with the equivalent statement

p = {p[1] * 0.75 + center[1] * 0.25, p[2], p[3] * 0.75 + center[3] * 0.25}

then everything worked perfectly. However, I am completely dumbfounded as to why this would fix the error. I use this exact for loop definition in like half a dozen places to iterate over the players and their components (which are stored in the global GUIDs) and it has worked flawlessly everywhere else.

To add a little more detail, even with the old code the first iteration of the loop works perfectly. The first turn token is moved to its proper position, both messages are printed, but the error prevents further iterations. The error is clearly occurring when incrementing the loop iterator, but I can't understand how assigning directly to p[1] and p[3] could possibly interfere with this but assigning to p is fine. One more detail: declaring p inside the for loop instead of outside beforehand didn't help.

(EDITED TO ADD MORE DETAILS)

After more testing it looks like @luther is probably correct that something weird is going on with the metatable for the value returned by positionToLocal. The value returned by this function is a Vector defined by Tabletop Simulator which I believe is an extension of Unity's Vector3 type. An important detail is that this type allows you to refer to the indices x,y,z and 1,2,3 interchangeably.

So, I replaced the p[1] and p[3] assignments with p.x and p.z which fixed the error. This seems to imply that the Vector returned by positionToLocal did not define indices 1,2,3 explicitly but instead uses a metamethod to link those indices to x,y,z. And, somehow, that metamethod is messing with the loop iterator... but honestly that still boggles my mind.

GUIDs.Nations is the table passed to the pairs() function which is used to generate the iterator and it is basically a constant--I never add to or update it in any function because it contains static GUIDs. It certainly has no connection to p.

FURTHER DETAILS

This definitely seems likely to be connected to Tabletop Simulator's Vector implementation: https://forums.tabletopsimulator.com/showthread.php?8344-For-loop

The above example just uses a simple numeric for loop to update indices 1,2,3 of a Vector value, and an assignment statement which uses i to index the Vector ends up changing the value of i to the same value that is assigned.

I'm still unable to understand how this is even possible in the language though...

Upvotes: 0

Views: 973

Answers (1)

Jim Howes
Jim Howes

Reputation: 61

Okay, I'm certain that this is a bug in Moonsharp, which is the Lua interpreter used by Tabletop Simulator: https://github.com/moonsharp-devs/moonsharp/issues/133

The bug was fixed in March 2016 (https://github.com/moonsharp-devs/moonsharp/commit/3ebc0e1fc706c452df9b309d51daec88a15eb0d1) but it seems like TTS probably hasn't updated Moonsharp.

Upvotes: 1

Related Questions