Lua error: cannot find ai.move_full (but finds & calls other func in 'ai')

Discussion of Lua and LuaWML support, development, and ideas.

Moderators: Forum Moderators, Developers

Post Reply
denispir
Posts: 80
Joined: March 14th, 2013, 12:26 am

Lua error: cannot find ai.move_full (but finds & calls other func in 'ai')

Post by denispir » January 22nd, 2019, 10:00 am

Hello,

I just had a Lua error, think (and hope) it may be a stupid bug by me, but who know?
"attempt to call a nil value (field 'move_full')" in ai_helper.lua at line 218 (if/else block below). This is in function 'checked_move_core':

Code: Select all

function ai_helper.checked_move_core(ai, unit, x, y, move_type)
    local check = ai.check_move(unit, x, y)

    if (not check.ok) then
        if (not ai_helper.is_incomplete_or_empty_move(check)) then
            ai.stopunit_moves(unit)
            ai_helper.checked_action_error(move_type .. ' from ' .. unit.x .. ',' .. unit.y .. ' to ' .. x .. ',' .. y, check.status .. ' (' .. check.result .. ')')
            return check
        end
    end

    if (move_type == 'ai.move_full') then
        return ai.move_full(unit, x, y)         -- *** line 218 ***
    else
        return ai.move(unit, x, y)
    end
end
'checked_move_core' is itself called by 'checked_move_full' which full code is:

Code: Select all

function ai_helper.checked_move_full(ai, unit, x, y)
    return ai_helper.checked_move_core(ai, unit, x, y, 'ai.move_full')
end
Fortunately, I have not made many changes before running a test. Among them, for consistency with other "import" names like AH, I set in my CA code at module top level:

Code: Select all

local W = wesnoth
local AI = ai
I guessed this should be a factor of the error, especially because I had read a few days ago that 'ai' is "now available as a "scoped global variable" anywhere in AI code" at wiki page https://wiki.wesnoth.org/Creating_Custom_AIs. Would someone explain what this actually means? (I searched the Lua ref because my knowledge of Lua is old, but found nothing, so this may be proper to Wesnoth Lua.)

Anyway, removing these lines alone did not help. I mention that just in case they still may be a 'cofactor' of the error (and to have an explanation as asked above).

In the function 'checked_move_core' (code above), a call to 'ai.check_move' is done in any case, so we can be sure that Lua properly finds 'ai' and its available, callable fields. Also, noting the if/else branching (end of func), I modified my own code to provoke a call to 'ai.move' instead of 'ai.move_full' (by calling AH.checked_move).
This provokes (as half expected) the same error except for a change to "field 'move'" and to line 220...

I am blocked because I cannot find the table (pseudo module) 'ai'. Thus, in addition to help about the bug, I take the opportunity to ask for the code defining 'ai' and also 'wesnoth'. (Present breve descriptions are not enough, especially around path finding; for other modules like AH I did have to read the code to actually understand purpose and usage).

Right time for a pause and doing something move moving ;) !
thank you, diniz

mattsc
Posts: 1105
Joined: October 13th, 2010, 6:14 pm
Location: Wandering, mostly aimlessly

Re: Lua error: cannot find ai.move_full (but finds & calls other func in 'ai')

Post by mattsc » January 24th, 2019, 5:22 pm

Hey,

The information you provide isn't really enough to say what is going on. As you suspect yourself, the problem is almost certainly in the code that makes the 'ai' table available, but I don't remember ever experiencing a case where 'ai.check_move()' is available and 'ai.move()' is not, so I have no idea what might be happening. If you post your entire code, I could do some checking.
denispir wrote:
January 22nd, 2019, 10:00 am
I guessed this should be a factor of the error, especially because I had read a few days ago that 'ai' is "now available as a "scoped global variable" anywhere in AI code" at wiki page https://wiki.wesnoth.org/Creating_Custom_AIs. Would someone explain what this actually means?
I actually don't know what the "scoped" means either (I did not write this), only the consequence that it is not necessary (and in fact does not work) any more if you pass the 'ai' table as an argument to a candidate action eval/exec function.
denispir wrote:
January 22nd, 2019, 10:00 am
I am blocked because I cannot find the table (pseudo module) 'ai'. Thus, in addition to help about the bug, I take the opportunity to ask for the code defining 'ai' and also 'wesnoth'.
The AI Lua functions are defined in 'src/ai/lua/core.cpp' and the 'wesnoth' table in 'src/scripting/game_lua_kernel.cpp' (or similar functions in the same directories). I don't actually always remember this off the top of my head, so I 'grep' for, for example, 'check_move_full' in the 'src/' directory.

Also, FYI, I find the 'dbms()' function of the Wesnoth Lua Pack extremely useful when working with Wesnoth Lua in order to see the structure of a table (although that does not always work with the 'ai' table, if I remember correctly, as its functions are hidden, at least in some cases). I'm not sure if the WLP is still maintained, but it should still be available on the add-ons server. Alternatively, there's a slightly modified local version in the AI-demos add-on.

Hope this helps.

denispir
Posts: 80
Joined: March 14th, 2013, 12:26 am

Re: Lua error: cannot find ai.move_full (but finds & calls other func in 'ai')

Post by denispir » January 25th, 2019, 7:49 pm

Hello @mattsc,

Thank you for your reply. In the meantime I have passed to something else to explore; and right now cannot give much time to this issue. Anyway, I am learning how to do micro AIs, albeit still at a very early stage with a single & simple CA added to the mainloop. I took inspiration from your CA_move_type in AI_Demos. I ended up rewriting it from scratch and found some interesting side problems which led to that "something else to explore" (another way to find next stop on the path toward a dest). The bug comes up when using this rewritten version.

Apart from what I'm telling above, I did not make any other change (between the time when it worked and the bug) than creating 3 free data fields in the CA table itself (to keep lists of controlled units, ones not moved yet, and their number), and setting them from either the eval or the exec funcs.

I now guess that the "scoped global variable" may just mean that now CA files run into a redefined _ENV table into which 'ai' is injected: 'ai' would thus be a module-level var as through an import. I now now that 'ai' is defined in C, thank you, which I suspected. I will have a look at the C code whenever I can, hoping that the '++' functionalities are not too heavily used (but since Lua is supposed to be 100% standard C I can hope ;)).

Tell you more when I have some free time to dedicate to this issue (and other fun problems).
diniz

PS: Why isn't there an AI forum (and also a map forum).

User avatar
Celtic_Minstrel
Developer
Posts: 1463
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Lua error: cannot find ai.move_full (but finds & calls other func in 'ai')

Post by Celtic_Minstrel » February 19th, 2019, 4:09 am

I'm guessing you're running into the fact that the gamestate-changing functions are removed from the ai table while running a candidate action evaluation function, as those functions are not supposed to change the gamestate. If you absolutely need to change the gamestate anyway during the evaluation phase, you can execute ai.read_only = false (possibly without the underscore, I can't quite remember) and then those functions will become available, but I recommend instead moving your code to the candidate action execution function. This might involve changing the WML that defines your AI.

The meaning of "scoped global variable" is just that if for some reason you create a global variable named ai in non-AI code, it won't be overwritten by the ai module (though it will be inaccessible from AI code). To put it another way: when running the AI code, the engine does something like this (pseudo-code):

Code: Select all

local save_ai = ai
ai = wesnoth.debug_ai(wesnoth.current.side).ai
local result = your_ai_function()
ai = save_ai
return result
Author of The Black Cross of Aleron campaign and Default++ era.
Maintainer of Steelhive.

Post Reply