Custom assembling machine

Place to get help with not working mods / modding interface.
User avatar
Pearlseverance
Burner Inserter
Burner Inserter
Posts: 5
Joined: Fri Aug 22, 2025 9:54 pm
Contact:

Custom assembling machine

Post by Pearlseverance »

I made a custom assembling machine that is supposed to craft an item that utilizes control.lua to randomize the output using a "dummy" item.

I want the randomization result to be weighted, with a 95% chance of crafting one item, and a 5% chance of crafting the other.

The problem is, I cannot get the dummy item to be replaced by the expected resulting items. I did use Google for help, so I do not understand what is wrong with my code.
The other problem is I cannot make the machine itself to appear on the screen.. as in, the sprite doesn't show, or is invisible. The item being produced is fine, however.

I can send the data.lua and control.lua for debugging purposes.

Code: Select all

data:extend(
{
  {
    type = "item",
    name = "shape-triangle",
    icon = "__TriangleFactory__/graphics/icons/triangle-icon.png",
	icon_size = 64,
    subgroup = "raw-material", -- Or a new subgroup, or an existing one
    order = "z[shape-item]",
    stack_size = 99,
	pictures = {
	{size = 64, filename = "__TriangleFactory__/graphics/icons/triangle1.png", scale = 0.5, mipmap_count = 1},
	{size = 64, filename = "__TriangleFactory__/graphics/icons/triangle2.png", scale = 0.5, mipmap_count = 1},
	{size = 64, filename = "__TriangleFactory__/graphics/icons/triangle3.png", scale = 0.5, mipmap_count = 1},
	{size = 64, filename = "__TriangleFactory__/graphics/icons/triangle4.png", scale = 0.5, mipmap_count = 1}
	}
  }
})
data:extend(
{
  {
    type = "item",
    name = "shape-circle",
    icon = "__TriangleFactory__/graphics/icons/circle-icon.png",
	icon_size = 64,
    subgroup = "raw-material", -- Or a new subgroup, or an existing one
    order = "z[shape-item]",
    stack_size = 99,
	pictures = {
	{size = 64, filename = "__TriangleFactory__/graphics/icons/circle1.png", scale = 0.5, mipmap_count = 1},
	{size = 64, filename = "__TriangleFactory__/graphics/icons/circle2.png", scale = 0.5, mipmap_count = 1},
	{size = 64, filename = "__TriangleFactory__/graphics/icons/circle3.png", scale = 0.5, mipmap_count = 1},
	{size = 64, filename = "__TriangleFactory__/graphics/icons/circle4.png", scale = 0.5, mipmap_count = 1}
	}
  }
})
data:extend(
{
  {
    type = "item",
    name = "placeholder-shape",
    icon = "__TriangleFactory__/graphics/icons/triangle-icon.png",
	icon_size = 64,
    subgroup = "raw-material", -- Or a new subgroup, or an existing one
    order = "z[shape-item]",
    stack_size = 1
  }
})
data:extend(
{
  {
    type = "item",
    name = "triangle-assembler-item",
    icon = "__base__/graphics/icons/assembling-machine-2.png",
	icon_size = 64,
    subgroup = "production-machine", -- Or a new subgroup, or an existing one
    order = "z[shape-item]",
    stack_size = 99,
	place_result = "triangle-assembler"
  }
})
-- Define a new recipe category
data:extend(
{
  {
    type = "recipe-category",
    name = "random-shape-crafting"
  }
})

data:extend(
{
  {
    type = "recipe-category",
    name = "trianglemaker-crafting"
  }
})

