crafting v0.5.0 + composition v0.4.0: Quality & Condition (Phase J)
lib-core.composition v0.4.0: un-defer quality/condition as inert numeric properties (loud-error removed); composition stores them without semantics. lib-core.crafting v0.5.0: quality-block (multi-contributor product-quality formula: skill-band with min=requires-floor + named ingredient/tool qualities), optional slot name, tool wear_per_use (condition decrement + wear report). affordance stays boolean. Additive to v0.4.0. vagrant-skeleton v0.22.0: branch quality-band RNG at spawn; stone_hammer condition=1.0; knap+axe quality-blocks; hammer wears out. Headless-verified 20/20. Design: meta/docs/design/2026-08-03-crafting-quality-condition-design.md. Docs synced: crafting-model.md, composition-model.md, libraries.md, READMEs.
This commit is contained in:
43
README.md
43
README.md
@@ -6,9 +6,9 @@ properties; template-id is the trivial constraint `{template="rock"}`. Inputs
|
||||
are consumed from the locale's source containers, non-consumed tools are
|
||||
presence-checked, and outputs are placed into the locale's sink container.
|
||||
|
||||
**Version:** 0.4.0
|
||||
**Version:** 0.5.0
|
||||
**Lib-ID:** lib-core.crafting
|
||||
**Requires:** `lib-core.composition` 0.3.0, `lib-core.inventory-list` 0.1.0
|
||||
**Requires:** `lib-core.composition` 0.4.0, `lib-core.inventory-list` 0.1.0
|
||||
**Tags:** crafting, recipe, registry
|
||||
|
||||
## Topology
|
||||
@@ -22,7 +22,7 @@ graph LR
|
||||
this --> inventory
|
||||
```
|
||||
|
||||
## Scope (v0.4.0 — ADR-0055 + ADR-0056)
|
||||
## Scope (v0.5.0 — ADR-0055 + ADR-0056 + Phase-J quality/condition)
|
||||
|
||||
Property-constraint recipe slots. A recipe slot matches items by a `match`
|
||||
table of property-constraints (AND-combined), evaluated via `get_property`;
|
||||
@@ -32,6 +32,11 @@ non-consumed `tools` (presence checks) and multi-output. Multi-Source /
|
||||
Single-Sink locale (Form 2) plus bw-compat bare-handle locale (Form 1).
|
||||
v0.4.0 (ADR-0056): actor-side `requires` (precondition gate vs `ctx.actor`) +
|
||||
`grants` (reward returned as `granted`).
|
||||
v0.5.0 (Phase J, design 2026-08-03): optional slot `name`; a `quality` block
|
||||
computing product quality from a skill-band + named ingredient/tool qualities
|
||||
(the skill `min` re-read from the `requires` floor); tool-slot `wear_per_use`
|
||||
decrementing the matched tool's `condition` (reported as `wear`). All additive:
|
||||
a recipe with none of these behaves exactly as v0.4.0.
|
||||
|
||||
**Supported:**
|
||||
- `define_recipe{id, inputs, tools?, outputs|output, requires?, grants?, name?, description?, is_known?}`
|
||||
@@ -42,18 +47,29 @@ v0.4.0 (ADR-0056): actor-side `requires` (precondition gate vs `ctx.actor`) +
|
||||
same predicate machinery as slots) — e.g. `{["skill.knapping"]=">=3"}`
|
||||
- `grants`: `property → number` reward; returned as `granted`, the **module**
|
||||
writes it to the actor — e.g. `{["skill.knapping"]=1}`
|
||||
- slot `name` (input or tool, optional): a label the `quality` formula
|
||||
references — e.g. `{match={...}, count=1, name="head"}`
|
||||
- `tools` entry `wear_per_use` (optional): decrements the matched tool's
|
||||
`condition` on a successful craft (clamped 0..1; reported as `wear`)
|
||||
- `quality = {contributors={...}}` (optional): product-quality formula;
|
||||
each contributor is one of `{skill, max, weight}` /
|
||||
`{ingredient=<slot-name>, weight}` / `{tool=<slot-name>, weight}`, weights
|
||||
sum to 1; result 0..1 written onto every crafted item and returned as `quality`
|
||||
- Constraint values: exact string/number/bool, or comparison string
|
||||
`">5"` / `">=0.2"` / `"<10"` / `"<=1"` / `"==x"` (numeric; string for `==`)
|
||||
- `list_recipes()`, `get_recipe(id)`, `is_known(recipe_id, ctx)`
|
||||
- `can_craft(recipe_id, locale, ctx)` — non-mutating; `craft(...)` — mutating
|
||||
- `locale`: bare container-entity (Form 1) or `{sources={...}, sink=...}` (Form 2)
|
||||
- Result `error ∈ {unknown_recipe, requires_unmet, missing_inputs, missing_tools}`;
|
||||
on `requires_unmet` also `unmet={keys}`; on a successful `craft` also `granted`
|
||||
on `requires_unmet` also `unmet={keys}`; on a successful `craft` also `granted`,
|
||||
plus `quality` (0..1, if a quality-block ran) and `wear` (per-tool new condition)
|
||||
|
||||
**Deferred:**
|
||||
- Skill XP→level curve, skill decay, `lib-core.skill` extraction (requires/grants
|
||||
are the generic substrate; skill vocabulary is the module's — ADR-0056)
|
||||
- Quality-band coupling (skill/ingredient/tool quality → output quality, Phase J)
|
||||
- Graded affordances (magnitude → success chance): `affordance.*` stays boolean;
|
||||
quality/condition are orthogonal scalars that scale OUTCOMES (design 2026-08-03 §7)
|
||||
- Repair (condition-raising / in-place input mutation) — deferred (design §8)
|
||||
- Workpiece-Model / multi-step / Batch / Time-coupled craft
|
||||
- True bipartite input↔item matching (v0.3 uses greedy first-fit — a solvable
|
||||
recipe where one item satisfies two slots can be missed; no stone-age
|
||||
@@ -123,7 +139,11 @@ Loud `error(...)` on: non-table `def`; missing / non-string / empty `id`;
|
||||
duplicate `id`; empty `inputs`; a slot with neither `template` nor `match`;
|
||||
an empty `match`; bad `count`; missing both `outputs` and `output`;
|
||||
non-function `is_known`; non-table or empty `grants`; non-string `grants` key
|
||||
or non-number `grants` value.
|
||||
or non-number `grants` value; non-string slot `name`; non-positive
|
||||
`wear_per_use`; a `quality` block whose `contributors` is empty, whose weights
|
||||
don't sum to 1, a contributor that isn't exactly one of skill/ingredient/tool,
|
||||
a `skill` contributor missing `max`, or an ingredient/tool contributor naming a
|
||||
slot that no `name` declares.
|
||||
|
||||
Error messages follow the pattern `"crafting.define_recipe '<id>': <reason>"`
|
||||
so test-suites can pattern-match.
|
||||
@@ -208,6 +228,9 @@ Loud-Error: `ctx` must be a table (empty `{}` OK); `locale` must not be
|
||||
crafted_items = { entity_handle, ... }, -- new output entities
|
||||
consumed = { entity_handle, ... }, -- input entities (already destroyed)
|
||||
granted = { ["skill.knapping"] = 1 }, -- recipe.grants, or nil; MODULE applies
|
||||
quality = 0.7, -- 0..1 if a quality-block ran (else nil);
|
||||
-- also written onto each crafted item
|
||||
wear = { hammer = 0.8 }, -- new condition per worn tool-slot (else nil)
|
||||
}
|
||||
|
||||
-- failure (same shape as can_craft)
|
||||
@@ -257,6 +280,11 @@ Loud-Error: `ctx` must be a table (empty `{}` OK); `locale` must not be
|
||||
-- vs ctx.actor; same match shape
|
||||
grants = { ["skill.knapping"] = 1 }, -- optional (ADR-0056): reward,
|
||||
-- returned as `granted`
|
||||
quality = { contributors = { -- optional (Phase J): product-quality
|
||||
{ skill = "skill.knapping", max = 5, weight = 0.4 }, -- min = requires-floor
|
||||
{ ingredient = "head", weight = 0.3 }, -- a NAMED input slot's `quality`
|
||||
{ tool = "hammer", weight = 0.3 }, -- a NAMED tool's `quality`×`condition`
|
||||
} }, -- weights sum to 1; product 0..1
|
||||
name = "Stone Pick", -- optional, display
|
||||
description = "A pick for mining stone.", -- optional, used by Inspect
|
||||
is_known = function(ctx) return true end,
|
||||
@@ -353,7 +381,8 @@ re-initialize state between assertions.
|
||||
| ~~H (Tools)~~ | **Shipped v0.3.0** (`tools` slot array) | crafting-model.md |
|
||||
| ~~H (Skills, gate)~~ | **Shipped v0.4.0** (`requires`/`grants`, ADR-0056) | crafting-model.md |
|
||||
| H (Skills, progression) | XP→level curve, decay, `lib-core.skill` extraction | — |
|
||||
| J (Quality) | `quality`-block: skill/ingredient/tool → output quality | crafting-model.md §Actor-Precondition |
|
||||
| ~~J (Quality/Condition)~~ | **Shipped v0.5.0** (`quality`-block + `wear_per_use`, design 2026-08-03) | crafting-model.md §Quality |
|
||||
| J+ (Repair / graded affordances) | condition-raising recipes; magnitude→success | design 2026-08-03 §7/§8 |
|
||||
| D+ (Workpiece) | Multi-step crafting with intermediate workpiece-entities | crafting-model.md |
|
||||
| D+ (Batch / Time) | Batch parameter, time-system coupling, abort-decon | crafting-model.md |
|
||||
| Domain-Libs | `lib-core.metalwork` / `textile` / `woodwork` consume crafting substrate | libraries.md §8 Catalog |
|
||||
|
||||
Reference in New Issue
Block a user