Advertisement
Civilization Fanatics' Center  

Welcome to Civilization Fanatics' Center.

You are currently viewing our site as a guest which gives you limited access to our site features. By joining our free community, you will be able to participate in the discussions, search the forum, send private messages, vote in polls, upload your own screenshots to the gallery, and access many other special features. Registration is fast, simple and absolutely free, so sign up today! If you have any problems with the registration process or your account login, please contact support.

Go Back   Civilization Fanatics' Forums > CIVILIZATION V > Civ5 - Creation & Customization > Civ5 - Modding Tutorials & Reference

Notices

Reply
 
Thread Tools
Old Nov 23, 2010, 04:08 PM   #1
Onni
Chieftain
 
Join Date: Oct 2010
Posts: 82
Creating UI mods with lua & xml

This tutorial is meant to help you to create a simple UI mod. You will learn how to create a simple button which will change it's caption once you press it. It will also give you tips on using lua-scripts, xml-elements, the Tuner and how to write not-corefile-dependant mods. Before reading this tutorial, I'd recommend first reading this excellent Modders Guide from Kael.

Changelog:
2010-11-25 Added chapter 10 about source code


1. You are trying to trick me into reading some kind of manual! No way, Jose!
Here's a quick list of steps how to create a simple mod with an UI element.
  1. Create a Lua-project in ModBuddy.
    Click image for larger version

Name:	ModBuddy_modinfo.jpg
Views:	278
Size:	86.1 KB
ID:	273434
  2. Add a lua- and xml-file with exactly the same name to that project.
  3. Add an InGameUIAddin for your lua-file. This will also automatically import the xml-file.
    Click image for larger version

Name:	ModBuddy_content.jpg
Views:	288
Size:	75.8 KB
ID:	273435
  4. Create an xml-element in your xml-file.
  5. All done! You don't need to write anything in lua-file for just creating an xml-element and showing it.
2. XML Pilgrim vs the world
There are two types of xml-elements used in Civ: <GameData> and <Context>. GameData-elements changes the game rules and has nothing to do with this tutorial. Context-elements on the other hand create all the windows and buttons you can see. Actually almost everything you can see in Civ is created with Context-elements. So when ever this tutorial refers to xml it's always about Context-elements.

3. Local warming a.k.a why my neighbors ice caps aren't melting
There are three different levels of environment scope in Civ's Lua-engine. If you fail to change a valua or call a function then it most likely because it doesn't exist in your current environment.
  • local = Any values declared with this are only available from the current lua-element and it's children.
  • thread = This is the default scope. You can change non-local-values from any file or function as long as they are in same thread. Normally a single mod creates a single thread.
  • global = Truly global environment is not available in Civ. There is a top level lua-environment "_G" (=Main State), but you can't access that from a mod. Otherwise all threads could be accessed through this (Main State -> Threads).
4. Would you like your beds be connected or separated for your mod, Sir?
If all your mods values and functions are within a single thread then you can eg. call a function from anywhere simply like this: MyFunction()
If your mods values and functions are spread in different threads then it's not that simple anymore. You can't call a function within a different thread with normal methods. You have to do that using LuaEvent's or ShareData.
I would recommend that you try to create a single thread for your mod if it's possible. If you have only one lua- and xml-file in your mod then that's easy:
  1. Use exactly the same name for both lua- and xml-file.
  2. Add an InGameUIAddin for your lua-file. This will automatically also import the xml-file.
    Click image for larger version

Name:	ModBuddy_content.jpg
Views:	288
Size:	75.8 KB
ID:	273435
  3. This should create a single thread that is called the same as your file name.
  4. If you are using my templates then the Tuner log should read something like this after the game has started:
    Click image for larger version

Name:	Tuner_startup.jpg
Views:	222
Size:	90.5 KB
ID:	273441
  5. Also in the game the button should look like this before and after it has been clicked:
    Click image for larger version

Name:	Game_buttons.jpg
Views:	165
Size:	2.3 KB
ID:	273437Click image for larger version

