[TOTPP] Prof. Garfield's Lua Code Thread

No questions on this one, thanks Prof.! It all went through just fine. Did not realize about generating scripts! Using these object designations will be much easier generally. This is a nifty feature. And I quite like all of the ways I can customize the leaders.

For this mod, I'll likely stick to pretty simple trait classifications (offensive, defensive), only because I want the AI to use their leaders at least somewhat effectively. I feel if I made a leader for, say, cavalry, the AI wouldn't understand this trait as much as they do the built-in ones.
 
All right, my project for today is fine-tuning, and I was wondering if I could get some assistance.

The code below is for generating a "Village" unit on the tile, which we worked on before. All works well. But I'd like to have three additions:

- I'd like the code to cycle between 3 different types of Village units (Village1, 2, 3) at random intervals (just picking one when it is time to place the unit). I'm guessing I need to use a threshold table, but when attempted, I couldn't get it to load properly.
- I'd like the code to not place a unit on that tile if one is already there.
- I'd like the code to randomly change terrain adjacent to this goodie hut terrain to another terrain type.

Here is what I did -- I tried a few iterations. This one has a syntax error, but some of my other attempts loaded no errors -- the event just didn't happen. I think I'm not properly identifying the function?

Spoiler :
Code:
local postUrbanTerrain = civ.getBaseTerrain(0,11)
local goodieHutUrbanChance = 0.8
local postGoodieHutTerrain = civ.getBaseTerrain(0,12)
local goodieHutVillageChance = 0.02
discreteEvents.onTurn(function(turn)
    local state = gen.getState()
    if not state.hutTable then
        state.hutTable = {}
        for tile in civlua.iterateTiles() do
            if tile.hasGoodieHut then
                state.hutTable[gen.getTileID(tile)] = true
            end
        end
    end
    for tileID,_ in pairs(state.hutTable) do
        local tile = gen.getTileFromID(tileID)
        if not tile.hasGoodieHut and tile.baseTerrain == postGoodieHutTerrain then
            if math.random() < goodieHutVillageChance then
                civ.createUnit(unitAliases.VillageMili,civ.getTribe(0),tile) or civ.createUnit(unitAliases.VillageInfra,civ.getTribe(0),tile) or civ.createUnit(unitAliases.VillageEcon,civ.getTribe(0),tile)
            end
                for _,adjacentTile in pairs(gen.getAdjacentTiles(tile)) do
                if math.random() < goodieHutUrbanChance then
                tile.baseTerrain == postUrbanTerrain
                end
                end
            end
        end
    end
end)
discreteEvents.onEnterTile(function (unit, previousTile, previousDomainSpec)
    local state = gen.getState()
    if not state.hutTable then
        state.hutTable = {}
        for tile in civlua.iterateTiles() do
            if tile.hasGoodieHut then
                state.hutTable[gen.getTileID(tile)] = true
            end
        end
    end
    if state.hutTable[gen.getTileID(unit.location)] then
        if unit.location.baseTerrain ~= postGoodieHutTerrain then
            unit.location.baseTerrain = postGoodieHutTerrain
        end
    end
end)
discreteEvents.onCanFoundCity(function (unit, advancedTribe)
    local state = gen.getState()
    if not state.hutTable then
        state.hutTable = {}
        for tile in civlua.iterateTiles() do
            if tile.hasGoodieHut then
                state.hutTable[gen.getTileID(tile)] = true
            end
        end
    end
    if state.hutTable[gen.getTileID(unit.location)] then
        return false
    end
    return true
end)
discreteEvents.onScenarioLoaded(function ()
    local state = gen.getState()
    if not state.hutTable then
        state.hutTable = {}
        for tile in civlua.iterateTiles() do
            if tile.hasGoodieHut then
                state.hutTable[gen.getTileID(tile)] = true
            end
        end
    end
end)
 
civ.createUnit(unitAliases.VillageMili,civ.getTribe(0),tile) or civ.createUnit(unitAliases.VillageInfra,civ.getTribe(0),tile) or civ.createUnit(unitAliases.VillageEcon,civ.getTribe(0),tile)
You can't use "or" like this.
Code:
a or b
is similar to
Code:
function(a,b)
    if a then
        return a
    else
        return b
end
If a is "truthy", which in Lua means anything other than false or nil, a is returned. Otherwise, b is returned. (In other programming languages, stuff like 0 and "" are falsy, but in Lua they are truthy.) The main difference is that if a is evaluated as truthy, b won't be touched/evaluated at all.

