Skip to main content

Cooking and processing

Some crafting is not a trade, it is a wait. UEDProcessingComponent turns one item into another over time while fuel burns: a furnace, a campfire, a smelter, a drying rack. You supply three slot tags and the recipes; the component does the rest, server-side.

Three slots, one container

A furnace's slots belong together — one panel to open, one thing to save, one thing to replicate — so they are three tagged slots of a single container using a Slot layout, not three containers.

// On an actor whose container has slots tagged Input / Fuel / Output.
Processor->InputSlot = MyTags::Slot_Input;
Processor->FuelSlot = MyTags::Slot_Fuel;
Processor->OutputSlot = MyTags::Slot_Output;
Processor->Recipes = { SmeltIron, CookMeat };

The component finds the container on its owner, or you can hand it one with SetContainer if the owner builds containers at runtime.

What burns, and what cooks

Both are data. The component never names an item.

AssetFieldMeaning
FEDFuelFragment (on the item)Burn SecondsHow long one unit keeps the fire alive
UEDCookingRecipeInputDefinition id and count consumed
OutputDefinition id and count produced
Cook SecondsHow long one item takes

UEDCraftingStatics::GetFuelSeconds(DefinitionId) answers what any item is worth as fuel, which is what a UI needs to grey out a fuel slot before the player drops a rock in it.

How it behaves, and why

SettingEffect
Burns Without InputWhether an empty chamber consumes fuel at all. false for a furnace, which should not waste coal on nothing; true for a campfire that is a fire first and a cooker second.
Speed MultiplierScales every recipe. A blast furnace is the same recipes, faster.
Progress Decay RateHow fast unfinished work cools when cooking stops, as a multiple of cooking speed.

Three rules make it read like the genre expects:

  • One unit of fuel at a time, and it burns to its end. Pulling the input out mid-burn does not snuff the fire; it just stops being useful. The next unit is consumed only when the last is spent.
  • Progress decays, it does not reset. Put the input back quickly and most of the progress is still there; dawdle and it is gone. Set the rate to zero to freeze progress instead.
  • The finished item leaves the input slot only when it is done. Until then it sits there cooking, which is what tells the player something is happening.

The component re-evaluates from the current contents every tick and holds no state machine, so pulling the input, filling the output or running dry all resolve themselves. There is no state to get stuck in.

Driving a UI

Only the server ticks the process and moves items, but the numbers a UI needs replicate, so a client draws live gauges without simulating anything:

Bar->SetPercent(Processor->GetCookFraction());   // the arrow filling
Flame->SetPercent(Processor->GetBurnFraction()); // the current unit of fuel depleting
Is Burning                       → Boolean
Get Cook Fraction → Float 0..1
Get Burn Fraction → Float 0..1
Get Burn Remaining → Seconds
On Burn Changed (bIsBurning) ⬤ every machine, at the transitions
On Produced (Recipe) ⬤ authority, per finished item

An output slot players cannot fill

A furnace's output is take-only, and that belongs in the layout rather than in UI code. Give the output slot an Accepted Tags entry naming a tag no item will ever carry: every player insert or move into it then fails the acceptance check on the server, wherever the attempt came from.

The machine still delivers there because its own transaction writes the slot address directly, exempt from the layout's filters. That exemption is the machine's alone — which is why the rule needs no special case anywhere else, and why a modified client cannot borrow it.

Where next