crafting: retire form, unify on affordance capability axis (ADR-0055 amendment)

Recipe roles now match on a single `affordance.*` axis, required by both consumed `inputs` and non-consumed `tools` (the inputs/tools split carries consumption, not a separate axis). `form` — which conflated geometry, identity and capability — is removed. Its functional members folded into affordances (blade->cutting, shaft->leverage, plus knappable/spinnable/binding); identity members became template-id (chop_tree) or material+weight (log, hammer head).

vagrant-skeleton v0.20.0; no crafting/composition lib bump (they never knew `form`). Verified headless via the tool-harness: 16/16 checks pass — role-flexibility (stick OR branch hafts), weight discrimination, tool-gating (tool not consumed), and anti-recursion guards (sharp_stone not re-knappable, cordage not re-spinnable).
This commit is contained in:
calic
2026-07-31 07:43:08 +00:00
parent 4825d01426
commit b28afd5290
4 changed files with 93 additions and 58 deletions

View File

@@ -181,7 +181,9 @@ composition.define_template{
description = "A heavy stone. Could be useful for crafting.",
weight = 2.5, -- kg (real units)
volume = 0.001, -- L (real units)
form = "lump", -- role: a knappable/poundable stone
-- Affordance = what the item OFFERS (ADR-0055 amendment): a raw
-- stone chunk affords being knapped (flaked into an edge).
["affordance.knappable"] = true,
-- Material composition (composition-model.md §4 — 0-1 platonic;
-- 1.0 = pure stone). Phase E (property-driven recipes) reads this.
["composition.stone"] = 1.0,
@@ -205,7 +207,10 @@ composition.define_template{
description = "A wooden stick. Useful for crafting tool handles.",
weight = 0.3, -- kg
volume = 0.0005, -- L
form = "shaft", -- role: a light rigid shaft (handle)
-- Affordance (ADR-0055 amendment): a rigid shaft affords leverage —
-- i.e. it can serve as a haft/handle. weight (light) distinguishes
-- it from a heavy branch in weight-gated recipes.
["affordance.leverage"] = true,
["composition.wood"] = 1.0,
sprite_atlas = "",
sprite_uv = {x = 0, y = 0, w = 1, h = 1},
@@ -644,7 +649,11 @@ function M.init(ctx)
position = { x = 0, y = 0 },
}
if a.scale then props.sprite_scale = a.scale * (d.scale or 1) end
if d.form then props.form = d.form end -- role tag: shaft / cord / fiber / lump / blade / …
-- Two orthogonal axes (ADR-0055 + amendment): `material` = composition
-- fractions (what it's MADE OF), `affordance` = capabilities it OFFERS
-- (what it can DO / what role it fills). `form` was retired — its
-- functional members folded into affordance, its identity members
-- into template-id / material+weight.
for m, v in pairs(d.material or {}) do props["composition." .. m] = v end
for k, v in pairs(d.affordance or {}) do props["affordance." .. k] = v end
composition.define_template{ id = d.id, properties = props, tags = { "renderable", "item" } }