The line will attempt to create the unit specified by
Code:
[QUOTE]
civ.createUnit(unitAliases.VillageMili,civ.getTribe(0),tile)
[/QUOTE]
If it succeeds, the unitObject returned by civ.createUnit is truthy, so the program goes to the next line.

If for some reason civ.createUnit fails to create the unit (I don't know if that's even possible, which is one reason to use gen.createUnit), the falsy nil will be returned, so Lua moves on to try
Code:
[QUOTE]
civ.createUnit(unitAliases.VillageInfra,civ.getTribe(0),tile)
[/QUOTE]
and, failing that, moves to
Code:
[QUOTE]
civ.createUnit(unitAliases.VillageEcon,civ.getTribe(0),tile)
[/QUOTE]

To do what you want, define this threshold table (outside the function):
Code:
local villageTypeThresholdTable = gen.makeThresholdTable({
    [0.66] = unitAliases.VillageEcon, -- 34%
    [0.33] = unitAliases.VillageInfra, -- 33%
    [0] = unitAliases.VillageMili, -- 33%
})
and replace the createUnit line with this:
Code:
local villageType = villageTypeThresholdTable[math.random()]
civ.createUnit(villageType,civ.getTribe(0),tile)
tile.baseTerrain == postUrbanTerrain
This should be
Code:
tile.baseTerrain = postUrbanTerrain
The == will cause an error if the result isn't being "used" (like assigned to a variable or checked in an if statement).
 
Aha! I see what I did wrong. And developing a better understanding of threshold tables, too. Thanks Prof.

For my code, I changed it to:
Code:
adjacentTile.baseTerrain = postUrbanTribeTerrain

This works, however, when it fires, it places those terrains in every adjacent tile.

How might I go about making a threshold table that only changes a random tile in any direction of that middle tile, but not all directions? And this can happen more than once. Can I tell the system to "choose" 1 adjacent tile, instead of all?

EDIT: I stand corrected! It does seem to be adding 1 tile at a time, actually.
 
Last edited:
This works, however, when it fires, it places those terrains in every adjacent tile.

How might I go about making a threshold table that only changes a random tile in any direction of that middle tile, but not all directions? And this can happen more than once. Can I tell the system to "choose" 1 adjacent tile, instead of all?

EDIT: I stand corrected! It does seem to be adding 1 tile at a time, actually.
Based on the rest of your code, each tile should have an 80% chance to be converted. You could try something along these lines:
Code:
local adjacentTiles = gen.getAdjacentTiles(tile)
for key,neighbourTile in pairs(adjacentTiles) do
    if neighbourTile.baseTerrain.type == 10 then
        adjacentTiles[key] = nil
    end
end
gen.makeArrayOneToN(adjacentTiles) -- clear all "gaps" in array, so next line will work
local chosenTile = adjacentTiles[math.random(#adjacentTiles)]
-- if all tiles are removed chosenTile will be nil, so we can't change it.
if chosenTile then
    chosenTile.baseTerrain = postUrbanTribeTerrain
end
 
Hi Prof.! Thanks for all your help this weekend.
I had a fun afternoon of coding and got some cool things done. Unfortunately, I got on a roll (and a bit cocky ;)), and wrote a lot of code without checking each aspect as I normally do.

After fixing some typos with the console's help, here is the strange error message I'm getting now:

Code:
Global variables are disabled
...op\ToT With Lua\Original\LuaCore\changeRules.lua:243: bad argument #1 to 'gsub' (string expected, got nil)
stack traceback:
    [C]: in function 'string.gsub'
    ...op\ToT With Lua\Original\LuaCore\changeRules.lua:243: in local 'convertFn'
    ...op\ToT With Lua\Original\LuaCore\changeRules.lua:546: in upvalue 'applyRuleRow'
    ...op\ToT With Lua\Original\LuaCore\changeRules.lua:819: in local 'newItemFn'
    ...op\ToT With Lua\Original\LuaCore\changeRules.lua:1149: in local 'createAuthoritativeDefaultRulesSubtable'
    ...op\ToT With Lua\Original\LuaCore\changeRules.lua:1332: in main chunk
    [C]: in function 'require'
    ... With Lua\Original\MechanicsFiles\calculateCityYield.lua:17: in main chunk
    [C]: in function 'require'
    ...strator\Desktop\ToT With Lua\Original\events.lua:192: in main chunk

Any ideas what this stuff means? I looked at those files and lines but couldn't figure it out. I haven't edited or adjusted those files, to be clear.
 
Any ideas what this stuff means? I looked at those files and lines but couldn't figure it out. I haven't edited or adjusted those files, to be clear.
Looks like there's something wrong with rules.txt, when reading the \@UNITS section of the rules, at least based on the lines in my copy of changeRules.lua. If our lines are off by a small amount, it could also relate to \@UNITS_ADVANCED or \@ATTACKS. The problem is probably that a line is missing for a unit type that the game thinks exists.

Evidently I'm going to have to put in some useful error messages. I have a bit of an unfortunate habit of assuming that the non-lua aspects of scenario building are perfect. It has been a source of errors for the legacy event engine as well.
 
Ah, yes! I updated my rules.txt, added some units and terrain types, and did not update setTraits or object. Updated, and now getting other errors, like this:

Code:
local treasureTypeThresholdTable = gen.makeThresholdTable({
    doWhenUnitKilled(loser,winner)
    [0.75] = winner.owner.money = math.max(winner.owner.money +100),
    [0.50] = winner.owner.money = math.max(winner.owner.money +500),
    [0.25] = winner.owner.money = math.max(winner.owner.money +1000),
    [0] = winner.owner.money = math.max(winner.owner.money +3000),
})

It keeps asking me to close the }, but I'm sure I'm doing something else wrong here. Any thoughts on this?

