AI Foundation Sequence vs AI Peasant Building Sequence

Discussion in 'Modding' started by Ftoomsh, Feb 19, 2018.

  1. Ftoomsh

    Ftoomsh Well-Known Member

    For those who have dabbled in AI:

    Have you noticed that if you order the AI to build more Town Centers up front (say six in millions) that the six town center foundations will be laid first but the peasants will still follow a different order of finishing foundations? That is to say the 6 TC foundations will be laid and then other foundations of the millions build will be laid but the peasants follow their own build order, to some considerable extent, not the foundations order? This is in progresseconomicai.inc when I just change line 2694 of the procedure _ai_BuildHouses from _ai_TryUnit(plind, cid, gc_ai_unit_center, 2, False); to _ai_TryUnit(plind, cid, gc_ai_unit_center, 6, False);


    Clearly, there is an AI foundation laying sequence and an AI peasant work detail sequence and these two are not the same . Where is the latter defined? They do eventually get around to building the extra TCs but not in the same order as the foundation laying.

    As always, I will keep looking for the answer but I am always happy if someone already knows the answer and saves me the search time.


    My First Guess

    Is it to do with procedure _ai_CallPeasantsToBuildProject?

    In particular is it to do with this set of lines, especially the bolded bits?

    if (reqpeasants>0) then
    [*] = ; begin
    [*] = ; var mmask : Integer = (1 shl gc_obj_material_body);
    [*] = ; var dist : Float = VectorDistance(GetGameObjectPositionXByHandle(trgHnd), 0, GetGameObjectPositionZByHandle(trgHnd), gPlayer[plind].aidata.centerx, 0, gPlayer[plind].aidata.centerz);
    [*] = ; if dist > 30 then
    [*] = ; _ai_MakeListObjectsInRadiusByUsageBySpiral(plind, gc_obj_usage_peasant, reqpeasants, gPlayer[plind].aidata.centerx, gPlayer[plind].aidata.centerz, 50, bAllowFood, false, 1 shl gc_obj_material_body, gPlayer[plind].aidata.ailist, false)
    [*] = ; else
    [*] = ; _ai_MakeListObjectsInRadiusByUsageBySpiral(plind, gc_obj_usage_peasant, reqpeasants, GetGameObjectPositionXByHandle(trgHnd), GetGameObjectPositionZByHandle(trgHnd), 50, bAllowFood, false, 1 shl gc_obj_material_body, gPlayer[plind].aidata.ailist, false);
    [*] = ; end;


    I assume the procedure _ai_BuildHouses is ordering my 6 Town Centers projects and then progressing down and doing the other orders it can afford in a first pass of procedure _ai_BuildHouses. Then it does a pass of procedure _ai_CallPeasantsToBuildProject and builds the projects by useage (however it determines that) by spiral outward from peasants' start location? This would make sense as it (at least partially) obeys shortest path logic.


    Another Issue

    I've decided, if I am going to re-work the AI, then I should be thorough and start with the economic AI. To re-work the AI build orders, I have to re-work procedure _ai_BuildHouses (which actually builds all structures) in progresseconomicai.inc. Of course, I would have to re-work other routines like procedure _ai_DoTrade because the results of trades feed into what builds are possible.

    As first step I wanted to make a new stub of _ai_BuildHouses but my first attempts to cut it down to a working stub (so I can rebuild it from the ground up) were hampered by errors I didn't understand. They were shown in the log like ERROR| 22 |Compile script error: ProgressEconomicAI.

    This error did not crash the program. When I ran the Game editor I could compile the scripts and it compiles successfully. No surprise as there was no crash. However, the error is real because the AI builds nothing when this error happens. How can I trace such errors in general?

    In this case I found it because I discovered you can't use curly brackets to comment out sections in a file like progresseconomicai.inc. Why is this?

    I have to use // after every line start of [*] = ; // as in comment out like this

    Why do lines start this way in such files? I guess as include files they are executable in loops as the game loop runs. Unlike script file which are included at load and not run again although their procedures can be called? Am I on the right track?
     
    Last edited: Feb 19, 2018