GUI basics
Build a small on-screen frame from the control stage: create the element, set
text, then tune layout through LuaStyle.
Requires a control-stage module (Stages). Attribute reads/writes: API types.
1. Create a frame on player join
Section titled “1. Create a frame on player join”use factorio_rs::{ factorio_api::{classes::LuaGuiElementAddParams, IndexOrName}, prelude::*,};
#[factorio_rs::event(OnPlayerCreated)]pub fn on_player_created(event: OnPlayerCreatedEvent) { if let Some(player) = game.get_player(IndexOrName::Index(event.player_index)) { let frame = player.gui().screen().add(LuaGuiElementAddParams { r#type: GuiElementType::Frame, name: Some("my_mod_root".into()), caption: Some("My mod".into()), ..Default::default() });
let label = frame.add(LuaGuiElementAddParams { r#type: GuiElementType::Label, caption: Some("Hello from factorio-rs".into()), ..Default::default() });
// Use the style object for size / spacing (typed LuaStyle). frame.style().set_width(280); label.style().set_padding(8);
// Optional: swap the whole style prototype by name. // frame.set_style("inside_shallow_frame"); }}r#type is Rust’s way of naming Factorio’s type field (frame, label, …).
GuiElementType lives in the prelude via generated unions.
IndexOrName::Index(player_index) is the typed form Factorio accepts for
get_player (prefer constructors over .into()).
2. What lowers to Lua
Section titled “2. What lowers to Lua”| Rust | Lua |
|---|---|
player.gui().screen().add(...) |
player.gui.screen.add{ type = "frame", ... } |
frame.set_caption("Hi") |
frame.caption = "Hi" |
frame.style().set_width(280) |
frame.style.width = 280 |
frame.set_style("...") |
frame.style = "..." |
Caption can also be set at create time (caption: Some(...)) as above, or later
with set_caption.
3. Rebuild and try it
Section titled “3. Rebuild and try it”Working tree: examples/gui_basics.
cd examples/gui_basicsfactorio-rs build && factorio-rs install --openCreate a new player (or join a map). You should see a titled frame with a label.
- Give elements unique
names under the same parent if you need to find them later (frame["child_name"]/children). Missing children are Factorionilat runtime. - Prefer
style().set_*for width/height/padding; useset_style("name")when you want a style prototype, not one property. TagsusesTags { pairs: &[TagPair { .. }] }for string values.- Choose-elem:
elem_valueisElemValue(Name/Signal/Prototype);elem_filtersisVec<PrototypeFilterEntry>via builders such asEntityPrototypeFilter::type_("furnace")(family must matchelem_type). Nestedelem_filterson some item filter variants are not typed yet. - Close a custom GUI with
player.set_opened(None)(openedisOption<OpenedTarget>).
See also
Section titled “See also”- gui_basics example - full crate in the repo
- API types - attribute writers and
style()typing - Events -
OnPlayerCreatedand filters - First hour - init / build / install loop
- Prototypes - data-stage items / recipes / tech