Name:	Game_buttons_pressed.jpg
Views:	156
Size:	2.8 KB
ID:	273438
5. How to do it in a single bed with multiple files
If you have multiple files in your mod then you can put them in a single thread using this method.
  1. Create main lua- and xml-files and use exactly the same name for both of them. Your thread will be named after them. You can write also your normal code in them, but their main purpose is to bring all the other files into this thread.
  2. Add an InGameUIAddin for your main lua-file. This will automatically also import the main xml-file.
  3. This should create a single thread that is called the same as your file name.
  4. If you would add a second InGameUIAddin then that would create a second thread and we don't want that.
  5. Now all your lua-files will be merged into this main lua-file using include command.
  6. You may have noticed that there is no default initialization function in Civ's lua-engine. You might need it to e.g. initialize your main window AFTER you have all function declared and ready. With this method it's easy to do that by inserting your own init-function after all the include commands. Here's an example main lua-file:
    Code:
    print("PracticeMod2.lua loaded")
    include("Extra1.lua")
    include("Extra2.lua")
    Init() --My initialization function
  7. Now we will import all the xml-files using the main xml-file. Here's an example main xml-file:
    Code:
    <Context>
    	<LuaContext FileName="PracticeMod2Button1" ID="PracticeMod2Button1" Hidden="0" />
    	<LuaContext FileName="PracticeMod2Button2" ID="PracticeMod2Button2" Hidden="0" />
    </Context>
  8. Warning: Do not create lua-files that are named like these xml-files. Otherwise also your lua-code will be divided into multiple threads.
  9. There are couple minor side-effects with this one. You will get an error message saying that the lua-file for this xml-file wasn't found. And also all these xml-files will be created within their own thread. I haven't found any other way to do this, but don't worry...it only looks bad.
  10. If you are using my templates then the Tuner log should read something like this after the game has started:
    Click image for larger version

Name:	Tuner2_startup.jpg
Views:	123
Size:	73.9 KB
ID:	273444
  11. Also in the game the buttons should look like this before and after they have been clicked:
    Click image for larger version

Name:	Game2_buttons.jpg
Views:	131
Size:	5.6 KB
ID:	273439Click image for larger version

Name:	Game2_buttons_pressed.jpg
Views:	106
Size:	6.4 KB
ID:	273440
Because your xml-elements are now in different threads than your lua-files, you have to use different methods to access them.
Normally you would access an xml-element within your thread like this:
Code:
Controls.MyButton:SetHide(true)
But if you wanted to do the same thing with an element within PracticeMod2Button1 thread you would have to do it like this:
Code:
ContextPtr:LookUpControl("PracticeMod2Button1/MyButton"):SetHide(true)
Remember that you have to use those ID-tags in your xml-elements to be able to manipulate them at all through lua.

