Crafting reference
The crafter, recipe book, crafting skills and station components, the recipe, category, station and skill assets, and the effect that teaches a recipe. For how to use it, see Crafting.
VtUnitCrafter
Component. Add it with Add Component → Vantage → Crafting → VtUnitCrafter.
Per-unit crafter — validates recipes, consumes ingredients, produces outputs, grants skill XP, drives the timed-craft state machine. The crafting actor.
Scripting API
| Member | Description |
|---|---|
bool IsCrafting { get; } |
True when a timed craft is currently in flight. |
VtRecipeDefinition CurrentRecipe { get; } |
The recipe currently being crafted, or null when idle. |
float CurrentProgress01 { get; } |
Progress of the current timed craft as a 0..1 fraction. 0 when idle. |
float CurrentRemainingSeconds { get; } |
Seconds remaining on the current timed craft. 0 when idle. |
IVtCostSource CostSource { get; } |
Where ingredients are taken from: the source set with SetCostSource, else the VtSharedStash that serves this unit, else its own bag. Tools in Required Items are always checked in the unit’s own bag. The crafted item goes where the recipe’s VtRecipeDefinition.outputDestination says. A timed craft pays when it finishes, from the source chosen when it started, even if the unit has since left a stash’s zone; when that source no longer holds the ingredients, or the stash was disabled, the craft fails with VtCraftFailureReason.MissingIngredients and produces nothing. |
event Action<VtRecipeDefinition> OnCraftStarted |
Fires when a craft begins — instant or timed. Args: the recipe. Subscribers spawn the craft-bar UI / play start animation. |
event Action<VtRecipeDefinition, float> OnCraftProgress |
Fires every Update tick while a timed craft is in flight. Args: (recipe, progress01) where progress01 is 0..1. Skipped for instant crafts (they fire Started + Completed in one tick). |
event Action<VtRecipeDefinition> OnCraftCompleted |
Fires after a craft successfully completes (instant or timed). At this point ingredients are consumed, output is granted, XP is credited. Args: the recipe. |
event Action<VtRecipeDefinition> OnCraftCancelled |
Fires when a timed craft is cancelled before completion. Args: the recipe. No consume / produce / XP grant. |
event Action<VtRecipeDefinition, VtCraftFailureReason> OnCraftFailed |
Fires when a TryCraft call refuses. Args: (recipe, reason). Recipe may be null when reason is VtCraftFailureReason.RecipeNull. |
void Initialize() |
Cache sibling components. Idempotent — safe to call any number of times. Public for the late-attach contract. |
void SetCostSource(IVtCostSource source) |
Take ingredients from source, such as a pool of your own. Null goes back to the default choice described on CostSource. |
bool IsAvailable(VtRecipeDefinition recipe, VtCraftingStation station, out VtCraftFailureReason reason) |
Run every prereq for recipe at station, including standing within the station’s interact radius. Returns true + VtCraftFailureReason.None when the recipe is craftable; returns false + the first failing reason otherwise. Pure query — never mutates. |
bool TryCraft(VtRecipeDefinition recipe, VtCraftingStation station, out VtCraftFailureReason reason) |
Start crafting recipe at station. Instant recipes (craftSeconds == 0) execute immediately. Timed recipes start a per-frame Update countdown; the crafter fires OnCraftStarted + OnCraftProgress while in flight, then OnCraftCompleted + consume + produce + XP grant when remainingSeconds hits 0. Returns true on accept, false + populated reason on refusal (also fires OnCraftFailed). |
bool CancelCraft() |
Cancel the active timed craft. No-op when idle. Returns false when nothing was crafting; true on cancel. Fires OnCraftCancelled; no consume / produce / XP grant. |
void ApplyCraftStateFromNet(VtRecipeDefinition active, float remaining) |
Net-replication entry point. Mirrors the authority’s active timed-craft state. Bypasses the authority gate. Fires OnCraftStarted when starting fresh, OnCraftCancelled when the active recipe is cleared. |
void Tick(float deltaTime) |
Advance the active timed craft by deltaTime seconds; completes it (consume, produce, XP, OnCraftCompleted) once the timer drains. Authority-only. The only time input this component consumes; Update forwards Time.deltaTime. |
VtUnitRecipeBook
Component. Add it with Add Component → Vantage → Crafting → VtUnitRecipeBook.
Per-unit recipe book — tracks the explicitly-learned recipes for the holder. Recipes with VtRecipeDefinition.learnedByDefault = true don’t need to be in the book; they’re always considered learned. The book stores only the rare / quest-locked / scroll-taught recipes.
Scripting API
| Member | Description |
|---|---|
IReadOnlyCollection<VtRecipeDefinition> LearnedRecipes { get; } |
Live read-only view of every explicitly-learned recipe. Does NOT include VtRecipeDefinition.learnedByDefault recipes — query IsLearned for the combined check. |
event Action<VtRecipeDefinition> OnRecipeLearned |
Fires after a recipe is added to the book via Learn. Args: the learned recipe. |
event Action<VtRecipeDefinition> OnRecipeForgotten |
Fires after a recipe is removed via Forget. Args: the forgotten recipe. |
void Initialize() |
Idempotent init for the late-attach contract — no per-instance state to seed, but the contract is uniform across the package. |
bool IsLearned(VtRecipeDefinition recipe) |
True when the recipe is craftable from a learning perspective: it’s VtRecipeDefinition.learnedByDefault OR has been explicitly learned. Other prereqs (level, skill, ingredients) are checked separately by VtUnitCrafter.IsAvailable. |
bool Learn(VtRecipeDefinition recipe) |
Add a recipe to the book. Authority-gated. Returns false if null, already learned, or replica side. Fires OnRecipeLearned on success. |
bool Forget(VtRecipeDefinition recipe) |
Remove a recipe from the book — admin / quest-flow. Authority-gated. Returns false if null or not learned. Fires OnRecipeForgotten on success. |
void ApplyRecipeBookFromNet(IReadOnlyList<VtRecipeDefinition> snapshot) |
Net-replication entry point. Replaces the learned set with the authoritative snapshot. Bypasses the authority gate. Fires OnRecipeLearned / OnRecipeForgotten only for entries whose presence actually differs from before the mirror. |
VtUnitCraftingSkills
Component. Add it with Add Component → Vantage → Crafting → VtUnitCraftingSkills.
Per-unit crafting-skill ledger — one (level, xp) state per VtCraftingSkillDefinition the holder progresses on. Mirrors VtUnitLevel in shape but tracks N independent skills instead of one global level.
Scripting API
| Member | Description |
|---|---|
event Action<VtCraftingSkillDefinition, int, int> OnSkillLeveledUp |
Fires once after every AddXp / SetLevel call that produces at least one level-up. Args: (skill, oldLevel, newLevel). Multi-level jumps fire once with the full old → new range. |
event Action<VtCraftingSkillDefinition, int, int, int> OnSkillXpChanged |
Fires after any mutation to a skill’s XP, AFTER any level-ups. Args: (skill, currentLevel, currentXp, xpToNext). Use for skill-bar UI. |
void Initialize() |
Idempotent init for the late-attach contract. |
void CopySnapshotTo(List<VtCraftingSkillSnapshot> target) |
Append one snapshot per skill the holder has progressed on. Used by save and replication. |
int GetLevel(VtCraftingSkillDefinition skill) |
Current level in skill. Returns 1 for skills the holder hasn’t progressed on yet — every player implicitly starts at level 1 in every skill. |
int GetXp(VtCraftingSkillDefinition skill) |
Accumulated XP toward the next level in skill. Always less than GetXpToNextLevel. |
int GetXpToNextLevel(VtCraftingSkillDefinition skill) |
XP needed to advance from GetLevel to the next level. 0 when the skill is at its VtCraftingSkillDefinition.maxLevel or the curve is missing. |
bool IsMaxLevel(VtCraftingSkillDefinition skill) |
True when the skill is at VtCraftingSkillDefinition.maxLevel. |
void AddXp(VtCraftingSkillDefinition skill, int amount) |
Credit XP to a skill. Authority-gated. Drains through the curve thresholds, firing OnSkillLeveledUp once per AddXp call that crosses any level boundary (multi-level jumps fire one event with the full range). |
void SetLevel(VtCraftingSkillDefinition skill, int level) |
Force-set a skill’s level. Authority-gated. Resets XP to 0. Used by save-restore, admin commands, mentor systems. |
void Reset(VtCraftingSkillDefinition skill) |
Wipe a skill’s XP back to 0 but keep current level. Authority-gated. |
void ApplySkillsFromNet(IReadOnlyList<VtCraftingSkillSnapshot> snapshot) |
Net-replication entry point. Replaces every skill’s state with the authoritative snapshot. Bypasses the authority gate. Fires OnSkillLeveledUp for skills whose level changed and OnSkillXpChanged for skills whose XP changed. |
VtCraftingStation
Component. Add it with Add Component → Vantage → Crafting → VtCraftingStation.
Scene-placed crafting station — anvil, alchemy table, cookpot, etc. Players reach it through the normal right-click, walk-to and interact flow, with no extra input wiring.
Inspector fields
| Field | Type | Default | Range | Description |
|---|---|---|---|---|
Station Type (stationType) |
VtRecipeStationDefinition | None | Station type — recipes that require this type can be crafted while interacting with this station. Required. | |
Interact Radius (interactRadius) |
float |
3 | ≥ 0 | Distance (world units) within which the player can interact with this station. The walk-to-pickup flow stops here. |
Scripting API
| Member | Description |
|---|---|
event Action<VtUnit, VtRecipeStationDefinition> OnStationOpened |
Fires when a player successfully interacts with this station. Args: (player, stationType). Consumer UI subscribes to render the recipe-list window filtered by stationType. |
void Initialize() |
Cache the sibling VtUnit. Idempotent — safe to call any number of times. Public for the late-attach contract. |
VtRecipeDefinition
Asset. Create it with Create → Vantage → Crafting → Recipe Definition.
Authored crafting recipe: what it consumes and produces, where and how long it takes, and who may craft it. A unit crafts it through its VtUnitCrafter.
Inspector fields
General
| Field | Type | Default | Range | Description |
|---|---|---|---|---|
Id (id) |
string |
Empty | Stable string identifier for DB / network payloads. Convention: ‘recipe.. |
|
Display Name (displayName) |
string |
Empty | UI display name shown in the recipe-list window. | |
Description (description) |
string |
Empty | Recipe description shown in the crafting UI tooltip. | |
Icon (icon) |
Sprite |
None | Icon for the recipe list. Optional; a list usually shows the output item’s icon when this is empty. | |
Icon Id (iconId) |
string |
Empty | Name of an icon from the package’s icon set (VtIcons), used when Icon is empty. Optional. | |
Sort Weight (sortWeight) |
int |
0 | Order within its category: lower comes first. Recipes with the same weight keep their list order. |
Classification
| Field | Type | Default | Range | Description |
|---|---|---|---|---|
Category (category) |
VtRecipeCategoryDefinition | None | Recipe category — drives recipe-list UI sort + tinting. Optional — null categorizes the recipe as ‘uncategorized’. | |
Station (station) |
VtRecipeStationDefinition | None | Required station type. Null = craft anywhere (no station required). Non-null = the player must be interacting with a VtCraftingStation whose stationType matches this reference. |
Inputs & Output
| Field | Type | Default | Range | Description |
|---|---|---|---|---|
Inputs (inputs) |
VtRecipeIngredient[] | Empty | Ingredients consumed on a successful craft. Every entry must be in the crafter’s cost source in the listed count before TryCraft accepts: its own bag, or the shared stash that pays for it. On completion they’re removed. | |
Output (output) |
VtRecipeOutput | — | Item produced on a successful craft. | |
Output Destination (outputDestination) |
VtCraftOutputDestination | CrafterBag |
Crafter Bag puts the output in the crafter’s bag. Cost Source puts it back where the ingredients came from: the shared stash when one paid, else the crafter’s bag. Use Cost Source for materials made from materials. | |
Craft Seconds (craftSeconds) |
float |
0 | ≥ 0 | How long the craft takes, in seconds. 0 = instant (consume + produce same frame). > 0 = timed; the crafter fires Started / Progress(t) / Completed events. One craft active at a time per crafter; consumer wires queueing if needed. |
Prerequisites
| Field | Type | Default | Range | Description |
|---|---|---|---|---|
Required Level (requiredLevel) |
int |
0 | ≥ 0 | Minimum holder level. 0 = no level gate. Checked against VtUnitLevel.Level; units without a level component are treated as level 1. |
Required Completed Quests (requiredCompletedQuests) |
VtQuestDefinition[] | Empty | Quests that must be in the TurnedIn state before this recipe becomes craftable. Empty = no quest gate. | |
Required Items (requiredItems) |
VtRecipeIngredient[] | Empty | Items the crafter MUST hold to use this recipe but that AREN’T consumed (Crafter’s Tools, Hammer, Recipe Book reagent). Distinguished from inputs[] which ARE consumed. Empty = no required-tool gate. | |
Required Unlock (requiredUnlock) |
VtUnlockDefinition | None | Unlock that must be owned, by the crafter or the shared stash that pays for it. Empty = no unlock gate. |
Skill Gate
| Field | Type | Default | Range | Description |
|---|---|---|---|---|
Required Skill (requiredSkill) |
VtCraftingSkillDefinition | None | Crafting skill this recipe requires. Optional — null = no skill gate (and no XP grant on completion). | |
Required Skill Level (requiredSkillLevel) |
int |
0 | ≥ 0 | Minimum level in the requiredSkill. 0 = any level passes; ignored when requiredSkill is null. |
Unlock & Reward
| Field | Type | Default | Range | Description |
|---|---|---|---|---|
Learned By Default (learnedByDefault) |
bool |
On | If true, every player can craft this recipe by default (no Learn step required). If false, the recipe must be added to the player’s VtUnitRecipeBook first — typically by consuming a recipe-scroll item with VtLearnRecipeEffect. | |
Xp Grant (xpGrant) |
int |
10 | ≥ 0 | XP credited to requiredSkill on a successful craft. Ignored when requiredSkill is null. Set to 0 to skip the XP grant. |
VtRecipeCategoryDefinition
Asset. Create it with Create → Vantage → Crafting → Recipe Category.
Authored recipe category — Weapons / Consumables / Food / Engineering / custom. Each VtRecipeDefinition references one category; the category drives UI sort order, tinting, and any consumer-side feature gating (filter the recipe-list window by category tab). Asset-per-tier and consumer-extensible — same shape as VtItemRarityDefinition / VtQuestCategoryDefinition.
Inspector fields
| Field | Type | Default | Description |
|---|---|---|---|
Id (id) |
string |
Empty | Stable string identifier for DB / network payloads. Convention: ‘recipe.category.weapons’, ‘recipe.category.consumables’. Required. |
Display Name (displayName) |
string |
Empty | UI display name. E.g. ‘Weapons’, ‘Consumables’, ‘Food’. |
Description (description) |
string |
Empty | Designer-facing description. Doesn’t affect runtime. |
Sort Weight (sortWeight) |
int |
0 | Sort priority for recipe-list UI ordering. Lower = appears first. Convention: Weapons 0, Consumables 100, Food 200, Engineering 300. Leave gaps for inserts. |
Color (color) |
Color |
#FFFFFFFF |
UI tint applied to the recipe’s name / category label in the crafting window. |
Icon (icon) |
Sprite |
None | Optional category icon shown in the recipe-list UI. Null for no icon. |
Icon Id (iconId) |
string |
Empty | Name of an icon from the package’s icon set (VtIcons), used when Icon is empty. Optional. |
VtRecipeStationDefinition
Asset. Create it with Create → Vantage → Crafting → Recipe Station.
Authored crafting-station type — Anvil / AlchemyTable / Cookpot / custom. Pure marker: no behavior, just an identity. Recipes tag a station type via VtRecipeDefinition.station; VtCraftingStation instances on scene-placed entities declare their type; the crafter matches them on VtUnitCrafter.TryCraft.
Inspector fields
| Field | Type | Default | Description |
|---|---|---|---|
Id (id) |
string |
Empty | Stable string identifier for DB / network payloads. Convention: ‘station.anvil’, ‘station.alchemy_table’. Required. |
Display Name (displayName) |
string |
Empty | UI display name. E.g. ‘Anvil’, ‘Alchemy Table’, ‘Cookpot’. |
Description (description) |
string |
Empty | Designer-facing description. Doesn’t affect runtime. |
Icon (icon) |
Sprite |
None | Optional station icon for crafting-window header. Null for no icon. |
VtCraftingSkillDefinition
Asset. Create it with Create → Vantage → Crafting → Crafting Skill.
Authored crafting skill — Smithing / Alchemy / Cooking / Engineering / custom. Each skill is its own progression track on VtUnitCraftingSkills; recipes can require a minimum level in a specific skill, and successful crafts grant XP to the recipe’s skill via VtRecipeDefinition.xpGrant.
Inspector fields
| Field | Type | Default | Range | Description |
|---|---|---|---|---|
Id (id) |
string |
Empty | Stable string identifier for DB / network payloads. Convention: ‘skill.smithing’, ‘skill.alchemy’. Required. | |
Display Name (displayName) |
string |
Empty | UI display name. E.g. ‘Smithing’, ‘Alchemy’, ‘Cooking’. | |
Description (description) |
string |
Empty | Designer-facing description. | |
Sort Weight (sortWeight) |
int |
0 | Sort priority for skill-list UI ordering. Lower = appears first. | |
Icon (icon) |
Sprite |
None | Optional skill icon for the skill-list UI. | |
Color (color) |
Color |
#FFFFFFFF |
UI tint applied to the skill’s name in the crafting / skills windows. Default white. | |
Xp Curve (xpCurve) |
VtXpCurveDefinition | None | XP-to-next-level curve, the same asset type characters level on. Share one curve across skills, or give a skill its own for different pacing. Required. | |
Max Level (maxLevel) |
int |
60 | ≥ 1 | Maximum level reachable on this skill. AddXp at maxLevel drops excess silently. Should usually mirror the curve’s maxLevel. |
VtLearnRecipeEffect
Asset. Create it with Create → Vantage → Abilities → Effects → Learn Recipe. Inherits VtAbilityEffect.
Ability effect: add a VtRecipeDefinition to the caster’s VtUnitRecipeBook on cast. The mechanism behind recipe-scroll items — author a recipe scroll as a regular VtItemDefinition with consumeOnUse = true and a one-effect useAbility that contains this effect; using the scroll learns the recipe and disposes the scroll.
Inspector fields
| Field | Type | Default | Description |
|---|---|---|---|
Recipe (recipe) |
VtRecipeDefinition | None | Recipe added to the caster’s recipe book on cast. Required — effect silently no-ops if null. |
Scripting API
| Member | Description |
|---|---|
override void Execute(in VtAbilityContext ctx) |
Adds recipe to the caster’s VtUnitRecipeBook. Does nothing when the caster has no recipe book. |
VtRecipeIngredient
Serializable struct.
One row in a recipe’s VtRecipeDefinition.inputs or VtRecipeDefinition.requiredItems array. Pairs an item with a count.
Inspector fields
| Field | Type | Default | Range | Description |
|---|---|---|---|---|
Item (item) |
VtItemDefinition | None | Item required by this entry. For inputs[]: consumed on craft. For requiredItems[]: must be in inventory but NOT consumed. | |
Count (count) |
int |
0 | ≥ 1 | How many of this item are required. Stackable items count across stacks via VtUnitInventory.GetCount. |
VtRecipeOutput
Serializable struct.
What a recipe produces on a successful craft: one item and a count.
Inspector fields
| Field | Type | Default | Range | Description |
|---|---|---|---|---|
Item (item) |
VtItemDefinition | None | Item produced on a successful craft. Required — recipe silently no-ops if null. | |
Count (count) |
int |
0 | ≥ 1 | How many copies are added to the crafter’s inventory on success. Stackable items merge; non-stackable each take a slot. |
Enums
VtCraftFailureReason
Why a VtUnitCrafter.IsAvailable check or VtUnitCrafter.TryCraft call refused. Surfaced via the out param on those calls and the VtUnitCrafter.OnCraftFailed event so consumer UI can render a precise “you can’t craft this because…” message.
| Value | Description |
|---|---|
None |
The check passed — recipe is craftable / craft succeeded. |
RecipeNull |
The recipe argument was null. |
NotLearned |
The crafter doesn’t know this recipe yet (not learnedByDefault + not in the unit’s VtUnitRecipeBook). |
MissingIngredients |
The unit’s inventory doesn’t hold enough of one or more VtRecipeDefinition.inputs ingredients. |
MissingRequiredItems |
The unit’s inventory doesn’t hold one or more VtRecipeDefinition.requiredItems tools (must-have but not consumed — e.g. Crafter’s Tools). |
WrongStation |
The recipe requires a station the player isn’t using (null station or wrong type). |
LevelTooLow |
The unit’s VtUnitLevel.Level is below VtRecipeDefinition.requiredLevel. |
SkillTooLow |
The unit’s VtUnitCraftingSkills.GetLevel for the recipe’s VtRecipeDefinition.requiredSkill is below VtRecipeDefinition.requiredSkillLevel. |
MissingPrereqQuests |
One or more VtRecipeDefinition.requiredCompletedQuests haven’t been turned in yet. |
AlreadyCrafting |
A timed craft is already active. Cancel it first or wait for it to complete. |
AuthorityNotLocal |
Replica side refused the mutation; only authority can craft. |
NoCrafterComponent |
The unit doesn’t carry a VtUnitCrafter component. Returned by external helpers; the crafter itself never emits this since it can only be invoked when present. |
TooFarFromStation |
The crafter is farther from the station than its interact radius allows. |
Locked |
The recipe’s VtRecipeDefinition.requiredUnlock is not owned. |
InventoryFull |
The output would go into the crafter’s bag and the bag has no room for it, even after the ingredients are taken out. |
VtCraftOutputDestination
Where a VtRecipeDefinition’s output goes. Serialized as int; append only.
| Value | Description |
|---|---|
CrafterBag |
Into the crafter’s own bag, or into what paid when the crafter has no bag. |
CostSource |
Back into what paid for the ingredients: a shared stash when one served the crafter, else the crafter’s own bag. Planks cut at camp go into the team’s pool, planks cut in the wild into the pack. |