Mod compatibility - PFQNiet/Satisfactorio GitHub Wiki

How to add a compatibility script for a mod:

Add a file to __Satisfactorio__/compatibility/ and a corresponding require in __Satisfactorio__/compatibility.lua. Add the mod as an optional dependency in info.json to ensure it loads first.

Recipes

Recipes that can be automated should be in constructing, assembling or manufacturing depending on if they take 1, 2 or 3-4 ingredients respectively. If a fluid ingredient is involved, it should be in refining (or possibly packaging if appropriate). Recipes with 5+ solid ingredients, 2+ fluid ingredients cannot be automated and must be made compatible. 5+ ingredients is OK for manual-only recipes.

  • Technically you could have up to 8 ingredients in a Manufacturer but it would require mixed belts.

Manual recipes go in the craft-bench or equipment categories as appropriate.

If a recipe can be automated but should also be manually craftable, duplicate the recipe and change:

  • name = name.."-manual"
  • category = "craft-bench"
  • hide_from_player_crafting = true
  • energy_required = X/4 where X is the "number of hammer strikes" needed to manually craft it

For buildings, the category is building and a deconstruct recipe should be added.

local _group = data.raw['item-subgroup'][building.subgroup]
local undo = {
    type = "recipe",
    name = building.name.."-undo",
    localised_name = {"recipe-name.dismantle",{"item-name."..building.name}},
    ingredients = {{building.name,1}},
    results = data.raw.recipe[building.name].ingredients, -- may need adjusting
    energy_required = 1,
    category = "unbuilding",
    subgroup = _group.group.."-undo",
    order = _group.order.."-"..building.order,
    allow_decomposition = false,
    allow_intermediates = false,
    allow_as_intermediate = false,
    hide_from_stats = true,
    icons = {
        {icon = "__base__/graphics/icons/deconstruction-planner.png", icon_size = 64},
        {icon = building.icon, icon_size = building.icon_size} -- may need adjusting too
    },
    enabled = false
}

Both -manual and -undo recipes are automatically unlocked when their respective automatic and building recipes are.

Take note that some items in Satisfactorio are remapped automatically, notably:

  • Iron Stick => Iron Rod
  • Iron Gear Wheel => Screw
  • Copper Cable => Cable
  • Steel Plate => Steel Beam
  • Plastic Bar => Plastic
  • Advanced Circuit => High-speed Connector
  • Processing Unit => A.I. Limiter

Technology

Tech can be added using local addTech = require("prototypes.technology") - this gives a function:

addTech( techname, icon, category, subgroup, order, time, prerequisites, ingredients, effects)
  • techname: Must conform to type-name, where type is hub-tier#, space-elevator or mam-XXX (where XXX is the MAM subtree)
  • icon: Either a path relative to __Satisfactorio__/graphics/technology/ (eg. hub/factory) or a full path including mod name. The icon should be 256x256.
    * HUB techs should always use a hub/* icon. MAM techs should use the icon of the thing it unlocks
    Alternatively this can be a table containing {filename=..., size=...} if the size isn't 256x256
  • category: hub-progressing, space-elevator or mam as appropriate - this determines where the research takes place
  • subgroup: hub-tier#, space-parts or mam-XXX (same XXX as the techname)
  • order: Order of the tech. HUB techs use a-TIER-ORDER, Space Elevator uses e-PHASE and the MAM uses m-SUBTREE-ORDER
  • time: HUB cooldown or MAM research time. Unused by the Space Elevator
  • prerequisites: An array of technologies that must be researched first
  • ingredients: The items that must be submitted to the HUB/Elevator/MAM to begin this research
  • effects: The technology's effects (eg. unlock-recipe...)

addTech() returns a table consisting of {tool=..., recipe=..., recipe_done=..., technology=...} with the newly added components. These need a localised_name set.

local tech = addTech(...)
tech.tool.localised_name = data.raw.technology['thing-added-by-mod'].localised_name
tech.recipe.localised_name = tech.tool.localised_name
tech.recipe_done.localised_name = tech.tool.localised_name
tech.technology.localised_name = tech.tool.localised_name

Be sure to delete any techs added by the mod itself, as they will try to use Science Packs that aren't available in Satisfactorio.

Buildings

Due to the lack of inserters in Satisfactorio, any new buildings that receive input/output will need "loaders" adding to them. There currently isn't a hook for compatibility scripts in control-stage, but if/when it is added, loaders can be created as follows:

local io = require("scripts.lualib.input-output")
local function onBuilt(event)
    local entity = event.created_entity or event.entity
    if not entity or not entity.valid then return end
    if entity.name == "new-building" then -- set name here
        -- the vector here is where the input goes when the building is facing North
        -- it should be centred on a tile just inside the building's bounding box
        io.addInput(entity, {0,2})
        io.addOutput(entity, {0,-2})
        -- the resulting belts will be facing North too - this can be changed:
        -- io.addOutput(entity, {1,2}, entity, defines.direction.south)
        -- (the third parameter there is the "target" for more complex entities - just pass the base entity again)
    end
end
local function onRemoved(event)
    local entity = event.entity
    if not entity or not entity.valid then return end
    if entity.name == "new-building" then
        io.remove(entity, event)
    end
end
return {
    events = {
        [defines.events.on_built_entity] = onBuilt,
        [defines.events.on_robot_built_entity] = onBuilt,
        [defines.events.script_raised_built] = onBuilt,
        [defines.events.script_raised_revive] = onBuilt,

        [defines.events.on_player_mined_entity] = onRemoved,
        [defines.events.on_robot_mined_entity] = onRemoved,
        [defines.events.on_entity_died] = onRemoved,
        [defines.events.script_raised_destroy] = onRemoved
    }
}

Buildings should be modified to have max_health = 1 - this causes them to be indestructible, as all buildings in Satisfactory are.