6. OMG! My Tuner is live! Or on fire?
Personally I could almost live without ModBuddy, but I would refuse to do any modding without Firaxis Live/FireTuner. This program is a Lua console that you can use to either keep track watch happening with all the lua stuff behind the game engine or run your own lua commands. Here's what you can do with it.
  • Log (Lua Console tab): If you execute a print("Hello world") command from your mod then this is the place where you can the see result. It also shows you all the lua errors that you may encounter. The first word in every row is the thread name from where that log message is coming from.
  • Lua console (Lua Console tab): At the bottom row you can see an editbox where you can execute lua commands. But before you try to do that you have to choose a thread which you want to direct that command. Just underneath the "Lua Console" tab there's a dropdown box. By default "Main State" is chosen. You can't really get anything done with this one, but more likely be greeted with an error message. Choose your mods thread from this (it's normally called the same as your mod or main file). Now all your commands will be executed as you would have written them into your actual code. Here are example logs about using wrong threads.
    Click image for larger version

Name:	Tuner_commands.jpg
Views:	111
Size:	57.7 KB
ID:	273442Click image for larger version

Name:	Tuner_commands_error.jpg
Views:	102
Size:	71.2 KB
ID:	273445
  • Other thing you can use this console is to reload your lua-files without ever leaving the game. You can do that with include("YourFileName.lua") command. But be aware that there are some difficulties with this one. It doesn't replace your current file, but simply add that file a second time to your mod. Therefore it will overwrite any values or functions you had with the same name. But if you eg. had event registration in that file then you have now registered twice into that event (=your function is called twice). At the moment there is no known way to reload your xml-files.
  • Table browser (Table Browser tab): With this tool you can see all the tables within the selected thread. Confusion comes when you try to select your own mods thread from the dropdown. You can't find it! You have to add it here by right clicking on the right side (on the blue bar) of this dropdown. Choose "Edit panel" and then tick your mods checkbox on the opened list.

7. Waiter, there's a ContextPtr in my Tooltip!
ContextPtr object can be accessed from all threads. You can use it to either create new threads or manipulate xml-elements in any thread.
  • Creating new threads with ContextPtr
Code:
--This command creates a new thread. The functions argument is the name
--of the lua- and xml-file you wish to use.
--You don't normally need to use this command.
ContextPtr:LoadNewContext("FileNameWithoutTail")
  • Manipulate xml-elements with ContextPtr. ContextPtr points to the <Context> element in your xml-file. Here are few of it's commands explained.
Code:
--Will hide your context-element and everything in it.
ContextPtr:SetHide(true)
Code:
--Everytime when you hide or show this Context-element then this function is called.
ContextPtr:SetShowHideHandler(ShowHideFunction)
Code:
--Everytime when you press a key or move your mouse this function is called.
--Be careful with this one since it's called very often.
ContextPtr:SetInputHandler(InputHandlerFunction)
Code:
--This is a powerful command to refer to any element (not just Context) with ID
--within any thread. You could use it to manipulate your own sub-threads
--or even the elements in core files.
ContextPtr:LookUpControl("/ParentThreadName/SubThreadName/ElementId")
8. Who let the dogs out (into MY front lawn)
In Civ you can have multiple mods functioning at the same time so you should try to design your mods so that they will interface other mods as little as possible. Maybe the biggest question is when and how you should modify the core-files (eg. InGame.xls)? Core-files are the lua- and xml-files that come with the vanilla Civ. You can overwrite those core-files by simply adding a file with the same name into your mod. If possible you should avoid modifying them or at least do it the "right way".
  • Only if you need to attach your mods xml-element to an existing xml-element then you might need to also modify core-files.
  • If you need to modify core-xml-element then you don't necessary need to modify the actual core-file. Here's an example how to hide the science-per-turn column on top panel from your mod:
    Code:
    ContextPtr:LookUpControl("/InGame/TopPanel/SciencePerTurn"):SetHide(true)
  • It's always possible to overwrite a single core-element from your mod, but if you can you should try adding to that element instead. This enables other mods to also use that same element. Here's another example how to add a new column to top panel:
    Code:
    --In xml-file:
    <TextButton Hidden="0" Anchor="C,T" String="CUSTOM" ColorLayer0="255,255,200,255"  ID="CustomString"/>
    
    --In lua-file:
    Controls.CustomString:ChangeParent(ContextPtr:LookUpControl("/InGame/TopPanel/TopPanelInfoStack"))
    ContextPtr:LookUpControl("/InGame/TopPanel/TopPanelInfoStack"):ReprocessAnchoring()
  • Sometimes there are no perfect solutions, but just compromises. Then the best thing is to communicate with other mod authors that are using same elements. And most importantly: let the users know about it.
__________________
Civ 5: Blog about development of CivWillard 2.0 -> One Lucky Build
Civ 5: [UI]CivWillard - Easy City & Diplo management
Civ 5: [TUTORIAL] Creating UI mods with lua & xml

Last edited by Onni; Nov 25, 2010 at 12:49 AM.
Onni is offline   Reply With Quote
Old Nov 23, 2010, 04:08 PM   #2
Onni
Chieftain
 
Join Date: Oct 2010
Posts: 82
9. Mom! Where are my socks!?
I've attached templates from the mods that I used to create these examples. You can create a new project in ModBuddy using them as the template so that you can see for yourself how they work. To be able to see these templates you should save them (do not extract them, but just leave them as zip's) into this directory: "..\My Documents\Firaxis ModBuddy\Templates\ProjectTemplates\" (eg. ..\ProjectTemplates\PracticeMod.zip)

Remember to look into the top level folder in ModBuddy to see these templates:
Click image for larger version

Name:	ModBuddy_templates.jpg
Views:	111
Size:	48.9 KB
ID:	273451

10. The source is out there
Here is the source code for PracticeMod:
Spoiler:

PracticeMod.lua
Code:
print("PracticeMod.lua loaded")

--This function has to exist before it's assigned to RegisterCallback.
function MyButtonFunction(arg1, arg2)
	print("Argument 1 = " .. arg1 .. ", Argument 2 = " .. arg2)
	Controls.MyLabel:SetText("Button pressed (" .. arg1 .. ", " .. arg2 .. ")")
end

--Hides button
Controls.MyBackground:SetHide(true)
--Shows button
Controls.MyBackground:SetHide(false)
--Changes the buttons text
Controls.MyLabel:SetText("New button text")

