Also this is written for 0.2.10 and earlier. I'm not sure yet exactly how much may change with the coming 0.3 so if you are reading this after 0.3 is out and it has not been updated BEWARE OF POSSIBLE CHANGES. now that that is out of the way, here it is:
First I'll say I am in no way an expert on either lua or Factorio. Second I use Notepad++ for modding (and adobe photshop cs5 for the graphics). I also happen to be using the Windows 7 64 bit OS. As such any locations I give as to where to find files may, or may not, be accurate depending on if you are using the same OS. In relation the my first statement, Notepad++ is only for windows, it has not been ported to linux or mac (though it is open source, GPL license, written in c++).
Next I will say there are two things, once you start with lua, that are really really helpful.
first the wiki https://forums.factorio.com/wiki/inde ... _scripting (go there read it).
Second the Factorios campaign lua files. They are found under factorio\data\campaigns then you have demo and beta within both of those there are the levels folders inside of each level is a control.lua. These are the lua files that control the campagins. It can be very useful to look through these (especially when you are first learning) to see how the devs did something
Beyond that use the forums and experiment, not necessarily in that order.
Now, if you were to open factorio\data\lualib\freeplay.lua you would be looking at the lua code that is run whenever you start a new game. This is/will be copied into the player's saves. What this means is that if someone tries to play your mod from their save file it probably WILL NOT WORK, unless you let them know that they need to copy your freeplay.lua (or control.lua as it is called in the save files) into their save directory (which is C:\Users\<user>\AppData\Roaming\Factorio\saves on windows 7 64bit installation, if they have the zip file it is simply Factorio\saves).
One other thing before we jump into the Lua code. When you start an 'if' statement you MUST end it with 'end', you may hear/see it called an if-then statement, this is because without a 'then' there is no code to execute. the basic syntax is:
if something == something then
do this
end
Notice the double ==, lua uses a single = to SET a variable, and double == to CHECK a variable. You CAN NOT use a single = to check if x equals 10. it will give an error! (sorry about stressing this but if you are not used to coding it will cause problems, and you will use if statements alot. If you have some experience then you will understand)
Now then onto a bit of code:
When you open freeplay.lua you will see
Code: Select all
require "util"
require "story"
require "defines"
next you will see:
Code: Select all
game.oninit = function()
end
Then you will see
Code: Select all
game.onevent = function(event)
an entity if you do not know is anything, repeat anything, that is generated when the world is (like trees, coal, and creeper spawners) or that you can place 'in' the world (like furnaces, assembling machines, and inserters). The only thing that you will see in the game that are NOT entities are the tiles (the grass/water/'hills' that you walk on) and the items in your inventory (or that of a chest/furnace/etc.)
BTW: a 'block' is a section of code that works together, in an if statement the 'block' of code that is executed is the code between then and end.
The next block of code is another if statement:
Code: Select all
if event.name == "ontick" then
if glob.introduction == nil then
glob.introduction = true
game.getplayer().insert{name="iron-plate", count=8}
game.getplayer().insert{name="pistol", count=1}
game.getplayer().insert{name="basic-bullet-magazine", count=10}
end
To break this down:
Code: Select all
if glob.introduction == nil then
The next line is
Code: Select all
game.getplayer().insert{name="iron-plate", count=8}
Notice that after insert are curly brackets { this tells the insert function that the data is in the form of a table/array. There are four types of variables, there are tables which contain the other three types (though tables can contain tables), then you have you basic numbers (which can be decimal), then you have strings which is text like "This is a string." It is possible to have numbers as a string "This string contains the number 5, but it is still a string type variable", then last you have the boolean type variable, which is very simple. A boolean variable is either true or false, note that if you set a variable this="true" it is a string variable not a boolean variable. There is one other type of variable, there are global variables which lua creates whenever you write:
Code: Select all
var=whatever
Code: Select all
local var=whatever
You should now see that the name variable is a string that tells insert to give the player the item named iron-plate (the items are defined in the json files of factorio\data\prototype-definition\item) and that count is a variable containing the number of iron-plate's to insert. Pretty simple right?
After the iron plates the game lua code also gives the player a pistol and some basic ammo.
That's the very basics of lua for factorio. To really learn how to code then you will need to watch the wiki for updated information (especially the events) and simply TRY IT OUT. Another good way is to look at the code that other people have written to see if you can A) understand it and B) see why they did it that way and if how they did it is better than you would have done it.
One last thing to be aware of, ingame you can type lua commands by pressing the ~ (the key next to the 1 on a standard us keyboard). Note that this has a limited amount of typing space, though you can use it to set variables and then use those variables to execute a longer commad.
Some common variables/commands to know (there are probably alot more, i'll edit this when people yell at me or i remember them)
game.getplayer().print("some text") will print text to the screen (very useful when debugging your code, and if you were creating a mission for someone)
game.showmessagedialog("text") Will pop message up so that the user has to hit TAB to acknowledge it.
game.getplayer().position.x and game.getplayer().position.y the x and y positions of the player.
Useful code aka "cheater chest":
Code: Select all
if event.name == "onbuiltentity" then
if event.createdentity.name=="wooden-chest" then
entities = game.findentities{topleft = {x = event.createdentity.position.x - .1, y = event.createdentity.position.y - .1}, bottomright = {x = event.createdentity.position.x + .1, y = event.createdentity.position.y + .1}}
for fieldName, _ in pairs(entities) do chest=entities[fieldName].getinventory(defines.inventory.chest) end
if chest.isvalid() and chest.caninsert({name="iron-ore", count="200"}) then
chest.insert({name="iron-plate", count="200"})
game.showmessagedialog("Gratis")
game.getplayer().insert({name="rifle-gun", count="1"})
game.getplayer().insert({name="copper-rifle-ammo", count="200"})
game.getplayer().insert({name="coal", count="200"})
game.getplayer().insert({name="car", count="1"})
end --end if chest is valid
end --end if entity=wooden-chest
end--end onbuiltentity
The block of code that begins with for is called a for loop because it will loop through the code after 'do' and before 'end' until the table is empty. It can also be used like:
Code: Select all
for i=1, v do
count=count+1
game.getplayer().print(count) --note we are print the value of the variable count, not the text string count. This is why "" are important when you want to print something to the screen
end
Also not sure if I mentioned it or not but if
Code: Select all
--anthing
if you want to comment out more than one line (for debugging or you just want a long intro to your mod whatever) use
Code: Select all
--[[comment]]
http://lua-users.org/wiki/TutorialDirectory