[LUA] Calling the game database

Joined
Jul 31, 2014
Messages
836
Hey all, probably a really basic question, but how would I go about calling the game database from a base LUA script (such as AssignStartingPlots.lua)?

For example:

Since Firaxis hard-coded the values to "take into account the various terrain yields in determining fertility....." crap in order to "determine how much value to assign each starting region", I would like to access the table "Terrain_Yields" (as well as others) to retrieve the yields for say, plains, grass, tundra, etc. to feed into the existing algorithm.

What would be the general syntax for doing so (calling a specific element from any game database table - i.e. not using a loop to iterate through everything)?
 
No need to use DB, you can use GameInfo (and several other examples of this in the core Lua files)

Code:
local sTerrain = "TERRAIN_PLAINS"
for yields in GameInfo.Terrain_Yields{TerrainType = sTerrain} do
  print(yields.TerrainType, yields.YieldType, yields.Yield)
end

will print

Code:
TERRAIN_PLAINS YIELD_FOOD 1
TERRAIN_PLAINS YIELD_PRODUCTION 1
 
For the line :

Code:
for yields in GameInfo.Terrain_Yields{TerrainType = sTerrain} do

Is that roughly translated to "if the element in GameInfo.[table name] has column TerrainType equal to sTerrain"?

Also, am I correct in assuming that to extract anything out of a game database table, we must use a loop to iterate (and use a check to filter results), as opposed to say, calling out a specific row?
 
Code:
for yields in GameInfo.Terrain_Yields{TerrainType = sTerrain} do

Is that roughly translated to "for each element in GameInfo.[table name] has column TerrainType equal to sTerrain"?
Yes (but "for each" rather than "if" - as there may be 0, 1 or more entries)

Also, am I correct in assuming that to extract anything out of a game database table, we must use a loop to iterate (and use a check to filter results), as opposed to say, calling out a specific row?
No.

The result of GameInfo.table_name{something=value} is an iterator, which is why it can be used where the for statement expects an iterator. Each time an iterator is called it returns the next value, so we can write

Code:
local row = GameInfo.Terrain_Yields{TerrainType = sTerrain}()

Note the use of () after the closing curly bracket, which causes the iterator function to be called once and return the first row from the Terrain_Yields table.

row will either be nil or a Lua table holding a single row from the database table

If, and only if, we know that there will always be an entry in the database table, we could write
Code:
local iPlainsProd = GameInfo.Terrain_Yields{TerrainType="TERRAIN_PLAINS", YieldType="YIELD_PRODUCTION"}().Yield
which would directly retrieve the value

BUT, beware, if we wrote

Code:
local iTundraProd = GameInfo.Terrain_Yields{TerrainType="TERRAIN_TUNDRA", YieldType="YIELD_PRODUCTION"}().Yield

(unless a mod had added production on tundra) we would get a nil pointer error, so the safe code would be

Code:
local row = GameInfo.Terrain_Yields{TerrainType="TERRAIN_TUNDRA", YieldType="YIELD_PRODUCTION"}()
local iTundraProd = row and row.Yield or 0

(That last bit is a more condensed way or writing "local iTundraProd = 0; if (row) then iTundraProd = row.Yield end", it's (almost) equivalent to the C++/Java "condition ? true value : false value;" construct.)

[[For more on Lua iterators see here]]

W
 
Back
Top Bottom