Passive Crafting

Passive crafting adds a new WorldObjectComponent that can be added to any WorldObject in order to provide the ability for the object to generate items passively over time.


using Eco.EM.ModkitTools;

To Use the Passive Crafting Component you need to add it too your WorldObject as an Attribute, But the Passive Crafting also has a Component Pre-Requisite, below we show you how to use it and a bit of an idea on how it will work.

Passive Crafting Attribute:

The Passive Crafting Component requires the public storage component as well


In the PostInitialize() method of the WorldObject.

Initialize component with outputs for generation

var pcc = GetComponent<PassiveCraftingComponent>
pcc.Initialize( {Int: TimePerCraft}, new List<(Item,float)>() 
{ (Item:Item1, Int:Amount1),(Item:Item2,Int:Amount2)} );
//*pseudo code only

Optionally add conditions

pcc.AddCraftCondition(new CraftCondition));

//*pseudo code only

Crafting conditions allow you to create your own requirements that must exist before the passive craft should be allowed to happen. CraftingConditions implements the interface IPassiveCraftCondition.

public interface IPassiveCraftCondition
string FailString { get; } // the string returned should this condition fail, for use in a status message
bool AllowCraft(); // The condition for crafting to proceed
void OnCraft(); // Call back for post-effects if craft is successful

The PassiveCraftComponent invokes an Action “OutputCrafted” that is invoked when the component successfully crafts an item which can be subscribed to in the craft condition and be used for after effects of the craft.

Currently EM-Framework provides two PassiveCraftConditions for use:


This condition requires the WorldObject to have a link component to additional storages.

This Condition will check storages nearby for input ingredients and consume them for the craft event. Passive crafters are unable to benefit from a player's talents or skills and hence will always use the maximum number of items rounded up for a craft.

The IngredientCraftCondition can be added by a special overloaded Initialize() method for the PassiveCraftingComponent which automatically sets the ingredients and outputs.

var pcc = GetComponent<PassiveCraftingComponent>();
RecipeFamily.Get(typeof(RecipeFamilyName)).DefaultRecipe );

This condition will check the surrounding area of the WorldObject for a desired Plant Block and will only craft if the block is found in sufficient numbers.

new PlantAreaCraftCondition(
this, //passing the worldobject to be used
Int: RadiusToCheck,
Int: NumberRequiredToBeFound,
new Type[] { typeof(Block:PlantBlock) }));
Example Object BeeBox

Produces Beeswax & Honey

Condition for production, 5 Sunflowers planted around the WorldObject in a radius of 10 blocks.

[RequireComponent(typeof(PassiveCraftingComponent))]    // Ensure component is attached to the object
[RequireComponent(typeof(PublicStorageComponent))]      // Needs public storage to have something to output items to
public partial class ResidentialBeeBoxObejct: WorldObject, IRepresentsItem
    public override LocString DisplayName => Localizer.DoStr("Residential Bee Hive");

    public Type RepresentedItemType => typeof(ResidentialBeeBoxItem);

    protected override void PostInitialize()
        // Initialize public storage with slots and restrictions
        var storage = GetComponent<PublicStorageComponent>();
        storage.Inventory.AddInvRestriction(new SpecificItemTypesRestriction(new Type[] { typeof(BeeswaxItem), typeof(HoneyItem) }));
        storage.Inventory.AddInvRestriction(new StackLimitRestriction(20));

        // Initialize component with outputs and conditions for generation (see API for list)
        var pcc = GetComponent<PassiveCraftingComponent>();
        pcc.Initialize(15, new List<(Item,float)>() 
            { (Item.Get(typeof(BeeswaxItem)), 1), (Item.Get(typeof(HoneyItem)), 1) });
        pcc.AddCraftCondition(new PlantAreaCraftCondition(this, 5, 10, new Type[] { typeof(SunflowerBlock) }));

    static ResidentialBeeBoxObejct()
        WorldObject.AddOccupancy<ResidentialBeeBoxObejct>(new List<BlockOccupancy>()
            { new BlockOccupancy(new Vector3i(0, 0, 0)) });