Skip to main content

Crafting

A recipe is an asset. Crafting is one call. If the output does not fit, nothing is consumed.

The recipe

UEDCraftingRecipe is a data asset:

FieldMeaning
IngredientsDefinition ids and counts.
OutputA definition id and a count.
Required TagsOptional gate — a station, a learned skill.

Ingredients and output are referenced by FPrimaryAssetId, so a recipe holds no hard references and costs nothing to keep loaded.

Crafting

// Can it be crafted right now?
const bool bPossible = UEDCraftingStatics::CanCraft(Container, Recipe);

// Do it. Safe from a client: on the authority it runs now, otherwise it travels to the server.
UEDCraftingStatics::RequestCraft(Container, Recipe);
Can Craft      (Container, Recipe)  → Boolean
Request Craft (Container, Recipe)

RequestCraft runs one FEDCraftTransaction: ingredients consumed and output inserted in a single atomic step. If the output will not fit, the whole thing rolls back and the ingredients are still there. There is no state in which a player has paid and received nothing.

A recipe list that stays honest

CanCraft reads live container contents, so a UI can poll it — but the better pattern is to bind the container's change event and refresh:

Container->OnInventoryChanged.AddDynamic(this, &UMyCraftingPanel::HandleInventoryChanged);

Each row then shows its ingredients with have-counts, tinted by availability, and greys its button when CanCraft is false. The demo's UEDCraftingPanelWidget does exactly this and is worth reading as a worked example.

Stations

The framework has no station concept — a station is an actor in your game that decides which recipes to offer.

The usual shape: an actor holds a recipe list and an interaction opens a panel bound to the player's own container. Crafting consumes from the player's inventory, not from the station, because the container passed to RequestCraft is the one that pays.

To gate recipes by station, put a tag on the station and filter the list before showing it, or use the recipe's Required Tags.

Which container pays

Whichever one you pass. That is a real decision:

  • Pass the main grid and crafting spends only what is carried there.
  • Pass a container that spans more, or check the inventory first, if you want it to spend from anywhere.

The framework does not assume, because "can I craft from my bank?" is a design question with no universal answer.

Where next