Introduction#
Factorio is a sandbox automation and logistics game notable for, among other things, very good support for mods. The developers often go out of their way to support features and fix bugs that only affect mods.
I've only just started to dip my toes in the world of Factorio modding, so I'm definitely no authority on the topic. But this post will be about things that weren't obvious to me starting out.
Resources#
As I said, modding is very well supported, which includes comprehensive documentation and tutorials. One detail I'd call out is that I recommend installing FMTK, which provides IDE tooling for writing Factorio mods, including a VS Code extension (don't worry, there's a Vim mode for VS Code). Also you will probably spend a lot of time looking at the log file. Additionally, you can find lots of examples by looking at the many existing mods; a lot them have links to source code repositories from their mod pages, but even if they don't, you can just download them and unzip them.
If you have a question that can't be answered by those resources or a
web search, you can ask for help on the modding forum
or the #modding-help
channel of the
official Factorio Discord.
Other tips#
Where to put mods#
(See also: FMTK documentation "Setting up your workspace for Modding" and Factorio wiki "Tutorial:Mod structure")
Factorio mods are stored in the mods
directory under the user data
directory. Mods installed from the mod portal are in
ZIP files named {mod-name}_{version}.zip
. But Factorio will also load
mods from a directory in that directory, as long as the directory name
matches the name of the mod, with a preference for loading from a
directory over a ZIP file. For my own organization, I kept the mod
code elsewhere on my filesystem and symlinked it into there.
Note that FMTK recommends setting the VS Code workspace directory to the
mods
directory, not the directory of a single mod.
Setting up debugging#
(See also: FMTK documentation "Debug Adapter" and VS Code debugging)
Probably the most useful feature of FMTK is the debugger. To set it up, open your mods directory in VS Code, and go to the "Run" menu, select "Add Configuration...", and then "Factorio Mod Debug". Additionally, you may need to tell FMTK which Factorio install to use. Towards the left side of the status bar on the bottom of the VS Code window, you should see it say "Factorio (unselected)". Click there to get the option to point it at your Factorio install.
Then debug by going to the "Run and Debug" pane in VS Code and select the kind of debugging you want to do from the drop-down. Factorio mods act in a few different phases, and the default debugging option is for debugging the actual gameplay, while there's an alternate option "Factorio Mod Debug (Settings & Data)" for debugging loading the game and the initialization logic that your mod may do at that point. (There's another option for profiling which I have not made use of yet.)
Lua#
Factorio, like many modern games, uses the Lua programming language for its mods, as it is lightweight and intended for embedding in other applications. One notable difference in Factorio's version of Lua is that everything is deterministic as for multiplayer, the computations have to get the same answer on every player's computer. In practice, unless you doing something weird, you are unlikely to notice that detail.
Notable differences from other languages#
The Lua manual does a pretty good job of describing the language. A few surprises include:
- The not-equals operator is
~=
. - The string concatenation operator is
..
. - There's no separate ternary operator (
?:
) but due to the semantics ofand
/or
on non-boolean values, the Lua idiom is to writecond and a or b
which is equivalent tocond ? a : b
in C-like languages (as long asa
is notfalse
/nil
). - Since functions are first-class values, to define a local function,
you write
local function f () ... end
not justfunction f () ... end
. Otherwise you are declaring the function a global. - Table values cannot be
nil
(Lua's equivalent tonull
in other languages); setting a value tonil
is how you delete an entry from a table. Related, there's no error for looking up a missing table value: it just reads the valuenil
. Trying to further treatnil
as a table and look up a value on it will cause an error. - Iterating over a table in a
for
loop requirespairs
/ipairs
(for k,v in pairs(t) do body end
), and the latter iterates only integer indexes until it reaches a missing value. type(val)
will give you the language-defined type of a value. That is, for a table, it will always give the string"table"
, not some user-defined typename.
Future posts#
I expect to write more posts as I get deeper into the world of modding Factorio, which will appear under the "Factorio mods" tag here.
Comments
Have something to add? Post a comment by sending an email to comments@aweirdimagination.net. You may use Markdown for formatting.
There are no comments yet.