Gameplay · guide
Interactables, gathering and crafting
One channelled system for mining, looting, reading and pulling levers, with a claim that stops two players finishing the same rock — and recipes over it, whose stations are tag queries.
Edit this page on GitHubDocuments
- InteractionInstancing
- InterruptOn
- InteractionRefusal
- InteractableDefinition
- Interactable
- InteractionLibrary
- Channel
- InteractionResult
- InteractionNode
- InteractionModule
- RecipeSource
- CraftingRefusal
- RecipeItemDefinition
- RecipeDefinition
- RecipeItem
- Recipe
- CraftingResult
- CraftingLibrary
- Crafter
- CraftingModule
What it is#
An InteractableDefinition is a thing you use: a node, a chest, a door, a lever, a forge. An
InteractionNode is one of them in the world — how much is left of it and who is on it. A
Recipe is inputs, a station and outputs, and a Crafter is one character's knowledge of
them.
What it is for#
Doc 28 calls interaction *"the grinding loop"* and crafting *"recipes over that"*. Mining a node, smelting at a forge, opening a chest, reading a book, flipping a lever and picking a herb are one system with different definitions.
Using it#
Compile the two libraries, make an InteractionNode per thing in the world, and Begin, Disturb
and Complete. For crafting, Learn, CanCraft and Craft.
⚠ A shared node is claimed for the duration of a channel — without it two players both finish and it yields twice.
⚠ Interruption consumes nothing, and respawn counts from the completion that emptied it rather than from the last attempt.
⚠ Per-player instancing puts the uses on the player, which is the answer to node-stealing.
⚠ A station is a tag query, so an enchanted forge satisfies a recipe that asks for a forge.
Vixen.Gameplay.Crafting does not reference Vixen.Gameplay.Interaction: what it borrows is the
shape, not the code.
⚠ Discovery is an exact match on the ingredients, or throwing everything in the pot discovers everything. ⚠ Skill gain falls linearly to nothing across a band, or the last recipe before a cliff is the only one anybody makes.
⚠ Neither library moves anything. A node reports what it yields and a craft reports what to consume; the caller's containers do the rest.
Examples#
A node and a recipe:
# Assets/World/copper-vein.vxdef!InteractableDefinitiondisplayName: Copper veintag: Interactable.Node.Oreverb: MinechannelSeconds: 3uses: 2respawnSeconds: 120yields: loot/copperrequires: [ { kind: Value, subject: Profession.Mining, comparison: AtLeast, value: 25 } ]# Assets/Recipes/copper-bar.vxdef!RecipeDefinitiondisplayName: Copper barprofession: Profession.Smithingstation: Interactable.Station.Forgeinputs: [ { item: items/copper-ore, count: 2 } ]outputs: [ { item: items/copper-bar } ]skillRequired: 0skillCap: 100skillGain: 4Mining it:
using Vixen.Gameplay;using Vixen.Gameplay.Interaction;static class Mining { public static InteractionRefusal Swing(InteractionNode vein, PlayerId who, float now) => // Claimed from here until it completes, is interrupted, or the claimant walks off. vein.Begin(who, now); public static bool Hit(InteractionNode vein) => // The definition says whether being hit stops it; nothing is consumed either way. vein.Disturb(InterruptOn.Damage); public static DefId Finish(InteractionNode vein, PlayerId who, float now) => vein.Complete(who, now, out var result) == InteractionRefusal.None ? result.Yields : DefId.None;}Crafting, and finding something by experiment:
using Vixen.Gameplay;using Vixen.Gameplay.Crafting;static class Forge { public static CraftingResult? Smelt( Crafter smith, Recipe bar, GameplayTagSet station, IReadOnlyDictionary<uint, int> holdings, ulong attempt ) => smith.Craft(bar, station, holdings, attempt, out var result) == CraftingRefusal.None ? result : null; public static Recipe? Experiment(Crafter smith, IReadOnlyList<RecipeItem> pot) => // An exact match — a superset would discover everything at once. smith.TryDiscover(pot, out var found) ? found : null;}See also#
- Loot — what a node's
yieldsaddress names. - Progression — what answers a recipe's skill.
- Requirements — what gates both.