feat(vagrant): v0.16.0 stone-age tech chain (knap/twist/haft → stone_axe); fix crafting manifest.lib to 0.3.0

This commit is contained in:
calic
2026-07-28 11:38:23 +00:00
parent 8994b24567
commit ff9d50937d
3 changed files with 122 additions and 5 deletions

115
init.lua
View File

@@ -251,6 +251,23 @@ composition.define_template{
tags = {"renderable", "item"},
}
-- `plant_fiber` is a light gatherable; three twist into cordage (binding).
composition.define_template{
id = "plant_fiber",
properties = {
stack_mode = "individual",
name = "Plant Fiber",
description = "A strand of tough plant fiber. Twist several into cordage.",
weight = 0.05,
volume = 0.0002,
["composition.fiber"] = 1.0,
sprite_atlas = "",
sprite_uv = {x = 0, y = 0, w = 1, h = 1},
position = {x = 0, y = 0},
},
tags = {"renderable", "item"},
}
-- NOTE: Crafted-output templates (rock_pick, rock_pile) are defined inside
-- M.init rather than at top-level, because their sprite_atlas defaults need
-- the resolved blob_rect_stone PNG path. Crafting calls composition.create
@@ -718,6 +735,48 @@ function M.init(ctx)
tags = {"renderable", "item"},
}
-- cordage: crafted from 3 plant_fiber; a binding material for hafting.
local cordage_uv = tc_sprites.sack1
composition.define_template{
id = "cordage",
properties = {
stack_mode = "individual",
name = "Cordage",
description = "A length of twisted plant-fiber cord.",
weight = 0.1,
volume = 0.0003,
["composition.fiber"] = 1.0,
sprite_atlas = tc_atlas_png,
sprite_uv = {x = cordage_uv.x, y = cordage_uv.y, w = cordage_uv.w, h = cordage_uv.h},
sprite_scale = tc_scale,
position = {x = 0, y = 0},
},
tags = {"renderable", "item"},
}
-- stone_axe: hafted tool (sharp_stone head + stick haft + cordage binding).
-- Carries affordance.chopping for future wood-felling recipes.
local axe_uv = tc_sprites.spade
composition.define_template{
id = "stone_axe",
properties = {
stack_mode = "individual",
name = "Stone Axe",
description = "A hafted stone axe. Chops wood.",
weight = 1.8,
volume = 0.0012,
["composition.stone"] = 0.6,
["composition.wood"] = 0.3,
["composition.fiber"] = 0.1,
["affordance.chopping"] = true,
sprite_atlas = tc_atlas_png,
sprite_uv = {x = axe_uv.x, y = axe_uv.y, w = axe_uv.w, h = axe_uv.h},
sprite_scale = tc_scale,
position = {x = 0, y = 0},
},
tags = {"renderable", "item"},
}
-- Workbench-Template (Phase D v0.2). Container-kind=list so it can
-- accept items via inventory.add (crafting output landing spot).
-- Placeholder visual re-uses the blob_rect_stone atlas with
@@ -813,6 +872,23 @@ function M.init(ctx)
},
}
register_pickup(state.sharp_stone)
-- Three plant fibers (twist into cordage → haft a stone axe).
state.fibers = {}
local fiber_uv = tc_sprites.sack1
for i = 1, 3 do
local f = composition.create{
template = "plant_fiber",
properties = {
sprite_atlas = tc_atlas_png,
sprite_uv = {x = fiber_uv.x, y = fiber_uv.y, w = fiber_uv.w, h = fiber_uv.h},
sprite_scale = tc_scale * 0.6,
position = {x = LOG_X - 60, y = LOG_Y - 100 + (i - 1) * 28},
},
}
register_pickup(f)
state.fibers[i] = f
end
if CI_FRAME_PERF then engine.print("vagrant: stoneage_spawned") end
-- Workbench spawn (Phase D v0.2). Placed at (350, 380) — 20px above
@@ -866,6 +942,36 @@ function M.init(ctx)
name = "Saw Planks",
description = "Saw a wooden log into four planks (needs a cutting edge).",
}
-- ── Stone-Age tech chain (crafting v0.3) ──────────────────────────────
-- Self-bootstrapping graph: knap a rock into a sharp_stone (bare hands),
-- which is then the cutting TOOL for saw_planks AND the head for a
-- stone_axe. Twist plant fibers into cordage, then haft axe = head + stick
-- + cordage. Tier-0 steps need no tool (the bootstrap entry points).
crafting.define_recipe{
id = "knap_sharp_stone",
inputs = { {template = "rock", count = 1} },
outputs = { {template = "sharp_stone", count = 1} },
name = "Knap Sharp Stone",
description = "Strike a rock to flake off a sharp-edged stone.",
}
crafting.define_recipe{
id = "twist_cordage",
inputs = { {template = "plant_fiber", count = 3} },
outputs = { {template = "cordage", count = 1} },
name = "Twist Cordage",
description = "Twist three plant fibers into a length of cordage.",
}
crafting.define_recipe{
id = "craft_stone_axe",
inputs = {
{template = "sharp_stone", count = 1}, -- head (consumed)
{template = "stick", count = 1}, -- haft
{template = "cordage", count = 1}, -- binding
},
outputs = { {template = "stone_axe", count = 1} },
name = "Haft Stone Axe",
description = "Bind a sharp stone to a stick with cordage.",
}
-- v0.14.0: per-recipe icon resolver for the Crafting + Workbench-Crafting
-- widgets. Maps recipe.output.template → {atlas, uv} for the icon
@@ -874,9 +980,12 @@ function M.init(ctx)
-- domain-free), so the module-side that DEFINES the templates is the
-- canonical place to know each output's sprite.
local craft_icons = {
rock_pick = { atlas = tc_atlas_png, uv = tc_sprites.spade },
rock_pile = { atlas = stone_atlas_png, uv = stone_uvs.slot_13_solid },
plank = { atlas = tc_atlas_png, uv = tc_sprites.bench1 },
rock_pick = { atlas = tc_atlas_png, uv = tc_sprites.spade },
rock_pile = { atlas = stone_atlas_png, uv = stone_uvs.slot_13_solid },
plank = { atlas = tc_atlas_png, uv = tc_sprites.bench1 },
sharp_stone = { atlas = stone_atlas_png, uv = stone_uvs.slot_13_solid },
cordage = { atlas = tc_atlas_png, uv = tc_sprites.sack1 },
stone_axe = { atlas = tc_atlas_png, uv = tc_sprites.spade },
}
local function craft_icon_for(recipe)
if recipe and recipe.output and recipe.output.template then