MouseyPounds
Prince
I've always been one who wanted a little more information out of my Civ games. I want to know how stuff works and what the AI is doing and if I can change the things that bug me without screwing up my game; in other words, I'm a modder at heart. So I loved playing around in the Civ4 World Builder and Python Console to see what I could do, and now with Civ5 I'd like to do the same. Hence, I've decided to spend some quality time with the enigmatic Fire Tuner. And while the Tuner doesn't do everything that I would like, I've realized that we have quite a bit of freedom to change that. This brief tutorial will hopefully shed some light on the subject and perhaps inspire future modding efforts.
Introduction
If you've never used the Fire Tuner, there are a couple things you need to know. First, it's part of the SDK Download available for free on Steam. And second, to actually use it you need to set the "EnableTuner" option to 1 in your config.ini file which is located at the root of the Civ5 documents folder.
Once it has been enabled and Civ5 is running, you can simply launch the SDK and pick "Fire Tuner" from the menu and it will connect automatically. A connected Tuner will look something like this:
That can be mighty intimidating to a newbie modder but after poking around a bit I found that it's not that bad. It's really just a Console window and a bunch of configurable panels that let you do stuff. The Console lets you run arbitrary Lua commands similar to how the old Civ4 Python Console worked and all the Panels are just a barebones UI hiding some underlying Lua code; and all that code and even the Panels themselves are fully moddable. But before we mod, let's take a quick look around.
Early Exploration
The main caveat with the Lua console is that you can set it to various "States" to access different parts of the game. So if you want to run a function or access a variable from a running mod, you'd select the mod's name in the state dropdown menu first. Other than that the Console is pretty straightforward. If you want to test it, go ahead and switch to the "WorldView" state and type the following:
The name of your civ's leader should then be printed out prefaced with "WorldView:" If you have logging turned on (another config.ini option) it will also be output to the Lua.log file in the Logs subdirectory of your Civ5 documents folder. Let's leave off the console for now though and get back to the main topic. That "Active Player" tab sure looks like a good place to start...
So what we have here are a bunch of buttons that appear to give things to the player and also some information such as how much gold and culture the player currently has. Hmm. Make sure your game has been saved and then go ahead and change the money value or award a tech and notice the immediate effects. Okay, nice. But what's the deal with this "Current Research ID?" I sure don't know all the tech IDs; it'd be pretty useful if the output would also show the tech name. And a field for the happy bucket might be useful too. Wouldn't it be nice if we could make such changes? Yes it would; but more importantly, "Yes we can."
Hacking the Tuner
The first clues that we can change the functionality of the Tuner are that it has a "New Control" button next to the State dropdown and a "* New Panel *" tab at the end of the tab list. But before we start going crazy, let's back some stuff up. If you choose "Save Panel As" from the File Menu you'll see that all the panels are actually stored as ".ltp" files in the Debug subdirectory of the Civ5 Installation folder. Repeating for emphasis, they are in the Civ5 folder and not the SDK folder; I'm not sure what this means in terms of Steam updates but it's probably a good idea to do regular backups if you make any changes. In fact, we might as well back everything up somewhere safe right now. Additionally, for extra paranoia and because it serves as a useful example, let's actually save the panel under a new name. I chose "Active Player Plus.lua" but you can call it anything you want. Now we will reopen that file we just saved, which will add a second "Active Player" tab to the end of the list. Let's switch over to that one and start experimenting.
The first thing I'm going to do is rename my new panel so that I don't get too confused. So right-click anywhere in the blue bar below the tabs and choose "Edit Panel." This brings up a tiny "Panel Builder" window with a "Name" field, a slew of checkboxes, and some buttons. I'll change the Name to "Active Player Plus;" it doesn't have to match the filename but it's a good habit. The checkboxes allow you to restrict which Lua States the panel will be used with; "WorldView" should be the only one checked and we have no good reason to change that; BTW you can resize this window which makes it easier to work with the checkboxes since they aren't arranged alphabetically. The "On Enter" and "On Exit" buttons bring up additional windows where you can add Lua code. These code blocks are run when you switch to and away from the Panel respectively and would probably be useful for things like variable initialization and cleanup; for the purposes of this tutorial we'll leave them blank.
Right-clicking on one of the controls (e.g. the "Recalc Building Maint" button) shows us that we can actually Edit or Move that thing in addition to Copying and Deleting. So let's move it somewhere else like a little below the "Player 1 DoW" button. Being able to rearrange the panel at will is quite useful especially when you get String controls which overlap like the Gold/Culture boxes. Feel free to adjust the Culture one too to counteract this. Now let's edit something.
Keeping it simple, I'm gonna take the 1000 Culture button and make it a "5000 Culture" button. So I right-click it and choose Edit:
Well that's simple enough. I can change the name to "5000 Culture" and then change the 1000 to 5000 in the Lua code under the Action section. Note that you can hit the "Test" button right here and the Output will let you know if there was an error, but be warned that if there is no error it will affect the game. So go ahead and try it then check back in Civ5 to verify the 5000 Culture got added.
Now we'll do something a little more complicated and see if we can add a tech name indicator too. We could click the "New Control" menu and select a "String Control" but in this case I think it makes more sense to copy the "Current Research ID" control and modify that we'll probably use similar code. So let's right-click on it and "Copy," then right-click in a bare part of the window and choose "Paste Control." This gives us a box which we can move around and then click to place. I put it next to the control I just copied and then choose "Edit."
This seems pretty straightforward; the Name is the button label, there's a place for a Default value, and there are 2 code boxes for "Set" and "Get" with some Lua filled in. I'm going to change the name to "Tech Name" and leave the default as-is. Since I want this to be basically a read-only control (which can't actually be specified) I'll comment out the "Players..." line of the "Set" function so that it does nothing if the text gets edited. Now let's look at the "Get" function. Currently it gets the tech ID and stores it to a variable eCurrentTech and then returns this variable. What I want to do is lookup that ID and get the actual tech name and then return that instead. We also should add some error-checking since the tech ID is -1 when there is no actual research target. So I'll change the function to read:
After hitting OK, we should now see the tech name and if we go back into the game and switch techs, the tuner should update appropriately. Note that this isn't perfect and initially the field might remain blank; if this is the case you can force it to update by switching to another Panel and then back to "Active Player Plus." Additionally, we can't actually make the value read-only so you could actually click on the tech name and type something else. While that doesn't affect the game in any way because we made the "Set" function do nothing; you can always force a refresh as discussed previously to get the name back.
Although it won't really do anything, let's add a City List here too to illustrate how lists work. So either right-click in the open area or choose the "New Control" menu and then choose "Selection List."
This is a similar window to the other controls we've seen. The "Name" option and "Sort Alphabetically" checkbox should be self-explanatory but the code boxes may not be. "Populate List" creates the list itself by building and returning a table. If you don't want alphanumeric sorting you can arrange it however you want by how you order your table (I think.) For our purposes we will simply iterate over the list of player's cities and add those to the table with the following code:
Since the list is purely informational, you can leave the "On Selection" function as-is. Normally this would be used to process whatever value was clicked on. After hitting OK, you can place the list wherever you want; note that if you right-click the list-box after it is placed you actually get a resize command to help with fitting it onto the panel.
After rearranging things a bit more and adding some other "missing" controls, my "Active Player Plus" panel now looks like this:
I have attached the "Active Player Plus.ltp" file pictured above to this post. If you want to experiment with it, feel free to download, drop it into the Debug directory, and then Open it up in your Tuner. Note that despite the extension it is actually just an XML file which could be edited in a text editor which could be useful for fine-tuning the layout if you're sorta OCD about such things.
After I return from holiday travel I will do some more experimenting in this area; I'd love to be able to make versions of the "Selected City" and "Selected Unit" Panels that would easily work with any player's stuff or see what else could be done with the "Map" panel and the "ploppers." Thanks for reading and please let me know if there is anything which can be improved and/or about your own Tuner tweaks.
Introduction
If you've never used the Fire Tuner, there are a couple things you need to know. First, it's part of the SDK Download available for free on Steam. And second, to actually use it you need to set the "EnableTuner" option to 1 in your config.ini file which is located at the root of the Civ5 documents folder.
Once it has been enabled and Civ5 is running, you can simply launch the SDK and pick "Fire Tuner" from the menu and it will connect automatically. A connected Tuner will look something like this:
That can be mighty intimidating to a newbie modder but after poking around a bit I found that it's not that bad. It's really just a Console window and a bunch of configurable panels that let you do stuff. The Console lets you run arbitrary Lua commands similar to how the old Civ4 Python Console worked and all the Panels are just a barebones UI hiding some underlying Lua code; and all that code and even the Panels themselves are fully moddable. But before we mod, let's take a quick look around.
Early Exploration
The main caveat with the Lua console is that you can set it to various "States" to access different parts of the game. So if you want to run a function or access a variable from a running mod, you'd select the mod's name in the state dropdown menu first. Other than that the Console is pretty straightforward. If you want to test it, go ahead and switch to the "WorldView" state and type the following:
Code:
print(Players[0]:GetName())
The name of your civ's leader should then be printed out prefaced with "WorldView:" If you have logging turned on (another config.ini option) it will also be output to the Lua.log file in the Logs subdirectory of your Civ5 documents folder. Let's leave off the console for now though and get back to the main topic. That "Active Player" tab sure looks like a good place to start...
So what we have here are a bunch of buttons that appear to give things to the player and also some information such as how much gold and culture the player currently has. Hmm. Make sure your game has been saved and then go ahead and change the money value or award a tech and notice the immediate effects. Okay, nice. But what's the deal with this "Current Research ID?" I sure don't know all the tech IDs; it'd be pretty useful if the output would also show the tech name. And a field for the happy bucket might be useful too. Wouldn't it be nice if we could make such changes? Yes it would; but more importantly, "Yes we can."
Hacking the Tuner
The first clues that we can change the functionality of the Tuner are that it has a "New Control" button next to the State dropdown and a "* New Panel *" tab at the end of the tab list. But before we start going crazy, let's back some stuff up. If you choose "Save Panel As" from the File Menu you'll see that all the panels are actually stored as ".ltp" files in the Debug subdirectory of the Civ5 Installation folder. Repeating for emphasis, they are in the Civ5 folder and not the SDK folder; I'm not sure what this means in terms of Steam updates but it's probably a good idea to do regular backups if you make any changes. In fact, we might as well back everything up somewhere safe right now. Additionally, for extra paranoia and because it serves as a useful example, let's actually save the panel under a new name. I chose "Active Player Plus.lua" but you can call it anything you want. Now we will reopen that file we just saved, which will add a second "Active Player" tab to the end of the list. Let's switch over to that one and start experimenting.
The first thing I'm going to do is rename my new panel so that I don't get too confused. So right-click anywhere in the blue bar below the tabs and choose "Edit Panel." This brings up a tiny "Panel Builder" window with a "Name" field, a slew of checkboxes, and some buttons. I'll change the Name to "Active Player Plus;" it doesn't have to match the filename but it's a good habit. The checkboxes allow you to restrict which Lua States the panel will be used with; "WorldView" should be the only one checked and we have no good reason to change that; BTW you can resize this window which makes it easier to work with the checkboxes since they aren't arranged alphabetically. The "On Enter" and "On Exit" buttons bring up additional windows where you can add Lua code. These code blocks are run when you switch to and away from the Panel respectively and would probably be useful for things like variable initialization and cleanup; for the purposes of this tutorial we'll leave them blank.
Right-clicking on one of the controls (e.g. the "Recalc Building Maint" button) shows us that we can actually Edit or Move that thing in addition to Copying and Deleting. So let's move it somewhere else like a little below the "Player 1 DoW" button. Being able to rearrange the panel at will is quite useful especially when you get String controls which overlap like the Gold/Culture boxes. Feel free to adjust the Culture one too to counteract this. Now let's edit something.
Keeping it simple, I'm gonna take the 1000 Culture button and make it a "5000 Culture" button. So I right-click it and choose Edit:
Well that's simple enough. I can change the name to "5000 Culture" and then change the 1000 to 5000 in the Lua code under the Action section. Note that you can hit the "Test" button right here and the Output will let you know if there was an error, but be warned that if there is no error it will affect the game. So go ahead and try it then check back in Civ5 to verify the 5000 Culture got added.
Now we'll do something a little more complicated and see if we can add a tech name indicator too. We could click the "New Control" menu and select a "String Control" but in this case I think it makes more sense to copy the "Current Research ID" control and modify that we'll probably use similar code. So let's right-click on it and "Copy," then right-click in a bare part of the window and choose "Paste Control." This gives us a box which we can move around and then click to place. I put it next to the control I just copied and then choose "Edit."
This seems pretty straightforward; the Name is the button label, there's a place for a Default value, and there are 2 code boxes for "Set" and "Get" with some Lua filled in. I'm going to change the name to "Tech Name" and leave the default as-is. Since I want this to be basically a read-only control (which can't actually be specified) I'll comment out the "Players..." line of the "Set" function so that it does nothing if the text gets edited. Now let's look at the "Get" function. Currently it gets the tech ID and stores it to a variable eCurrentTech and then returns this variable. What I want to do is lookup that ID and get the actual tech name and then return that instead. We also should add some error-checking since the tech ID is -1 when there is no actual research target. So I'll change the function to read:
Code:
function()
local pPlayer = Players[Game.GetActivePlayer()];
local eCurrentTech = pPlayer:GetCurrentResearch();
local rStr = "(None)"
if eCurrentTech >= 0 then
rStr = Locale.ConvertTextKey(GameInfo.Technologies[eCurrentTech].Description)
end
return rStr
end
After hitting OK, we should now see the tech name and if we go back into the game and switch techs, the tuner should update appropriately. Note that this isn't perfect and initially the field might remain blank; if this is the case you can force it to update by switching to another Panel and then back to "Active Player Plus." Additionally, we can't actually make the value read-only so you could actually click on the tech name and type something else. While that doesn't affect the game in any way because we made the "Set" function do nothing; you can always force a refresh as discussed previously to get the name back.
Although it won't really do anything, let's add a City List here too to illustrate how lists work. So either right-click in the open area or choose the "New Control" menu and then choose "Selection List."
This is a similar window to the other controls we've seen. The "Name" option and "Sort Alphabetically" checkbox should be self-explanatory but the code boxes may not be. "Populate List" creates the list itself by building and returning a table. If you don't want alphanumeric sorting you can arrange it however you want by how you order your table (I think.) For our purposes we will simply iterate over the list of player's cities and add those to the table with the following code:
Code:
function()
local listItems = {}
local pPlayer = Players[Game.GetActivePlayer()]
local c
for c in pPlayer:Cities() do
table.insert(listItems, c:GetName())
end
return listItems
end
After rearranging things a bit more and adding some other "missing" controls, my "Active Player Plus" panel now looks like this:
I have attached the "Active Player Plus.ltp" file pictured above to this post. If you want to experiment with it, feel free to download, drop it into the Debug directory, and then Open it up in your Tuner. Note that despite the extension it is actually just an XML file which could be edited in a text editor which could be useful for fine-tuning the layout if you're sorta OCD about such things.
After I return from holiday travel I will do some more experimenting in this area; I'd love to be able to make versions of the "Selected City" and "Selected Unit" Panels that would easily work with any player's stuff or see what else could be done with the "Map" panel and the "ploppers." Thanks for reading and please let me know if there is anything which can be improved and/or about your own Tuner tweaks.