[TOTPP] Lua function reference

There are a ton of great enhancements here... obviously some major things like terrain and resources, but also some cases where the ability to access a single field could be leveraged by events for significant impact: city.currentProduction for example, or unit.domainSpec. Also the two new triggers, civ.scen.onCalculateCityYield() and civ.scen.onInitiateCombat(), are super flexible -- a whole new world of possibilities! Thanks, @TheNamelessOne, for this release! :goodjob:
 
Lots of excellent updates here. Being able to alter what players see on the map will make "radar" much easier to implement, for example.

Properties

aggregate (get)
totpp.movementmultipliers.aggregate -> integer

Returns the aggregate movement multiplier (the lcm of the four multipliers above). This value is recalculated when setting any of the individual multipliers. This is an alias for `civ.cosmic.roadMultiplier`.


alpine (get/set - ephemeral)
totpp.movementmultipliers.alpine -> integer

Returns the alpine movement multiplier if it is set, `nil` otherwise.


railroad (get/set - ephemeral)
totpp.movementmultipliers.railroad -> integer

Returns the railroad movement multiplier if it is set, `nil` otherwise.


river (get/set - ephemeral)
totpp.movementmultipliers.river -> integer

Returns the river movement multiplier if it is set, `nil` otherwise.


road (get/set - ephemeral)
totpp.movementmultipliers.road -> integer

Returns the road movement multiplier if it is set, `nil` otherwise.

Sorry to bother you about this, but it should be movementMultipliers. I only ask for the fix since it could cause confusion when looking up how to do something.
 
I'm getting crash to desktop behaviour when trying to get tribe.researching for a tribe not currently researching anything. (at least from the console) Can anyone confirm this behaviour? Does anyone have an idea of how to find out if the tribe currently isn't researching anything through some other code?
I confirmed crash to desktop if I try to print(tribe.researching) from the console, when they aren't researching anything. But this didn't crash:
if tribe.researching == nil then print("It was nil") else print("It was something else") end
What printed was "It was something else". So it seems that referencing the field isn't what causes the crash, it's apparently trying to print it (or convert it to a string?).
...
@Prof. Garfield Just as an FYI, it looks to me like TNO fixed this bug in TOTPP 0.16. Now I can set tribe.researching = nil which I also couldn't do before, and then follow that up with print(tribe.researching) and nil appears on the console. So the workaround code I posted above, while it still works, doesn't seem to be necessary any more.
 
Does this work for the human as well as the AI? If so thank you very much as gold can simply be renamed "resources" or "fuel." Very cool development!

activateUnitEveryMove (get/set - ephemeral)
civ.scen.compatibility.activateUnitEveryMove -> boolean

If set to true, onActivateUnit will re-trigger for every tile the active unit moves. Defaults to false, in which case onActivateUnit triggers only once.
 
Does this work for the human as well as the AI? If so thank you very much as gold can simply be renamed "resources" or "fuel." Very cool development!

In previous versions, the AI always ran onActivateUnit for every move. A quick test reveals that it still does when civ.scen.compatibility.activateUnitEveryMove is false (which it is by default). A few months ago I suggested adding this for the Human player, along with backwards compatibility. @TheNamelessOne has implemented a number of things I've suggested, and I'm very pleased.
 
Could a moderator sticky this thread, please? Each time a new version of TOTPP is released, TheNamelessOne provides updated Lua documentation within the first post of the thread by editing it -- but edits don't bump the thread position in the forum list. It would be great to have this highlighted at the top of the page, right next to "The Test Of Time Patch Project" thread.
 
Registers a function that is called at the start of a turn. The basic sequence of this and other "turn" triggers is as follows:
  • `onTurn` fires
  • Non-tribe-specific updates take place
  • `onTribeTurnBegin` fires for tribe 0.
  • Tribe 0 cities are processed.
  • `onCityProcessingComplete` fires for tribe 0 (this fires even when a tribe has no cities).
  • `onTribeTurnEnd` fires for tribe 0.
  • Tribe 0 units move
  • All active tribes are processed in order according to the sequence for tribe 0
  • `onTribeTurnEnd` fires for tribe 7.
  • `onTurn` fires for the next turn

Is this order correct?
  • `onCityProcessingComplete` fires for tribe 0 (this fires even when a tribe has no cities).
  • `onTribeTurnEnd` fires for tribe 0.
  • Tribe 0 units move
Shouldn't it be this instead? (Haven't tested yet, but this seems the logical format.)
  • `onCityProcessingComplete` fires for tribe 0 (this fires even when a tribe has no cities).
  • Tribe 0 units move
  • `onTribeTurnEnd` fires for tribe 0.
 
