crafting: actor-precondition (requires) + reward (grants) — Skills half of Phase H (ADR-0056)
lib-core.crafting v0.4.0: two optional domain-free recipe fields.
- `requires`: a match-table evaluated against ctx.actor (not container items) — a hard gate. Failing -> {ok=false, error="requires_unmet", unmet={keys}}; fail-closed when ctx.actor is nil. Same predicate machinery as slots; distinct from is_known (discovery vs lock).
- `grants`: property->number reward, returned as `granted` from craft(); the consuming MODULE applies it to the actor (crafting stays container-scoped). Crafting knows no 'skill' vocabulary (ADR-0001).
vagrant-skeleton v0.21.0: player-actor carries skill.knapping (entity property, Phase-A lesson); knap_sharp_stone grants knapping XP, craft_stone_axe requires knapping>=3; module applies granted; skill-locked recipes show 'Skill too low'. Gate->earn->unlock loop headless-verified (axe locked @0 requires_unmet -> 3 knaps -> unlocks).
Quality-band reserved (Phase J): the requires threshold = the future quality floor (no re-authoring). Docs synced: ADR-0056, crafting-model.md (v0.4.0 + Actor-Precondition section), libraries.md, crafting README, vagrant README.
This commit is contained in:
@@ -21,6 +21,12 @@
|
||||
-- `inputs` and non-consumed `tools`; the inputs/tools split (not a separate
|
||||
-- axis) says whether the item is used up.
|
||||
--
|
||||
-- ACTOR-SIDE (crafting v0.4 / ADR-0056): a recipe may also gate on / reward the
|
||||
-- ACTOR, not the ingredients:
|
||||
-- * `requires = { ["skill.knapping"]=">=3" }` — hard gate vs ctx.actor
|
||||
-- * `grants = { ["skill.knapping"]=1 }` — XP given on successful craft
|
||||
-- Same predicate machine; the module applies `grants` to the actor.
|
||||
--
|
||||
-- `form` was RETIRED (ADR-0055 amendment): a physical-shape axis mixed
|
||||
-- geometry, identity and capability. Its functional members became
|
||||
-- affordances; its identity members (a "tree") stay template-id.
|
||||
@@ -86,10 +92,13 @@ return function(c)
|
||||
-- ---- recipes (match by CAPABILITY, not by item id) --------------
|
||||
-- knap: any KNAPPABLE stone + a HAMMERING tool -> a cutting edge.
|
||||
-- (rock is knappable; sharp_stone is NOT → no self-recursion.)
|
||||
-- Skill-ungated but GRANTS knapping XP (ADR-0056) — the accessible "grind"
|
||||
-- recipe that bootstraps the gated craft_stone_axe below.
|
||||
c.R{ id = "knap_sharp_stone",
|
||||
inputs = { { match = { ["affordance.knappable"] = true }, count = 1 } },
|
||||
tools = { { match = { ["affordance.hammering"] = true } } },
|
||||
outputs = { { template = "sharp_stone", count = 1 } },
|
||||
grants = { ["skill.knapping"] = 1 },
|
||||
name = "Knap Sharp Stone",
|
||||
description = "Strike a stone with a hammerstone to flake off a sharp edge." }
|
||||
|
||||
@@ -115,15 +124,18 @@ return function(c)
|
||||
description = "Lash a stone to a haft for a pounding tool (enables knapping)." }
|
||||
|
||||
-- axe: a CUTTING head + a LEVERAGE haft + a BINDING.
|
||||
-- Skill-GATED (ADR-0056): needs knapping >=3, earned by knap_sharp_stone.
|
||||
-- Demonstrates the gate+earn+unlock loop (gate downstream, grant upstream).
|
||||
c.R{ id = "craft_stone_axe",
|
||||
inputs = {
|
||||
{ match = { ["affordance.cutting"] = true }, count = 1 }, -- head (a sharp stone)
|
||||
{ match = { ["affordance.leverage"] = true }, count = 1 }, -- haft
|
||||
{ match = { ["affordance.binding"] = true }, count = 1 }, -- binding
|
||||
},
|
||||
outputs = { { template = "stone_axe", count = 1 } },
|
||||
requires = { ["skill.knapping"] = ">=3" },
|
||||
outputs = { { template = "stone_axe", count = 1 } },
|
||||
name = "Haft Stone Axe",
|
||||
description = "Bind a sharp stone to a haft with cordage." }
|
||||
description = "Bind a sharp stone to a haft with cordage. (Needs knapping skill 3.)" }
|
||||
|
||||
-- break: a HEAVY leverage-thing (branch, not a light stick) -> two sticks.
|
||||
c.R{ id = "break_branch",
|
||||
|
||||
Reference in New Issue
Block a user