--When you left click the button MyButtonFunction is called. MyButtonFunction has to be without () !
Controls.MyButton:RegisterCallback(Mouse.eLClick, MyButtonFunction )
--MyButtonFunction is called with these arguments (eg. MyButtonFunction(9, 99)).
--The arguments can only be numbers.
Controls.MyButton:SetVoid1(9)
Controls.MyButton:SetVoid2(99)
PracticeMod.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<Context>
	<!-- Color="red, green, blue, transparency" -->
	<!-- ConsumeMouse="1" so that we don't click anything behind the element -->
	<Box ID="MyBackground" Hidden="0" Anchor="C,C" Size="200,50" Offset="0,0" Color="0,0,0,150" ConsumeMouse="1">
		<Button ID="MyButton" Anchor="L,T" Size="200,50">
			<Label ID="MyLabel" Anchor="C,C" Font="TwCenMT18" String="Button text"/>
		</Button>
	</Box>
</Context>

And the source code for PracticeMod2:
Spoiler:

PracticeMod2.lua (main lua-file)
Code:
print("PracticeMod2.lua loaded")

include("Extra1.lua")
include("Extra2.lua")
Init()
Extra1.lua
Code:
print("Extra1.lua loaded")

function Init()
	InitMainButton()
	InitButton1()
	InitButton2()
end

function InitMainButton()
	--Hides button
	Controls.MyBackground:SetHide(true)
	--Shows button
	Controls.MyBackground:SetHide(false)
	--Changes the buttons text
	Controls.MyLabel:SetText("New main button text")

	--When you left click the button MyButtonFunction is called. MyButtonFunction has to be without () !
	Controls.MyButton:RegisterCallback(Mouse.eLClick, MyButtonFunction )
	Controls.MyButton:RegisterCallback(Mouse.eLClick, MyButtonFunction2 )
	--MyButtonFunction is called with these arguments (eg. MyButtonFunction(9, 99)).
	--The arguments can only be numbers.
	Controls.MyButton:SetVoid1(9)
	Controls.MyButton:SetVoid2(99)
end

function InitButton1()
	--Manipulate the button in sub-thread: PracticeMod2Button1
	ContextPtr:LookUpControl("PracticeMod2Button1/MyLabel"):SetText("New button1 text")
	ContextPtr:LookUpControl("PracticeMod2Button1/MyButton"):RegisterCallback(Mouse.eLClick, MyButtonFunction )
	ContextPtr:LookUpControl("PracticeMod2Button1/MyButton"):SetVoid1(1)
	ContextPtr:LookUpControl("PracticeMod2Button1/MyButton"):SetVoid2(11)
end

function InitButton2()
	--Manipulate the button in sub-thread: PracticeMod2Button2
	ContextPtr:LookUpControl("PracticeMod2Button2/MyLabel"):SetText("New button2 text")
	ContextPtr:LookUpControl("PracticeMod2Button2/MyButton"):RegisterCallback(Mouse.eLClick, MyButtonFunction )
	ContextPtr:LookUpControl("PracticeMod2Button2/MyButton"):SetVoid1(2)
	ContextPtr:LookUpControl("PracticeMod2Button2/MyButton"):SetVoid2(22)
end
Extra2.lua
Code:
print("Extra2.lua loaded")

--This function has to exist before it's assigned to RegisterCallback.
function MyButtonFunction(arg1, arg2)
	print("Argument 1 = " .. arg1 .. ", Argument 2 = " .. arg2)
	local _text = "Button pressed (" .. arg1 .. ", " .. arg2 .. ")"
	if arg1 == 9 then
		Controls.MyLabel:SetText(_text)
	elseif arg1 == 1 then
		ContextPtr:LookUpControl("PracticeMod2Button1/MyLabel"):SetText(_text)
	elseif arg1 == 2 then
		ContextPtr:LookUpControl("PracticeMod2Button2/MyLabel"):SetText(_text)
	end
end

function MyButtonFunction2(arg1, arg2)
	print("XXXArgument 1 = " .. arg1 .. ", Argument 2 = " .. arg2)
