Commit Graph

5 Commits

Author SHA1 Message Date
Calic
ececf38b2c 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.
2026-08-03 09:14:55 +00:00
Calic
ff95be19a8 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.
2026-07-31 10:00:26 +00:00
Calic
b75a2432f6 feat(vagrant): v0.16.0 stone-age tech chain (knap/twist/haft → stone_axe); fix crafting manifest.lib to 0.3.0 2026-07-28 11:38:22 +00:00
Calic
f938d11ca8 feat: lib-core.crafting v0.2.0 — Multi-Source / Single-Sink Locale-API
Extends can_craft + craft to take a `locale` parameter that describes
WHERE inputs come from and WHERE outputs go. Two forms are accepted;
the v0.1 single-container call signature continues to work unchanged
via a transparent bw-compat shim.

Locale-Schema:
  Form 1 (bw-compat): a bare container-entity-handle. Internally
                      wrapped to {sources={h}, sink=h}; the single
                      container is both the sole input source AND the
                      output sink. v0.1 call sites need no migration.
  Form 2 (explicit):  { sources = {c1, c2, ...}, sink = c_out } where
                      sources is a non-empty array of container-entity-
                      handles and sink is a single container-entity-
                      handle. sink MAY appear in sources (e.g. workbench
                      buffer as both source and sink).

can_craft aggregates input counts across the union of all sources
before comparing against the recipe's needs. `missing` entries report
the aggregated `have` count across sources.

craft greedy-drains in array-order: for each input.need it walks
sources left-to-right, fully draining matching-template items from
the first source before moving on to the next. The order is stable
and deterministic so callers can encode priority via the array.

A file-local resolve_locale helper centralizes the Form-1-vs-Form-2
dispatch and validates Form 2 with loud errors:
  locale == nil                       → "locale must not be nil"
  Form 2, sources not array or empty  → "sources must be non-empty array"
  Form 2, sink == nil                 → "sink must not be nil"

The count_by_template helper now takes a sources array and walks each
container's inventory in turn, summing per-template counts.

Manifest bumped 0.1.0 → 0.2.0. Deps unchanged (composition 0.3.0,
inventory-list 0.1.0). README documents both locale forms, the
greedy-drain order, the bw-compat guarantee, and the loud-error
conditions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-14 18:48:04 +02:00
Calic
a4f60b4825 feat: lib-core.crafting v0.1.0 — Recipe Registry + Craft Action
Headless data + logic layer for recipe-based crafting. Manages a
recipe registry, performs match-checks against a container's
inventory contents, and atomically consumes inputs + creates outputs.

Surface:
  define_recipe{id, inputs, output, name?, description?, is_known?}
  list_recipes(), get_recipe(id)
  is_known(recipe_id, ctx)              -- per-recipe discovery gate
  can_craft(recipe_id, container, ctx)  -- non-mutating availability
  craft(recipe_id, container, ctx)      -- mutating action

Recipe-Schema: count-form inputs (array of {template, count}) +
single output {template, count} + optional is_known(ctx) hook
(default returns true). Match-result schema:
  { ok=true, crafted_items, consumed }
  { ok=false, error='unknown_recipe' }
  { ok=false, error='missing_inputs', missing={{template, needed, have}} }

Container is both inputs-source and output-destination (single-container
v0.1; multi-container deferred). craft re-runs can_craft internally
and returns the structured error if state changed since the last frame.

Depends on lib-core.composition 0.3.0 (template_of, create, destroy)
and lib-core.inventory-list 0.1.0 (contents, add, remove).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-14 12:20:42 +02:00