Recycler Formula / Description

Anything related to the content on our wiki (https://wiki.factorio.com/)

Moderator: Bilka

Beechsack
Manual Inserter
Manual Inserter
Posts: 3
Joined: Fri Mar 22, 2019 12:07 pm
Contact:

Recycler Formula / Description

Post by Beechsack »

The wiki page for the Recycler currently contains the following :

Code: Select all

For each type of item used as an ingredient in the recycled item's main recipe, the number of items returned by the recycler is decided by 
⌊0.25 * i / o + r ], where i is the number of items used as ingredients, o is the number of items returned by the recipe, and r
is a random number that is greater than or equal to 0 but less than 1. On average, this returns exactly 25% of the items needed to craft one item of the same type as the recycled item. For example, recycling a processing unit always gives 5 electronic circuits while having a 50% chance of returning one advanced circuit.
This seemed a little off , so I played with the recycling LUA code a bit. This seems to be more in line with what is actually occurring.

To create the recipe used by the recycler:
  1. Check the recipe used to create the item. See how many items are created by one craft.
  2. Multiply this number by 4. ("final_probability")

    For every non-fluid ingredient used to create this item:
  3. Original count divided by final_probability = number returned.
  4. Original count MOD final_probability , to get a remainder. Remainder divided by final_probability = extra_fraction
The integer value of #3 is guaranteed to be returned, but #4 ends up being a value between 0-1, effectively a percentage. I would assume under the hood that the game just rolls a random number against extra_fraction to see if 1 more of that item is returned or not.

I believe this is important to spell out this more more accurately in the wiki.

Supporting test LUA outputs:

Code: Select all