end
PracticeMod2.xml (main xml-file)
Code:
<?xml version="1.0" encoding="utf-8"?>
<Context>
	<Box ID="MyBackground" Hidden="0" Anchor="C,C" Size="200,50" Offset="0,0" Color="0,0,0,150" ConsumeMouse="1">
		<Button ID="MyButton" Anchor="L,T" Size="200,50">
			<Label ID="MyLabel" Anchor="C,C" Font="TwCenMT18" String="Main button"/>
		</Button>
	</Box>
	<LuaContext FileName="PracticeMod2Button1" ID="PracticeMod2Button1" Hidden="0" />
	<LuaContext FileName="PracticeMod2Button2" ID="PracticeMod2Button2" Hidden="0" />
</Context>
PracticeMod2Button1.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<Context>
	<Box ID="MyBackground" Anchor="C,C" Size="200,50" Offset="0,-51" Color="0,0,0,150" ConsumeMouse="1">
		<Button ID="MyButton" Anchor="L,T" Size="200,50">
			<Label ID="MyLabel" Anchor="C,C" Font="TwCenMT18" String="Button1 button"/>
		</Button>
	</Box>
</Context>
PracticeMod2Button2.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<Context>
	<Box ID="MyBackground" Anchor="C,C" Size="200,50" Offset="0,51" Color="0,0,0,150" ConsumeMouse="1">
		<Button ID="MyButton" Anchor="L,T" Size="200,50">
			<Label ID="MyLabel" Anchor="C,C" Font="TwCenMT18" String="Button2 button"/>
		</Button>
	</Box>
</Context>

Seen you in the game!
Attached Files
File Type: zip PracticeMod.zip (10.3 KB, 55 views)
File Type: zip PracticeMod2.zip (11.9 KB, 47 views)
__________________
Civ 5: Blog about development of CivWillard 2.0 -> One Lucky Build
Civ 5: [UI]CivWillard - Easy City & Diplo management
Civ 5: [TUTORIAL] Creating UI mods with lua & xml

Last edited by Onni; Nov 25, 2010 at 12:45 AM.
Onni is offline   Reply With Quote
Old Nov 23, 2010, 04:09 PM   #3
Onni
Chieftain
 
Join Date: Oct 2010
Posts: 82
Again reserved for later use...
__________________
Civ 5: Blog about development of CivWillard 2.0 -> One Lucky Build
Civ 5: [UI]CivWillard - Easy City & Diplo management
Civ 5: [TUTORIAL] Creating UI mods with lua & xml
Onni is offline   Reply With Quote
Old Dec 01, 2010, 06:41 PM   #4
Deep_Blue
Knight
 
Deep_Blue's Avatar
 
Join Date: Aug 2005
Posts: 750
Do you know how to edit the UI for trade table in diplomacy windows?
I tried editing SimpleDiploTrade.xml but no change occurs in the game.
Deep_Blue is offline   Reply With Quote
Old Dec 14, 2010, 01:48 AM   #5
Slowpoke
The Mad Modder
 
Slowpoke's Avatar
 
Join Date: Sep 2010
Posts: 1,321
Ooooo this is just what I need! Thanks, I'll be looking through this.
__________________
Art of War Mod! by Ordian. It rocks.
France- A double Anceint Era Declaration of War on Deity against two clearly conquest geared civs that dredged on for 1500 years.
Okay this one makes the above one look like a bunch of preschoolers out at a picnic getting attacked by baby ants. THIS ONE is awesome. Read it.
Mega Mod What started as a balance fix is now getting massive. Now accepting suggestions (units/buildings in particular)
Beatles/Elvis -4.3 Talker/Listener +7.2
Slowpoke is offline   Reply With Quote
Old Dec 20, 2010, 12:58 PM   #6
Zyxpsilon
Running Spider
 
Zyxpsilon's Avatar
 
Join Date: Oct 2009
Location: On Earth
Posts: 2,095
Images: 3
Yeah, i agree... this whole fantastic stuff should be directly linked with the Wiki.

While i'm here. Onni, could you look into "adding" some virtual button for quick access to Fire-Tuner without having to alt-tab out of everything during runtime?
Attached Images
 
__________________
Z'Stuff Reference Threads... Advisors, Eras+Center, UI, LeoPaRd, -- yep, Life itself is ART.
__________________
Z'Helps while... SpreadSheet'ing the Facts, TerraForming and,
Trying to Resolve Tactical 1upT or Multiplying CS Variety!
Zyxpsilon is offline   Reply With Quote
Old Dec 20, 2010, 02:44 PM   #7
martijnaikema
Warlord
 
Join Date: Oct 2010
Posts: 111
This was some quite usefull information. Especially the Contextptr info. I need to digest this information and do some experimenting. Thanx a lot!
martijnaikema is offline   Reply With Quote
Old Dec 23, 2010, 09:34 AM   #8
martijnaikema
Warlord
 