Thanks for noticing this, it's fixed.
 
isHuman (get/set)
tribe.isHuman -> boolean

Returns whether the tribe is a/the human player.
Spoiler Error on my side, this is not the isHuman() function which was used, explaining the behaviour. With much thanks to Prof. Garfield ! :
Hello TheNamelessOne.

I just came across an issue in a hotseat game yesterday where this function was used :

To make it simple, bonuses that were meant for the ai got provided to a human player.
This code was located in the "onTurn" section, before tribes play.

Does this function in multiplayer games only works at the playing player's tribe turn ?
Does it not work at all in multiplayer game ?


Much thanks.
 
Last edited:
The tribe object


Properties

numUnits (get)
tribe.numUnits -> integer

Returns the number of units the tribe has.

Just noticed, to have in mind when using it :

Units with "Settle", "Diplomacy" or "Trade" role are excluded from this count ! :)
 
Here are some notes on the behaviour and interactions between these functions. I'll describe with canIrrigate and irrigateTo, but they apply to canMine and mineTo as well.

canIrrigate (get/set - ephemeral)
baseterrain.canIrrigate -> boolean

Returns `true` if the underlying terrain type allows irrigation, `false` otherwise.


canMine (get/set - ephemeral)
baseterrain.canMine -> boolean

Returns `true` if the underlying terrain type allows mining, `false` otherwise.

irrigateTo (get/set - ephemeral)
baseterrain.irrigateTo -> baseterrain

If the irrigation order changes the underlying terrain type return the baseterrain of the new terrain type, `nil` otherwise.

mineTo (get/set - ephemeral)
baseterrain.mineTo -> baseterrain

If the mine order changes the underlying terrain type return the baseterrain of the new terrain type, `nil` otherwise.


This is how the game interprets the two fields:

baseTerrain.canIrrigate == true and baseTerrain.irrigateTo == nil --> You can improve the terrain with irrigation
baseTerrain.canIrrigate == false and baseTerrain.irrigateTo == nil --> Game won't let you give the irrigate order
baseTerrain.canIrrigate == true and baseTerrain.irrigateTo == plainsBaseTerrain --> Not possible to have
baseTerrain.canIrrigate == false and baseTerrain.irrigateTo == plainsBaseTerrain --> You can change the terrain to plains

Changing either field has side effects on the other field:

baseTerrain.canIrrigate = true --> baseTerrain.irrigateTo set to nil
baseTerrain.canIrrigate = false --> baseTerrain.irrigateTo set to nil even if baseTerrain.canIrrigate was already false
baseTerrain.irrigateTo = plainsBaseTerrain --> baseTerrain.canIrrigate set to false
baseTerrain.irrigateTo = nil --> baseTerrain.canIrrigate set to false even if baseTerrain.irrigateTo was already nil, baseTerrain.irrigateTo set to desertBaseTerrain

The takeaway is that your code has to handle both of these fields as if they were one field, and change only one key at a time. This will probably only be relevant if you're trying to set terrain to reflect a data set, because you can't just have a table with what each of these values is supposed to be, since "changing" one to the same thing has side effects on the other, not to mention the irrigateTo=nil -> irrigateTo==desert bug.

EDIT:
transformTo (get/set - ephemeral)
baseterrain.transformTo -> baseterrain

If the underlying terrain type can be transformed return the baseterrain of the new terrain type, `nil` otherwise.

It turns out this has a similar behaviour to irrigateTo and mineTo.
baseTerrain.transformTo = nil -> baseTerrain.transformTo is set to desertBaseTerrain, even if it is already nil

I haven't figured out a way to set baseTerrain.transformTo to be nil from a non-nil starting point, but setting it to the same base terrain is a decent workaround. nil would be preferable since it prevents the order from being given in the first place, but that's a fairly minor downside.
 
Last edited:
Hello all. Considering we can take advantage of changing terrain graphics in-game, putting hope in your expertise.

Do you know if it is possible to get (I guess done with your readRules.lua) and set :
-resources names ?
-resource food ?
-resource shields ?
-resource trade ?

or in a simple way, resource parameters ?
or, to put it simplier, alter dynamically resources in-game ?

Much thanks :)
 
Do you know if it is possible to get (I guess done with your readRules.lua) and set :
-resources names ?
All names are currently "set" only, so you can't change them wile the game is active.
-resource food ?
-resource shields ?
-resource trade ?
For these, you use the terrainObject instead of the baseTerrainObject.

If you need further information, it is probably best to ask in Lua Scripting Possibilities or some other thread, so this one doesn't get cluttered.
 
Top Bottom