Lua API (getting started)

Salmo

Chieftain
Joined
Oct 24, 2016
Messages
64
I'n new to Lua but have years of coding in other languages behind me so coding constructs like iteration, variable/value types etc are not the issue. It's a matter of learning the Lua syntax. I've installed ZeroBrane (don't know if that's what others use as an IDE). I can find bits & pieces of Lua code in the forums, but can someone point me to a tutorial on how to reference/setup the Civ 6 API (is there one?) so I can expose the games' methods/functions/events to my code.
 
SO it looks like Modbuddy is the IDE to use. But I can't figure out where the API's are located & how to set a reference to them for my project. All dll's I've tried to reference in the steamapps\common\Sid Meier's Civilization VI\.... folders give a pathing errors
 
I would read www.Lua.org for some examples.

I think probably the most important thing to understand about Lua coming from other languages is tables. You can read some about them here: https://www.lua.org/pil/2.5.html

In some ways Lua is fairly similar to how ActionScript 1 used to be if you've worked with Flash back in the early 2000s.

For concrete examples for Civ 6, I recommend looking at the DLC scenarios, in the script folders.

Overall I still find Lua extremely messy and hard to work with. But a few modders have been able to do some very cool things with it.
 
SO it looks like Modbuddy is the IDE to use. But I can't figure out where the API's are located & how to set a reference to them for my project. All dll's I've tried to reference in the steamapps\common\Sid Meier's Civilization VI\.... folders give a pathing errors

You posted while I was typing my comment. I haven't linked to APIs at all. I've been editing in Notepad++. It is definitely less than optimal. If someone knows a better way I'd be interested to hear their method.
 
@Salmo You don't need to reference anything in Civ6 Lua. Just write a script, all functions and objects are available at once (well, all for a given context). Just check out mods that utilize Lua, you'll see what I mean.
 
The way the game calls lua scripts, all functions, methods and events from the game engine are already exposed and available to your code by default. Gedemon's made a useful list of them here: https://forums.civfanatics.com/threads/lua-objects.601146/

I use Notepad++ for coding myself, and use Firetuner to get realtime feedback from the lua log (i.e. print statements and error messages). Typically, I'll have the game running on one monitor and Notepad++ and Firetuner up on another while I'm editing code. The game reloads scripts on-the-fly whenever you save a new version of the file, so there's no need to keep starting new games to see the effect of changes.
 
Thankyou for the assistance. I've looked at the DLC contents which are helpful to understanding how Lua works. I've made a simple lua script that should just charge the frequency of goodyhut types on game load. Here's the mod https://www.mediafire.com/?rrvxfd6dr9nrv9c Unfortunately, I can't find the printed 'debug ' lines in the log files which suggests that the script is not executing at game-load. I suspect I either have a script error, or it's not setup to execute on game-load properly. Help appreciated.

-- LuaScript1
-- Author: Owner
-- DateCreated: 5/20/2017 1:17:24 PM
--------------------------------------------------------------

print("DEBUG LUA SCRIPT ENTRY ...")
local NumberOfGoodyHutSubTypes = RowCount("GoodyHutSubTypes")
local sql
if NumberOfGoodyHutSubTypes > 0 then
-- generates integer numbers between 0 and 100.
sql = "UPDATE GoodyHutSubTypes SET Weight = \"" .. tostring(math.random(101) - 1) .. \""
local resultId = DB.QUERY(sql)
print(sql)
end
print("DEBUG LUA SCRIPT EXIT ...")
end

function RowCount(TableName)
local resultId = DB.QUERY("SELECT COUNT(1) AS count FROM " .. TableName .. \"")
if resultId then
local count = result.getDataInt(resultId, "count")
result.free(resultId)
return count
else
return -1
end
end
 
Error at line 11 --- LuaScript1.lua:11: function expected instead of nil

-- LuaScript1
-- Author: Owner
-- DateCreated: 5/20/2017 1:17:24 PM
--------------------------------------------------------------