Join Date: Oct 2010
Posts: 111
You know if it is possible to change the order in which the different lua-parts are anchored in the toppanel? Like if I would like the Gold per Turn to display on the right, is that possible?
martijnaikema is offline   Reply With Quote
Old Dec 27, 2010, 06:57 AM   #9
Onni
Chieftain
 
Join Date: Oct 2010
Posts: 82
Sorry for the late answers, but I was taking a little break from Civ modding..

Quote:
Originally Posted by Deep_Blue View Post
Do you know how to edit the UI for trade table in diplomacy windows?
I tried editing SimpleDiploTrade.xml but no change occurs in the game.
I think the correct xml might be DiploTrade.xml? All the lua-action in trade-window is handled in TradeLogic.lua (which doesn't have equal xml-file).


Quote:
Originally Posted by Zyxpsilon View Post
While i'm here. Onni, could you look into "adding" some virtual button for quick access to Fire-Tuner without having to alt-tab out of everything during runtime?
What do you mean with this virtual button? Do you mean that you would like to see FireTuner log within a game window?


Quote:
Originally Posted by martijnaikema View Post
You know if it is possible to change the order in which the different lua-parts are anchored in the toppanel? Like if I would like the Gold per Turn to display on the right, is that possible?
There is one interesting looking function in \asset\UI\FrontEnd\GameSetup\SelectGameSpeed.lua
Code:
ContextPtr:BuildInstanceForControlAtIndex( "ItemInstance", controlTable, Controls.Stack, i-1 );
Haven't tried it myself, but it could be the thing you are looking for? Otherwise I don't know any perfect solutions, but perhaps first using that ChangeParent function to detach the previous elements from that TopPanelInfoStack and then attaching them back there in your preferred order could accomplish it?
__________________
Civ 5: Blog about development of CivWillard 2.0 -> One Lucky Build
Civ 5: [UI]CivWillard - Easy City & Diplo management
Civ 5: [TUTORIAL] Creating UI mods with lua & xml
Onni is offline   Reply With Quote
Old Jan 06, 2011, 01:04 AM   #10
Deep_Blue
Knight
 
Deep_Blue's Avatar
 
Join Date: Aug 2005
Posts: 750
Do you know how to change the order of displayed contents in lua, like bringing a box element forward. I know that elements are shown in order of their location in the xml file, is there a lua function to change this order?
Deep_Blue is offline   Reply With Quote
Old Mar 21, 2011, 05:35 PM   #11
Civ Fuehrer
Eat, Sleep, Mod
 
Civ Fuehrer's Avatar
 
Join Date: May 2008
Location: CA, USA
Posts: 1,182
This is a great tut - I used it to start my UI mod a while ago which I have been taking a break from recently - but could I get a tut on how to do all this with dynamic buttons? Sure it's pretty handy for a static button format, but my mod is constantly updating with in-game progress and as random things through random events unlock, more buttons automatically spawn. I need to know how to get the Lua to understand which button was pressed since dynamic box instances all contain the same name / ID.
__________________
"The sweet taste of victory is a flavor that never runs bland" - Civ Fuehrer

Last edited by Civ Fuehrer; Mar 22, 2011 at 10:00 AM.
Civ Fuehrer is offline   Reply With Quote
Old Jan 22, 2012, 01:05 PM   #12
Moriboe
Prince
 
Moriboe's Avatar
 
Join Date: Nov 2010
Location: Belgium
Posts: 566
Great guide! I was getting lost in my erratic lua code; the info here made things clear for me! Why didn't I read this earlier...
__________________
Building Made Fun going strong with 25,000+ downloads
Terra Nostra's last version got thumbs up by 500+ people
Uomo Universalis wraps it all up: Try it now! (vanilla only)
Moriboe is offline   Reply With Quote
Reply

Bookmarks

Go Back Civilization Fanatics' Forums > CIVILIZATION V > Civ5 - Creation & Customization > Civ5 - Modding Tutorials & Reference > [TUTORIAL] Creating UI mods with lua & xml

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Advertisement

All times are GMT -6. The time now is 03:59 AM.


Powered by vBulletin®
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
This site is copyright © Civilization Fanatics' Center.
Support CFC: Amazon.com | Amazon UK | Amazon DE | Amazon CA | Amazon FR