multiplier [ number of items crafted by source recipe ] = 1
Looping through ingredients...
Checking ingredient : electronic-circuit
final_amount [number of this item in the source recipe ] = 20
final_probability [4 * multiplier ] = 4
remainder [ final_amount % final_probability ] = 0
(updated) final_amount [ original final_amount / final_probability ] = 5.0
final_extra_fraction [ remainder / final_probability ] = 0.0
Done with ingredient : electronic-circuit
Checking ingredient : advanced-circuit
final_amount [number of this item in the source recipe ] = 2
final_probability [4 * multiplier ] = 4
remainder [ final_amount % final_probability ] = 2
(updated) final_amount [ original final_amount / final_probability ] = 0.5
final_extra_fraction [ remainder / final_probability ] = 0.5
Done with ingredient : advanced-circuit
Checking ingredient : sulfuric-acid
Final recycling recipe for processing-unit : 
table: 0x55cdf86a3c90 {
  [subgroup] => "other"
  [category] => "recycling"
  [unlock_results] => false
  [type] => "recipe"
  [results] => table: 0x55cdf86a3c90 {
                 [1] => table: 0x55cdf869cdb0 {
                          [extra_count_fraction] => 0.0
                          [amount] => 5.0
                          [name] => "electronic-circuit"
                          [type] => "item"
                        }
                 [2] => table: 0x55cdf869cdb0 {
                          [extra_count_fraction] => 0.5
                          [amount] => 0.5
                          [name] => "advanced-circuit"
                          [type] => "item"
                        }
               }
  [allow_decomposition] => false
  [localised_name] => table: 0x55cdf86a3c90 {
                        [1] => "recipe-name.recycling"
                        [2] => "processing-unit"
                      }
  [name] => "processing-unit-recycling"
  [ingredients] => table: 0x55cdf86a3c90 {
                     [1] => table: 0x55cdf869cc90 {
                              [amount] => 1
                              [name] => "processing-unit"
                              [type] => "item"
                            }
                   }
  [energy_required] => 0.625
  [hidden] => true
}
=====
multiplier [ number of items crafted by source recipe ] = 1
Looping through ingredients...
Checking ingredient : radar
final_amount [number of this item in the source recipe ] = 1
final_probability [4 * multiplier ] = 4
remainder [ final_amount % final_probability ] = 1
(updated) final_amount [ original final_amount / final_probability ] = 0.25
final_extra_fraction [ remainder / final_probability ] = 0.25
Done with ingredient : radar
Checking ingredient : calcite
final_amount [number of this item in the source recipe ] = 1
final_probability [4 * multiplier ] = 4
remainder [ final_amount % final_probability ] = 1
(updated) final_amount [ original final_amount / final_probability ] = 0.25
final_extra_fraction [ remainder / final_probability ] = 0.25
Done with ingredient : calcite
Checking ingredient : tungsten-plate
final_amount [number of this item in the source recipe ] = 4
final_probability [4 * multiplier ] = 4
remainder [ final_amount % final_probability ] = 0
(updated) final_amount [ original final_amount / final_probability ] = 1.0
final_extra_fraction [ remainder / final_probability ] = 0.0
Done with ingredient : tungsten-plate
Checking ingredient : explosives
final_amount [number of this item in the source recipe ] = 8
final_probability [4 * multiplier ] = 4
remainder [ final_amount % final_probability ] = 0
(updated) final_amount [ original final_amount / final_probability ] = 2.0
final_extra_fraction [ remainder / final_probability ] = 0.0
Done with ingredient : explosives
Final recycling recipe for artillery-shell : 
table: 0x55cdf86a3c90 {
  [subgroup] => "other"
  [category] => "recycling"
  [unlock_results] => false
  [type] => "recipe"
  [results] => table: 0x55cdf86a3c90 {
                 [1] => table: 0x55cdf86a8290 {
                          [extra_count_fraction] => 0.25
                          [amount] => 0.25
                          [name] => "radar"
                          [type] => "item"
                        }
                 [2] => table: 0x55cdf86a8290 {
                          [extra_count_fraction] => 0.25
                          [amount] => 0.25
                          [name] => "calcite"
                          [type] => "item"
                        }
                 [3] => table: 0x55cdf86a8290 {
                          [extra_count_fraction] => 0.0
                          [amount] => 1.0
                          [name] => "tungsten-plate"
                          [type] => "item"
                        }
                 [4] => table: 0x55cdf86a8290 {
                          [extra_count_fraction] => 0.0
                          [amount] => 2.0
                          [name] => "explosives"
                          [type] => "item"
                        }
               }
  [allow_decomposition] => false
  [localised_name] => table: 0x55cdf86a3c90 {
                        [1] => "recipe-name.recycling"
                        [2] => "artillery-shell"
                      }
  [name] => "artillery-shell-recycling"
  [ingredients] => table: 0x55cdf86a3c90 {
                     [1] => table: 0x55cdf86a83a0 {
                              [amount] => 1
                              [name] => "artillery-shell"
                              [type] => "item"
                            }
                   }
  [energy_required] => 0.9375
  [hidden] => true
}
=====
multiplier [ number of items crafted by source recipe ] = 2
Looping through ingredients...
Checking ingredient : tungsten-plate
final_amount [number of this item in the source recipe ] = 40
final_probability [4 * multiplier ] = 8
remainder [ final_amount % final_probability ] = 0
(updated) final_amount [ original final_amount / final_probability ] = 5.0
final_extra_fraction [ remainder / final_probability ] = 0.0
Done with ingredient : tungsten-plate
Checking ingredient : express-underground-belt
final_amount [number of this item in the source recipe ] = 2
final_probability [4 * multiplier ] = 8
remainder [ final_amount % final_probability ] = 2
(updated) final_amount [ original final_amount / final_probability ] = 0.25
final_extra_fraction [ remainder / final_probability ] = 0.25
Done with ingredient : express-underground-belt
Checking ingredient : lubricant
Final recycling recipe for turbo-underground-belt : 
table: 0x55cdf86a3c90 {
  [subgroup] => "other"
  [category] => "recycling"
  [unlock_results] => false
  [type] => "recipe"
  [results] => table: 0x55cdf86a3c90 {
                 [1] => table: 0x55cdf86aa490 {
                          [extra_count_fraction] => 0.0
                          [amount] => 5.0
                          [name] => "tungsten-plate"
                          [type] => "item"
                        }
                 [2] => table: 0x55cdf86aa490 {
                          [extra_count_fraction] => 0.25
                          [amount] => 0.25
                          [name] => "express-underground-belt"
                          [type] => "item"
                        }
               }
  [allow_decomposition] => false
  [localised_name] => table: 0x55cdf86a3c90 {
                        [1] => "recipe-name.recycling"
                        [2] => "turbo-underground-belt"
                      }
  [name] => "turbo-underground-belt-recycling"
  [ingredients] => table: 0x55cdf86a3c90 {
                     [1] => table: 0x55cdf86aa4d0 {
                              [amount] => 1
                              [name] => "turbo-underground-belt"
                              [type] => "item"
                            }
                   }
  [energy_required] => 0.125
  [hidden] => true
}
=====
multiplier [ number of items crafted by source recipe ] = 1
Looping through ingredients...
Checking ingredient : steel-plate
final_amount [number of this item in the source recipe ] = 1000
final_probability [4 * multiplier ] = 4
remainder [ final_amount % final_probability ] = 0
(updated) final_amount [ original final_amount / final_probability ] = 250.0
final_extra_fraction [ remainder / final_probability ] = 0.0
Done with ingredient : steel-plate
Checking ingredient : concrete
final_amount [number of this item in the source recipe ] = 1000
final_probability [4 * multiplier ] = 4
remainder [ final_amount % final_probability ] = 0
(updated) final_amount [ original final_amount / final_probability ] = 250.0
final_extra_fraction [ remainder / final_probability ] = 0.0
Done with ingredient : concrete
Checking ingredient : pipe
final_amount [number of this item in the source recipe ] = 100
final_probability [4 * multiplier ] = 4
remainder [ final_amount % final_probability ] = 0
(updated) final_amount [ original final_amount / final_probability ] = 25.0
final_extra_fraction [ remainder / final_probability ] = 0.0
Done with ingredient : pipe
Checking ingredient : processing-unit
final_amount [number of this item in the source recipe ] = 200
final_probability [4 * multiplier ] = 4
remainder [ final_amount % final_probability ] = 0
(updated) final_amount [ original final_amount / final_probability ] = 50.0
final_extra_fraction [ remainder / final_probability ] = 0.0
Done with ingredient : processing-unit
Checking ingredient : electric-engine-unit
final_amount [number of this item in the source recipe ] = 200
final_probability [4 * multiplier ] = 4
remainder [ final_amount % final_probability ] = 0
(updated) final_amount [ original final_amount / final_probability ] = 50.0
final_extra_fraction [ remainder / final_probability ] = 0.0
Done with ingredient : electric-engine-unit
Final recycling recipe for rocket-silo : 
table: 0x55cdf86a3c90 {
  [subgroup] => "other"
  [category] => "recycling"
  [unlock_results] => false
  [type] => "recipe"
  [results] => table: 0x55cdf86a3c90 {
                 [1] => table: 0x55cdf86abbb0 {
                          [extra_count_fraction] => 0.0
                          [amount] => 250.0
                          [name] => "steel-plate"
                          [type] => "item"
                        }
                 [2] => table: 0x55cdf86abbb0 {
                          [extra_count_fraction] => 0.0
                          [amount] => 250.0
                          [name] => "concrete"
                          [type] => "item"
                        }
                 [3] => table: 0x55cdf86abbb0 {
                          [extra_count_fraction] => 0.0
                          [amount] => 25.0
                          [name] => "pipe"
                          [type] => "item"
                        }
                 [4] => table: 0x55cdf86abbb0 {
                          [extra_count_fraction] => 0.0
                          [amount] => 50.0
                          [name] => "processing-unit"
                          [type] => "item"
                        }
                 [5] => table: 0x55cdf86abbb0 {
                          [extra_count_fraction] => 0.0
                          [amount] => 50.0
                          [name] => "electric-engine-unit"
                          [type] => "item"
                        }
               }
  [allow_decomposition] => false
  [localised_name] => table: 0x55cdf86a3c90 {
                        [1] => "recipe-name.recycling"
                        [2] => "rocket-silo"
                      }
  [name] => "rocket-silo-recycling"
  [ingredients] => table: 0x55cdf86a3c90 {
                     [1] => table: 0x55cdf86abd30 {
                              [amount] => 1
                              [name] => "rocket-silo"
                              [type] => "item"
                            }
                   }
  [energy_required] => 1.875
  [hidden] => true
}
User avatar
DaveMcW
Smart Inserter
Smart Inserter
Posts: 3722
Joined: Tue May 13, 2014 11:06 am
Contact:

Re: Recycler Formula / Description

Post by DaveMcW »

The wiki formula does match what you are saying, though the math symbols make it hard to understand.

The topless brackets mean "round down to the nearest integer".

Adding a random number between 0-1 to extra_fraction and then rounding down, is the same as rolling a random number against extra_fraction.
Beechsack
Manual Inserter
Manual Inserter
Posts: 3
Joined: Fri Mar 22, 2019 12:07 pm
Contact:

Re: Recycler Formula / Description

Post by Beechsack »

Thanks for the note about the square brackets and floor function. That's not a notation I'd seen before.

I'd still put forth the formula is slightly inaccurate , since it states that the random(0,1) function occurs for EVERY item in the list, where it should not.

Take for example the basic firearm magazine. Original cost is 4 iron plates, 25% recycle return is 1. If this ever returned MORE than 1 plate back, it would be easy to make this iron plate positive, so it's a reasonable assumption that they don't.

IMO, the more correct way to state this is :

Code: Select all

i =  number of items originally used as ingredients 
o =  number of items returned by the original item recipe

For each non-fluid ingredient used to create an item:
amount_returned = ( .25 * ( i / o) ) 
if ( i mod o != 0 ) : 
	amount_returned += rand(0,1)
Post Reply

Return to “Wiki Talk”