-- Define the custom assembling machine
data:extend(
{
  {
    type = "assembling-machine",
    name = "triangle-assembler",
    icon = "__base__/graphics/icons/assembling-machine-2.png",
    icon_size = 64,
    flags = {"placeable-neutral", "placeable-player", "player-creation"},
    minable = {hardness = 0.2, mining_time = 0.5, result = "triangle-assembler-item"},
    max_health = 300,
    corpse = "small-remnants",
    collision_box = {{-1.2, -1.2}, {1.2, 1.2}},
    selection_box = {{-1.5, -1.5}, {1.5, 1.5}},
    fast_replaceable_group = "assembling-machine",
    crafting_speed = 1.0,
    crafting_categories = {"random-shape-crafting"},
    energy_usage = "150kW",
    energy_source =
    {
      type = "electric",
      emissions = 0.05,
      usage_priority = "secondary-input"
    },
     animation = {
      layers = {
        {
          filename = "__TriangleFactory__/graphics/entity/triangle-assembler/triangle-assembler.png",
          width = 64,
          height = 64,
          frame_count = 1,
          shift = {0, 0}
        },
        {
          filename = "__TriangleFactory__/graphics/entity/triangle-assembler/triangle-assembler.png",
          tint = {r=0.0, g=0.0, b=0.0}, -- Change tint to show it's a special machine
          width = 64,
          height = 64,
          frame_count = 1,
          shift = {0, 0}
        }
      }
    },
    module_inventory_size = 2,
    working_visualisations = {
      {
        filename = "__TriangleFactory__/graphics/entity/triangle-assembler/triangle-assembler.png",
        width = 128,
        height = 128,
        frame_count = 4,
        line_length = 2,
        animation_speed = 1,
        shift = {0.2, 0.05}
      }
    },
    vehicle_impact_sound =  { filename = "__base__/sound/car-metal-impact.ogg", volume = 0.65 },
    open_sound = { filename = "__base__/sound/machine-open.ogg", volume = 0.85 },
    close_sound = { filename = "__base__/sound/machine-close.ogg", volume = 0.85 }
  }
 }
)

-- Define the recipe with a placeholder result
data:extend(
{
  {
    type = "recipe",
    name = "shape-recipe",
    category = "random-shape-crafting",
    ingredients = {
	{
      type = "item",
      name = "steel-plate",
      amount = 3
    },
    {
      type = "item",
      name = "copper-plate",
      amount = 3
    },
	},
    results = {
      {type= "item", name = "placeholder-shape", probability=1, amount_min=1, amount_max=1}
    },
    enabled = true,
	auto_recycle = false
  }
})
-- Shape Assembly recipe
data:extend(
{
  {
    type = "recipe",
    name = "triangle-assembler-recipe",
    category = "crafting",
	ingredients = {
	{
      type = "item",
      name = "steel-plate",
      amount = 4
    },
    {
      type = "item",
      name = "copper-plate",
      amount = 5
    },
	{
      type = "item",
      name = "electronic-circuit",
      amount = 3
    },
	{
      type = "item",
      name = "engine-unit",
      amount = 3
    },
	},
    results = {
      {type= "item", name = "triangle-assembler-item", probability=1, amount_min=1, amount_max=1}
    },
    enabled = true,
	auto_recycle = false
  }
})

Code: Select all

-- Store your weighted random outcomes in a global variable
global = {}
global.random_outcomes = {
  { name = "shape-triangle", count = 1, weight = 95 }, -- 95% chance
  { name = "shape-circle", count = 1, weight = 5 } -- 5% chance
}

-- The total weight is used to get a random number
global.total_weight = 0
for _, outcome in ipairs(global.random_outcomes) do
  global.total_weight = global.total_weight + outcome.weight
end

-- Function to pick a random item based on weights
local function get_random_item()
  local random_roll = math.random(1, global.total_weight)
  local cumulative_weight = 0
  
  for _, outcome in ipairs(global.random_outcomes) do
    cumulative_weight = cumulative_weight + outcome.weight
    if random_roll == 0 and progress == 0 then
        -- We can be sure a craft just finished
        
        -- Get the machine's output inventory
        local output_inventory = entity.get_output_inventory()

        if output_inventory then
          -- Get a random outcome
          local result = get_random_outcomes()
          
          -- Remove the placeholder item (if any) and insert the new item
          output_inventory.insert(result)
          
          -- Log the outcome for debugging
          game.print("Triangle Assembler created: " .. result.count .. " " .. result.name)
        end
      end
      
      data.last_progress = progress
    end
      -- Clean up invalid entities
      global.tracked_assemblers[unit_number] = nil