print("* TRUELY RANDOM GOODYHUTS LUA SCRIPT ENTRY *")
local iNumberOfGoodyHutSubTypes = RowCount("GoodyHutSubTypes")
if iNumberOfGoodyHutSubTypes > 0 then
-- generates integer numbers between 0 and 100.
local sql = "UPDATE GoodyHutSubTypes SET Weight = " .. tostring(math.random(101) - 1)
local resultId = DB.QUERY(sql)
print(sql)
end
print("* TRUELY RANDOM GOODYHUTS EXIT *")


function RowCount(TableName)
local resultId = DB.QUERY("SELECT COUNT(1) AS count FROM " .. TableName)
if resultId then
local count = result.getDataInt(resultId, "count")
result.free(resultId)
return count
else
return -1
end
end
 
Is DB.QUERY even valid in GameplayScripts ? (it was a case sensitivity issue: see Post #15 below)

I keep getting nil function errors in this line no matter how I try to re-write the rest of the code in your mod:
Code:
local resultId = DB.QUERY(sql)
I've re-written your original code as:
Code:
function RowCount(TableName)
	local iRowCount = 0
	if GameInfo[TableName]() then
		for row in GameInfo[TableName]() do
			iRowCount = iRowCount + 1
		end
		return iRowCount
	else
		return -1
	end
end
local NumberOfGoodyHutSubTypes = RowCount("GoodyHutSubTypes")
print("NumberOfGoodyHutSubTypes = " .. tostring(NumberOfGoodyHutSubTypes))

local sql
	if NumberOfGoodyHutSubTypes > 0 then
		-- generates integer numbers between 0 and 100. 
		sql = "UPDATE GoodyHutSubTypes SET Weight = " .. tostring(math.random(101) - 1)
		print(sql)
		local resultId = DB.QUERY(sql)
	end
--end
  1. I get the proper number of rows in table GoodyHutSubTypes printed from this line:
    Code:
    print("NumberOfGoodyHutSubTypes = " .. tostring(NumberOfGoodyHutSubTypes))
  2. But then I just get the function expected instead of nil error for the line previously noted.
  3. As you originally had this:
    Code:
    local sql
    	if NumberOfGoodyHutSubTypes > 0 then
    		-- generates integer numbers between 0 and 100. 
    		sql = "UPDATE GoodyHutSubTypes SET Weight = " .. tostring(math.random(101) - 1)
    		print(sql)
    		local resultId = DB.QUERY(sql)
    	end
    end
    • This sort of construction won't be treated as a function or an interation loop. It will merely be treated as a syntax error becaue of the unecessary end
    • You'd get all rows with the same weighting since there is no iteration occuring and therefore the SQL update would act as a onetime global update to all rows in the table
  4. The mod as you originally linked it was not activating the file correctly. You had "UpdateDatabase" in your modinfo file and you need "AddGameplayScripts".
    • The other option "AddUserInterfaces" for an lua file merely results in being shunted back to main menu I assume because there is no xml file associated with the required information for <Context>.
  5. Lua was also throwing errors over the use of the / characters in the concatenations which is why I removed them.
 
Last edited:
Case Sensitivity>

DB.QUERY != DB.Query

I looked past it about 100 times before I saw it.

You want DB.Query(etc)

Although you cannot change much (if anything) in the Database from an lua script. Your code as this executes within lua but has no effect on any row within the table:
Code:
function RowCount(TableName)
	local iRowCount = 0
	if GameInfo[TableName]() then
		for row in GameInfo[TableName]() do
			iRowCount = iRowCount + 1
		end
		return iRowCount
	else
		return -1
	end
end
local NumberOfGoodyHutSubTypes = RowCount("GoodyHutSubTypes")
print("NumberOfGoodyHutSubTypes = " .. tostring(NumberOfGoodyHutSubTypes))

local sql
	if NumberOfGoodyHutSubTypes > 0 then
		-- generates integer numbers between 0 and 100. 
		sql = "UPDATE GoodyHutSubTypes SET Weight = " .. tostring(math.random(101) - 1)
		print(sql)
		local resultId = DB.Query(sql)
	end
--end
 
Not tried, but yes, should do that. I suspect that maybe you can change the game/map configuration using SetValue before restarting.
 
Back
Top Bottom