About putting in error messages: I think where I fumbled is that, once I added new units, the ctrl+shift+f4 wasn't bringing up an option to create new object.lua or setTraits.lua files. But also, I think a good rule of thumb is probably "finish the rules.txt, then add the lua." But I know that's not always possible, as in my case! Anyway, this is all a learning experience and a very rewarding one.
 
It keeps asking me to close the }, but I'm sure I'm doing something else wrong here. Any thoughts on this?
You have a doWhenUnitKilled line in the middle of a table constructor (the table is immediately used to make a threshold table). Inside a table constructor pair of curly brackets, you should only be assigning values to keys. You're allowed to run functions to get those values (or even to assign a function as the value), but you can't just randomly execute a function.
 
Evidently I'm going to have to put in some useful error messages. I have a bit of an unfortunate habit of assuming that the non-lua aspects of scenario building are perfect. It has been a source of errors for the legacy event engine as well.
Here's a changeRules.lua file (for LuaCore) that actually tells you that it has had trouble reading a section of the rules, what section that is, and where the error has been detected (though that is not necessarily where the error is, particularly if a line was deleted). Keep the original changeRules.lua file just in case. (This new file will be included in the next template release.)
 

Attachments

Thanks Prof.! Here is what I got:

Code:
Global variables are disabled
Enter console.commands() to see a list of keys in the console table.  Some give access to functions in modules, others will run event code.
...strator\Desktop\ToT With Lua\Original\events.lua:733: bad argument #1 to 'getUnit' (number expected, got no value)
stack traceback:
    [C]: in function 'civ.getUnit'
    ...strator\Desktop\ToT With Lua\Original\events.lua:733: in function <...strator\Desktop\ToT With Lua\Original\events.lua:732>

error: bad return value #1 from 'OnGetFormattedDate' (string expected, got no value)

Interestingly, this does not happen when I load the game, but when I press 'v' to look around the map, etc.
 
Line 733 of the events.lua file you sent me before has nothing to do with civ.getUnit, so I'm going to need your events.lua file again.

Based on the error, you've been changing the onGetFormattedDate event. There's a file for doing that, MechanicsFiles\onGetFormattedDate.lua. Basically, somewhere you call civ.getUnit on something that isn't a number, which causes an error. That error means that onGetFormattedDate doesn't work, so it doesn't get a string return value, and creates a second error.

Please don't make changes directly to the events.lua file. The scenario designer is supposed to be able to do anything that is supported in another file, and events.lua is used to keep everything together (and construct certain kinds of events out of other civ.scen calls). Have a look at this page if you need to figure out where to put a certain kind of event, and if you're still not sure, you can ask me.
 
I found the error by looking at the Lua Template's original events.lua file, where mine said getUnit only, it was getActiveUnit in the template. My guess is, at some point I did a search, and somehow that "Active" word was erased or spaced out of the text. I'm attaching the file before I noticed this, in case there was something I missed. But now it is loading fine and no errors in console.