end
eugenekay
Filter Inserter
Filter Inserter
Posts: 657
Joined: Tue May 15, 2018 2:14 am
Contact:

Re: Custom assembling machine

Post by eugenekay »

Pearlseverance wrote: Fri Aug 22, 2025 10:04 pmI want the randomization result to be weighted, with a 95% chance of crafting one item, and a 5% chance of crafting the other.
That seems like an awful lot of custom Lua Control code. Is there a reason that the built-in probability factor of the ItemProductPrototype does not work for your use case?

For example, uranium-processing has a 0.7% chance to produce Uranium-235 vs Uranium-238:

Code: Select all

  {
    type = "recipe",
    name = "uranium-processing",
    energy_required = 12,
    enabled = false,
    auto_recycle = false,
    category = "centrifuging",
    ingredients = {{type = "item", name = "uranium-ore", amount = 10}},
    icon = "__base__/graphics/icons/uranium-processing.png",
    subgroup = "uranium-processing",
    order = "a[uranium-processing]-a[uranium-processing]",
    results =
    {
      {
        type = "item",
        name = "uranium-235",
        probability = 0.007,
        amount = 1
      },
      {
        type = "item",
        name = "uranium-238",
        probability = 0.993,
        amount = 1
      }
    },
    allow_productivity = true
  },
Good Luck!
User avatar
Pearlseverance
Burner Inserter
Burner Inserter
Posts: 5
Joined: Fri Aug 22, 2025 9:54 pm
Contact:

Re: Custom assembling machine

Post by Pearlseverance »

Like I said. I was too shy to ask for help on the forums before.... So I asked Google and it gave me a bunch of jank I suppose!

Thank you for the new insight.
User avatar
Pearlseverance
Burner Inserter
Burner Inserter
Posts: 5
Joined: Fri Aug 22, 2025 9:54 pm
Contact:

Re: Custom assembling machine

Post by Pearlseverance »

eugenekay wrote: Fri Aug 22, 2025 10:24 pm
Pearlseverance wrote: Fri Aug 22, 2025 10:04 pmI want the randomization result to be weighted, with a 95% chance of crafting one item, and a 5% chance of crafting the other.
That seems like an awful lot of custom Lua Control code. Is there a reason that the built-in probability factor of the ItemProductPrototype does not work for your use case?

For example, uranium-processing has a 0.7% chance to produce Uranium-235 vs Uranium-238:

Code: Select all

  {
    type = "recipe",
    name = "uranium-processing",
    energy_required = 12,
    enabled = false,
    auto_recycle = false,
    category = "centrifuging",
    ingredients = {{type = "item", name = "uranium-ore", amount = 10}},
    icon = "__base__/graphics/icons/uranium-processing.png",
    subgroup = "uranium-processing",
    order = "a[uranium-processing]-a[uranium-processing]",
    results =
    {
      {
        type = "item",
        name = "uranium-235",
        probability = 0.007,
        amount = 1
      },
      {
        type = "item",
        name = "uranium-238",
        probability = 0.993,
        amount = 1
      }
    },
    allow_productivity = true
  },
Good Luck!
This recipe code indeed works for me. I removed the control.lua and nearly everything is perfect now. I only now need to find out why my machine is invisible.

It is a 128x128 image split into four 64 pixel frames... Not actually sure how I am supposed to get the machine to show up in this instance, but I tried using my experience in modding other games to help me.
User avatar
Pearlseverance
Burner Inserter
Burner Inserter
Posts: 5
Joined: Fri Aug 22, 2025 9:54 pm
Contact:

Re: Custom assembling machine

Post by Pearlseverance »

I added the priority code and the missing "graphics_set = " line to the machine code and now the image shows up. Everything is good in the Triangle Factory now.

This can be marked as SOLVED!

Image
Post Reply

Return to “Modding help”