Skip to content

Package graphics

factorio-rs builds a normal Factorio mod directory. Put graphics under your project, list them in Factorio.toml, and register items with item! so relative icon paths become __mod__/... and Items::* constants wire into locale!.

For recipes, technologies, hand-written stubs, and the full item! / recipe! / technology! field tables, see Prototypes.

my-mod/
assets/graphics/icon.png
Factorio.toml
Cargo.toml
src/
lib.rs
data.rs
[mod]
title = "My Mod"
factorio_version = "2.0"
assets = [
{ from = "assets/graphics", to = "graphics" },
]

Or keep the same relative path:

[mod]
assets = ["graphics"]

Rules (collisions, remaps, thumbnail): Factorio.toml -> Assets.

Cargo [package].name is the mod id. Relative icon paths are rewritten to __my_mod__/graphics/... (replace my_mod with your package name). Paths that already start with __ are left unchanged.

Co-locate item! and locale! in the same data-stage module, or import Items from a sibling module (see Locale and Prototypes) so Items::CONST keys resolve.

src/data.rs
use factorio_rs::prelude::*;
item! {
widget {
name = "my-mod-widget",
icon = "graphics/icon.png",
stack_size = 50,
icon_size = 64,
subgroup = "intermediate-product",
order = "a[my-mod]-a[widget]",
}
}
locale! {
file = "items",
en {
item_name {
Items::WIDGET = "Widget",
}
item_description {
Items::WIDGET = "A sample packaged item.",
}
}
}

item! expands to an Items type with name constants and pub fn register() that calls data.extend with typed Item literals (type = "item" is injected). Every pub fn in a data-stage module runs from data.lua at load time - see Stages.

Factorio reads [item-name] / [item-description] from locale .cfg files automatically (category idents use underscores -> hyphens).

Escape hatch: hand-write data.extend([Item { ... }]) when you need fields the macro does not expose yet.

Terminal window
factorio-rs build
ls dist/graphics
rg 'type = "item"' dist/lua
rg 'my-mod-widget' dist/locale

You should see icon.png, an item table using __my_mod__/graphics/..., and locale keys for the item name.

Emitted shape (simplified):

data.extend({
{
type = "item",
name = "my-mod-widget",
icon = "__my_mod__/graphics/icon.png",
icon_size = 64,
stack_size = 50,
subgroup = "intermediate-product",
order = "a[my-mod]-a[widget]",
},
})
[item-name]
my-mod-widget=Widget

Portal thumbnail is separate from assets:

[mod]
thumbnail = "assets/thumbnail.png" # or rely on ./thumbnail.png