I came by this thread while looking at documentation stuff, and I got along to writing a simple converter for XML.
It is not yet completely finished, and I'm sure it's rather ugly and inefficient, as it's the first time I've used Lua, and the data structure can be... confusing.
I'm using cube's Loader to load the data, and genx (
http://genx.luaforge.net/index.html) to generate the XML, which I may switch. it is the first Lua XML library I found, but it seems like it has many downsides. One such downside is that the XML is not formatted very pretty, but this is easily fixable with xmllint (
http://xmlsoft.org/xmllint.html).
Here is an example of the XML output (for Rocket Defense, just because

)
Code: Select all
<?xml version="1.0"?>
<item>
<name>rocket-defense</name>
<display>Rocket defense</display>
<type>entity</type>
<icon>__base__/graphics/icons/rocket-defense.png</icon>
<recipe ingredientCount="5">
<category/>
<time>0.5</time>
<ingredient>
<item>
<name>rocket</name>
<display>Rocket</display>
<type>entity</type>
<icon>__base__/graphics/icons/rocket.png</icon>
</item>
<count>100</count>
</ingredient>
<ingredient>
<item>
<name>advanced-circuit</name>
<display>Advanced Circuit</display>
<type>item</type>
<icon>__base__/graphics/icons/advanced-circuit.png</icon>
</item>
<count>128</count>
</ingredient>
<ingredient>
<item>
<name>processing-unit</name>
<display>Processing Unit</display>
<type>item</type>
<icon>__base__/graphics/icons/processing-unit.png</icon>
</item>
<count>128</count>
</ingredient>
<ingredient>
<item>
<name>speed-module-3</name>
<display>Speed module 3</display>
<type>item</type>
<icon>__base__/graphics/icons/speed-module-3.png</icon>
</item>
<count>50</count>
</ingredient>
<ingredient>
<item>
<name>productivity-module-3</name>
<display>Productivity module 3</display>
<type>item</type>
<icon>__base__/graphics/icons/productivity-module-3.png</icon>
</item>
<count>50</count>
</ingredient>
</recipe>
</item>
and the actual code, which I'm still hoping to make better/add features:
Code: Select all
require 'genx'
local Loader = require('loader')
local data_path = "~/games/factorio/data"
local types = {"entity", "equipment","item"}
function getDisplayNameType(name, lang)
local i_type = "unknown"
local display_name = nil
for i=1, #types do
if not display_name then
display_name = Loader.translate(types[i] .. "-name." .. name,lang)
if display_name ~= nil then
i_type = types[i]
end
end
end
return display_name, i_type
end
function getIcon(name)
for i=1,#Loader.item_types do
local t=Loader.item_types[i]
if Loader.data[t][name] then
return Loader.data[t][name]["icon"] or "?"
end
end
return "?"
end
function addItem(doc, item_name, include_recipe)
local i_type = "unknown"
local display_name = nil
display_name, i_type = getDisplayNameType(item_name, "en")
if not display_name then
display_name = item_name
end
doc:startElement('item') -- start item
doc:startElement('name')
doc:text(item_name)
doc:endElement()
doc:startElement('display')
doc:text(display_name)
doc:endElement()
doc:startElement('type')
doc:text(i_type)
doc:endElement()
doc:startElement('icon')
doc:text(getIcon(item_name))
doc:endElement()
if include_recipe then
local recipe = Loader.data.recipe[item_name]
if recipe then
addRecipe(doc, recipe)
end
end
doc:endElement() -- end item
end
function addRecipe(doc, recipe)
doc:startElement('recipe')
doc:attribute('ingredientCount', #(recipe.ingredients) or -1)
cat = recipe.category or ""
time = recipe["energy_required"] or 0.5
if cat=="smelting" or not time then
time = "?"
end
doc:startElement('category')
doc:text(cat)
doc:endElement()
doc:startElement('time')
doc:text(time)
doc:endElement()
for i =1, #(recipe.ingredients) do
local ing = recipe.ingredients[i]
i_name = ing.name or ing[1]
i_count = ing.amount or ing[2]
doc:startElement('ingredient')
addItem(doc, i_name, false) -- add the ingredient data
doc:startElement('count') -- add count for ingredient
doc:text(i_count)
doc:endElement()
doc:endElement() -- ingredient
end
doc:endElement() -- recipe
end
Loader.load_data({data_path .. "/core", data_path .. "/base"})
for k,item in pairs(Loader.data.item) do
local d = genx.new(io.open("xmls/" .. item.name .. ".xml", "w"))
addItem(d, item.name, true)
end
If you want to try it yourself change data_path to your local factorio installation path and make a folder named "xmls" where your script is (I haven't made the effort to find out how to create a folder in Lua, although I'm sure it's not complicated). To make the xmls prettier (nice for humans, shouldn't matter for computer processing ) you can use this (on linux):
Code: Select all
find . -name "*.xml" -type f -exec xmllint --output '{}' --format '{}' \;