You'll notice some tables are missing functions, too, as I have yet to implement them. Also, my "treasure table" doesn't seem to be working... the options come up for the VillageEcon killUnit, but I tried to make a random treasure table and think I may have mis-worded things.

The other function I'll play with today is "finding nearest friendly city," which I am looking forward to! Any advice there would always be welcome. I'm trying to have an option on that menu (for VillageInfra killUnit) that rushes production of the nearest city.

Anyway, here is the damaged events.lua file. Thank you, Prof.!
 
Last edited:
The other function I'll play with today is "finding nearest friendly city," which I am looking forward to! Any advice there would always be welcome. I'm trying to have an option on that menu (for VillageInfra killUnit) that rushes production of the nearest city.
Here's a lesson I wrote on that. It seems that the upgrade of the wiki version destroyed the code text boxes, but there are screenshots of the code also. gen.distance will save you a few lines.

Is there anything you still need me to look at your code for?
 
You'll be happy to hear that I troubleshooted all of my issues the first half of the day. I had so many problems with my nested tables. Once I got that down, it was smooth sailing. Now I have 3 different types of tribes with unique menus and choices. The threshold tables make things easy to modify, too, which is convenient. Thanks for that and other tips.

I was able to register the nearest friendly city, and tried stringing together code based on rush buy costs, but nothing is sticking. Do you think it would be possible in the game to, say, give Extra Shields to that Nearest Friendly City for X turns?

And would it also be possible to "fill" the shield box of the nearest city (e.g., finish production, but it wouldn't register until the next turn)?

Curious if these are doable!

Here are some screenshots of those 2 new menus. It would be a lot of photos to show that each option is functional, but everything is tested (AI uses them, too! which I am particularly excited about).

Spoiler :
builders.png


merchants.png
 
Hi again Prof. Here is my latest issue:

Code:
Enter console.commands() to see a list of keys in the console table.  Some give access to functions in modules, others will run event code.
...op\ToT With Lua\Original\LuaCore\leaderBonus.lua:485: attempt to index a nil value (local 'leaderClass')
stack traceback:
    ...op\ToT With Lua\Original\LuaCore\leaderBonus.lua:485: in upvalue 'verifyCommander'
    ...op\ToT With Lua\Original\LuaCore\leaderBonus.lua:538: in function 'leaderBonus.updateCommander'
    ...op\ToT With Lua\Original\LuaCore\leaderBonus.lua:608: in field '?'
    ...oT With Lua\Original\LuaCore\discreteEventsRegistrar.lua:101: in field 'performOnActivateUnit'
    ...strator\Desktop\ToT With Lua\Original\events.lua:519: in upvalue 'doOnUnitActivation'
    ...strator\Desktop\ToT With Lua\Original\events.lua:543: in function <...strator\Desktop\ToT With Lua\Original\events.lua:534>

The issue only comes up on the 2nd turn; there is 1 leader in the field. If I disband the unit the first turn, the issue doesn't come up.

I haven't yet parsed my code into different files, FYI. I haven't edited those lua docs at all, so I wonder if it has to do with my leader table. Here is that, for your reference:

Spoiler :
Code:
local leaderBonus = require("leaderBonus"):minVersion(1)
local traits = require("traits")
local combatMod = require("combatModifiers")
local gen = require("generalLibrary"):minVersion(4)
local object = require("object")
local traits = require("traits")

leaderBonus.registerLeaderClass({
    rank = "Tyrant I",
    seniority = 4,
    subordinates = {"offensive"},
    alwaysLeaderType = unitAliases.General1T,
    attackModifier = 1.5,
    defenseModifier = nil,
    responsibilityRadius = 0,
    subordinationRadius = 0,
    allMapCommand = true,
})

leaderBonus.registerLeaderClass({
    rank = "Tyrant II",
    seniority = 3,
    subordinates = {"offensive"},
    alwaysLeaderType = unitAliases.General2T,
    attackModifier = 1.5,
    defenseModifier = nil,
    responsibilityRadius = 1,
    subordinationRadius = 1,
    allMapCommand = true,
})

leaderBonus.registerLeaderClass({
    rank = "Tyrant III",
    seniority = 2,
    subordinates = {"offensive"},
    alwaysLeaderType = unitAliases.General3T,
    attackModifier = 1.5,
    defenseModifier = nil,
    responsibilityRadius = 2,
    subordinationRadius = 2,
    allMapCommand = true,
})

leaderBonus.registerLeaderClass({
    rank = "Tyrant IV",
    seniority = 1,
    subordinates = {"offensive"},
    alwaysLeaderType = unitAliases.General4T,
    attackModifier = 1.5,
    defenseModifier = nil,
    responsibilityRadius = 3,
    subordinationRadius = 3,
    allMapCommand = true,
})

leaderBonus.registerLeaderClass({
    rank = "Protector I",
    seniority = 4,
    subordinates = {"defensive"},
    alwaysLeaderType = unitAliases.General1P,
    attackModifier = nil,
    defenseModifier = 2.0,
    responsibilityRadius = 0,
    subordinationRadius = 0,
    allMapCommand = true,
})

leaderBonus.registerLeaderClass({
    rank = "Protector II",
    seniority = 3,
    subordinates = {"defensive"},
    alwaysLeaderType = unitAliases.General2P,
    attackModifier = nil,
    defenseModifier = 2.0,
    responsibilityRadius = 1,
    subordinationRadius = 1,
    allMapCommand = true,
})

leaderBonus.registerLeaderClass({
    rank = "Protector III",
    seniority = 2,
    subordinates = {"offensive"},
    alwaysLeaderType = unitAliases.General3P,
    attackModifier = nil,
    defenseModifier = 2.0,
    responsibilityRadius = 2,
    subordinationRadius = 2,
    allMapCommand = true,
})

leaderBonus.registerLeaderClass({
    rank = "Protector IV",
    seniority = 1,
    subordinates = {"defensive"},
    alwaysLeaderType = unitAliases.General4P,
    attackModifier = nil,
    defenseModifier = 2.0,
    responsibilityRadius = 3,
    subordinationRadius = 3,
    allMapCommand = true,
})
 
Hi again Prof. Here is my latest issue:

Code:
Enter console.commands() to see a list of keys in the console table. Some give access to functions in modules, others will run event code.
...op\ToT With Lua\Original\LuaCore\leaderBonus.lua:485: attempt to index a nil value (local 'leaderClass')
stack traceback:
...op\ToT With Lua\Original\LuaCore\leaderBonus.lua:485: in upvalue 'verifyCommander'
...op\ToT With Lua\Original\LuaCore\leaderBonus.lua:538: in function 'leaderBonus.updateCommander'
...op\ToT With Lua\Original\LuaCore\leaderBonus.lua:608: in field '?'
...oT With Lua\Original\LuaCore\discreteEventsRegistrar.lua:101: in field 'performOnActivateUnit'
...strator\Desktop\ToT With Lua\Original\events.lua:519: in upvalue 'doOnUnitActivation'
...strator\Desktop\ToT With Lua\Original\events.lua:543: in function <...strator\Desktop\ToT With Lua\Original\events.lua:534>
The issue only comes up on the 2nd turn; there is 1 leader in the field. If I disband the unit the first turn, the issue doesn't come up.

I haven't yet parsed my code into different files, FYI. I haven't edited those lua docs at all, so I wonder if it has to do with my leader table. Here is that, for your reference:
Please generate the error using this version of leaderBonus.lua (which should be placed in the LuaCore) and post the results. (right before the error, there should be a printing of a table, which might be fairly large, and I want that as well) This error isn't a mistake in your table, since the leaderBonus module is meant to have robust error checking that catches mistakes when starting the game.
 

Attachments

Here you go! Here's the whole thing. Thank you Prof.!

Spoiler :
Code:
Global variables are disabled
Enter console.commands() to see a list of keys in the console table.  Some give access to functions in modules, others will run event code.
{['Protector IV'] = {['rank'] = Protector IV,['seniority'] = 1,['subordinates'] = {[1] = defensive,},['allMapCommand'] = true,['defenseModifier'] = {['dCustomMult'] = 2.0,['customCheck'] = function: 056F1768,},['responsibilityRadius'] = 3,['alwaysLeaderType'] = UnitType<id=79, name="Protector IV", prereq="<no>", domain=0, attack=0, defense=1, hitpoints=20, firepower=1>,['subordinationRadius'] = 3,},['Tyrant I'] = {['rank'] = Tyrant I,['seniority'] = 4,['attackModifier'] = {['customCheck'] = function: 056DD120,['aCustomMult'] = 1.5,},['subordinates'] = {[1] = offensive,},['allMapCommand'] = true,['responsibilityRadius'] = 0,['alwaysLeaderType'] = UnitType<id=72, name="Tyrant I", prereq="<no>", domain=0, attack=0, defense=1, hitpoints=20, firepower=1>,['subordinationRadius'] = 0,},['Tyrant II'] = {['rank'] = Tyrant II,['seniority'] = 3,['attackModifier'] = {['customCheck'] = function: 056DFF68,['aCustomMult'] = 1.5,},['subordinates'] = {[1] = offensive,},['allMapCommand'] = true,['responsibilityRadius'] = 1,['alwaysLeaderType'] = UnitType<id=73, name="Tyrant II", prereq="<no>", domain=0, attack=0, defense=1, hitpoints=20, firepower=1>,['subordinationRadius'] = 1,},['Tyrant III'] = {['rank'] = Tyrant III,['seniority'] = 2,['attackModifier'] = {['customCheck'] = function: 056E2CD0,['aCustomMult'] = 1.5,},['subordinates'] = {[1] = offensive,},['allMapCommand'] = true,['responsibilityRadius'] = 2,['alwaysLeaderType'] = UnitType<id=74, name="Tyrant III", prereq="<no>", domain=0, attack=0, defense=1, hitpoints=20, firepower=1>,['subordinationRadius'] = 2,},['Protector II'] = {['rank'] = Protector II,['seniority'] = 3,['subordinates'] = {[1] = defensive,},['allMapCommand'] = true,['defenseModifier'] = {['dCustomMult'] = 2.0,['customCheck'] = function: 056EB998,},['responsibilityRadius'] = 1,['alwaysLeaderType'] = UnitType<id=77, name="Protector II", prereq="<no>", domain=0, attack=0, defense=1, hitpoints=20, firepower=1>,['subordinationRadius'] = 1,},['Tyrant IV'] = {['rank'] = Tyrant IV,['seniority'] = 1,['attackModifier'] = {['customCheck'] = function: 056E5998,['aCustomMult'] = 1.5,},['subordinates'] = {[1] = offensive,},['allMapCommand'] = true,['responsibilityRadius'] = 3,['alwaysLeaderType'] = UnitType<id=75, name="Tyrant IV", prereq="<no>", domain=0, attack=0, defense=1, hitpoints=20, firepower=1>,['subordinationRadius'] = 3,},['Protector III'] = {['rank'] = Protector III,['seniority'] = 2,['subordinates'] = {[1] = offensive,},['allMapCommand'] = true,['defenseModifier'] = {['dCustomMult'] = 2.0,['customCheck'] = function: 056EE810,},['responsibilityRadius'] = 2,['alwaysLeaderType'] = UnitType<id=78, name="Protector III", prereq="<no>", domain=0, attack=0, defense=1, hitpoints=20, firepower=1>,['subordinationRadius'] = 2,},['Protector I'] = {['rank'] = Protector I,['seniority'] = 4,['subordinates'] = {[1] = defensive,},['allMapCommand'] = true,['defenseModifier'] = {['dCustomMult'] = 2.0,['customCheck'] = function: 056E8A28,},['responsibilityRadius'] = 0,['alwaysLeaderType'] = UnitType<id=76, name="Protector I", prereq="<no>", domain=0, attack=0, defense=1, hitpoints=20, firepower=1>,['subordinationRadius'] = 0,},}
...op\ToT With Lua\Original\LuaCore\leaderBonus.lua:487: leaderBonus.verifyCommander: the rank 'General' is not a registered leaderClass.
stack traceback:
    [C]: in function 'error'
    ...op\ToT With Lua\Original\LuaCore\leaderBonus.lua:487: in upvalue 'verifyCommander'
    ...op\ToT With Lua\Original\LuaCore\leaderBonus.lua:542: in function 'leaderBonus.updateCommander'
    ...op\ToT With Lua\Original\LuaCore\leaderBonus.lua:612: in field '?'
    ...oT With Lua\Original\LuaCore\discreteEventsRegistrar.lua:101: in field 'performOnActivateUnit'
    ...strator\Desktop\ToT With Lua\Original\events.lua:519: in upvalue 'doOnUnitActivation'
    ...strator\Desktop\ToT With Lua\Original\events.lua:543: in function <...strator\Desktop\ToT With Lua\Original\events.lua:534>
 
Here you go! Here's the whole thing. Thank you Prof.!
Thanks. Did you happen to try the leader bonus code using 'General' as a rank, and then change it later? If so, then I've recreated your error and can fix it.
 
Back
Top Bottom