2026 10 13 crafting design - xopherdeep/do-it-for-the-xp GitHub Wiki

Crafting: drops, DIY recipes, the Workbench and the Kitchen — design

Date: 2026-10-13. Status: design approved in chat by the owner, section by section; this spec awaits review.

Why

Beasts should drop things, and heroes should craft with them, the way Animal Crossing does it: nothing can be made until its DIY recipe has been learned. The Kitchen cooks the 33 favorite foods; the Workbench makes battle goods, accessories, bag and storage upgrades and furniture. It must work with no setup: no Game Master writes drop tables.

The Workbench (MyCrafts) and the Kitchen (MyFoods) exist today with placeholder data (a remote accessory fetch and a mock food list). The bag already has a material kind (src/lib/services/inventory/Inventory.ts).

Decisions (owner, 2026-10-13)

  • Approach A: one built-in catalogue. Drops are a pure function of the beast's temple theme, the fight's difficulty and the beast's rank. Family-made beasts work because they carry a theme. No per-beast loot tables.
  • Food is in-game only. Cooked food restores HP/MP; a hero's own favorite food restores double. Real treats stay GP shop items (the rewards-vs-powers rule).
  • The Workbench makes all four: battle goods, accessories with stats, bag and storage upgrades, furniture. Placing furniture in My Home is a later epic with its own spec; furniture can be crafted and stored now.
  • Recipes come from beast drops, region shops, and temple chests and boss first-clears. No starter recipes; instead a hero's first victory always drops a recipe card.
  • Loot from a quest that waits for approval waits with it. Free fights drop commons and ingredients only.
  • The Workbench tab "Weapons" is relabelled "Battle". The only tab change; every other tab keeps its label.

1. Materials

Every temple theme (TEMPLE_THEME_KEYS) has one common material (the fodder) and one rare.

Theme Chores Common Rare
wind quick chores Feather Zephyr Plume
earth yard and pets Wood Amber
water bathroom Spring Water Pearl
fire cooking and big jobs Coal Fire Opal
ice laundry and fridge Cloth Frost Crystal
light school Paper Star Fragment
shadow kitchen Iron Nugget Onyx
moon bedtime and self-care Herb Moonstone
storm bedroom and clutter Stone Thunder Egg

Ingredients (the pantry, 10). Themed drops, and all ten are sold at the Home Town market for 5 GP each.

Theme Ingredients
shadow Flour, Sugar
ice Milk, Cheese
earth Egg, Veggies, Fruit
fire Meat, Spice
water Fish

wind, light, moon and storm drop no ingredients.

Bag rows: { id: "<material-id>", name, kind: "material", qty, faIcon } (ingredients use the same kind, so the Pantry and My Goods' Materials tab both find them).

2. Drops

rollDrops(input, rng) in src/lib/services/crafting/drops.ts, pure, rng defaults to Math.random and tests pass a seeded one. Input: the defeated beasts (each { theme?, element?, isBoss, type, elite }), the fight kind (free or not), the difficulty, and whether this is the hero's first victory. Each beast rolls on its own; the results merge into stacks.

Theme. The beast's theme; without one, its art element: wind→wind, earth→earth, water→water, fire→fire, ice→ice, light→light, shadow→shadow, moon→moon, lightning→storm; anything else→wind.

Difficulty. A quest fight uses the quest's Fibonacci difficulty; a non-free fight with no quest uses 3.

Drop Quest and temple fights Free fights
Common of the theme difficulty 1-2: 1, 3-7: 2, 8-12: 3, 13+: 4; +1 miniboss, +2 boss 1
Ingredient (themes that have them) 50% for 1; difficulty 5+: 1 for sure; 8+: 2 50% for 1
Rare of the theme boss 100%, miniboss 35%, elite 20%, plain 0 never
Recipe card boss 50%, miniboss 25%, elite 15%, plain 6% never

First victory. When the hero knows no recipe and holds no recipe card, the fight drops one recipe card for sure, whatever its kind.

Which card. A random recipe whose sources include a drop of that theme, preferring ones the hero neither knows nor holds. When every one is known, any of them (a duplicate, sold for GP).

Where loot lands. The bag, then Storage; what fits nowhere is left behind and the victory line says so.

When loot pays.

  • A fight with no approval wait: at the win, beside XP/GP/AP (useBattleOutcome.settleFight and settleQuestWin).
  • A quest held for approval: the win stores the roll input on the pending claim (lootRoll: themes, ranks, difficulty, first-victory flag) and the Game Master's approval rolls and pays it, with a notification.
  • Only battles drop. A quest completed off the battlefield drops nothing.

Enemies carry their theme. Enemy (src/lib/services/battle/battleService/types.ts) gains theme? and elite?, copied by the encounter loader from the beast (elite = the encounter used the beast's variantAvatar).

The victory dialog lists the loot under the rewards: "Wood ×2 · Egg · DIY: Pizza".

3. The recipe book

  • knownRecipes: string[] on each hero (persisted with the profile). Old saves start empty.
  • Recipe cards are bag rows { id: "recipe:<recipeId>", name: "DIY: <Name>", kind: "misc", type: "recipe", recipeId }. They list under Misc in My Goods (no new tab), with a Learn button.
  • Learn: the card is used up and the id joins knownRecipes. A card already known shows Sell for N GP instead.
  • Sell price: half the recipe's shop price; a recipe with no shop price sells for 20 GP (drop) or 60 GP (chest).
  • Unknown recipe ids in knownRecipes are ignored. Unknown recipes are never shown on the stations.

4. Crafting (both stations)

src/lib/services/crafting/crafting.ts, pure:

  • craftable(hero, recipe, qty): whether the materials are there, counted across the bag and Storage, and whether the output has room.
  • craft(hero, recipeId, qty): new bag and Storage rows, or a refusal line. Materials come from the bag first, then Storage (reuse Storage.ts: rowsAfterTaking, canCarry). The output goes to the bag, else Storage, else refuse ("Your bag and storage are full.").
  • Recipes need materials and ingredients only, never another crafted item.

Screen pattern for both stations:

  • Rows of known recipes for the active tab: the product, then the needs line Wood 3/5 · Iron Nugget 1/2. Craftable rows are bright; the others dimmed.
  • Tapping a row opens a bottom sheet (thumb reach): needs with have/need, a quantity stepper, Craft / Cook.
  • The header meta reads 23 / 75 recipes. An empty station says where recipes come from: "Defeat beasts to find DIY recipes."
  • Sounds through play$fx; toasts rpg-toast, position middle.

5. The Kitchen (MyFoods)

Tabs stay: All | Favorites | Meals | Snacks | Desserts | Pantry. Favorites pins the hero's own favoriteFood; Pantry lists the ingredients held. FOOD_OPTIONS stays the one list of foods; the catalogue adds each food's category and needs.

Food Kind Needs
Apple snack Fruit 2
Bacon snack Meat 1, Spice 1
Bread snack Flour 2
Burger meal Meat 1, Flour 1, Veggies 1
Burrito meal Flour 1, Meat 1, Veggies 1, Cheese 1
Cake dessert Flour 1, Sugar 2, Egg 1, Milk 1
Candy Cane dessert Sugar 2
Candy Corn dessert Sugar 1, Veggies 1
Carrot snack Veggies 2
Cheese snack Milk 2
Cheeseburger meal Meat 1, Flour 1, Cheese 1, Veggies 1
Coffee snack Spice 1, Milk 1
Cookie dessert Flour 1, Sugar 1, Egg 1
Corn snack Veggies 1, Spice 1
Croissant snack Flour 2, Milk 1
Drumstick meal Meat 1, Spice 1, Flour 1
Egg snack Egg 2
Fish meal Fish 2, Spice 1
French Fries snack Veggies 2, Spice 1
Fried Egg snack Egg 1, Spice 1
Hotdog meal Meat 1, Flour 1
Ice Cream dessert Milk 2, Sugar 1
Lemon snack Fruit 1, Sugar 1
Pepper snack Veggies 1, Spice 2
Pie dessert Flour 1, Fruit 2, Sugar 1
Pizza meal Flour 1, Cheese 1, Veggies 1
Popcorn snack Veggies 1, Milk 1
Salad meal Veggies 2, Fruit 1
Sandwich meal Flour 1, Meat 1, Cheese 1
Sausage snack Meat 2
Smoothie snack Fruit 1, Milk 1
Steak meal Meat 2, Spice 1
Taco meal Flour 1, Meat 1, Spice 1, Veggies 1

Source. Every food recipe drops from beasts of the theme of its first ingredient (Pizza: shadow, the kitchen).

Effects (src/lib/services/crafting/foodEffects.ts): snack +20 HP; meal +40 HP and +15 MP; dessert +30 MP; capped at max. The hero's own favoriteFood (matched on the singular name, as MyFoods already does) restores double. Cooked food is a consumable bag row; it can be eaten from My Goods and from the battle bag's Goods sheet (the same sheet that drinks potions, BattlePotions.ts).

6. The Workbench (MyCrafts)

Tabs: All | Furniture | Accessories | Battle (was Weapons) | Key. The remote xp_accessory fetch goes away.

Battle (8). Potions use the existing POTIONS rules. Bombs are one-shot goods with no MP cost: they run an existing BattleEffectId and are used up.

Recipe Needs Source
Potion Herb 2, Spring Water 1 drop moon; shop hometown-market 40 GP
Ether Spring Water 2, Feather 1 shop wrecked-ship 60 GP
X-Potion Herb 3, Spring Water 2, Amber 1 shop witchs-hut 150 GP
Mega Potion Herb 4, Spring Water 2, Pearl 1 chest water
Elixir Herb 3, Moonstone 1, Pearl 1 chest moon
Ember Bomb (kindle) Coal 3, Paper 1 shop crystal-caverns 80 GP
Frost Bomb (frost) Spring Water 2, Cloth 1, Iron Nugget 1 shop snow-shack 80 GP
Spark Bomb (stun) Stone 2, Iron Nugget 1, Feather 1 shop cloud-market 80 GP

Accessories (9). Each needs its theme's rare; all come from chests of that theme.

Accessory Needs Bonus
Zephyr Charm Zephyr Plume 1, Feather 5 +3 speed
Amber Amulet Amber 1, Wood 5 +10 max HP
Pearl Ring Pearl 1, Spring Water 3 +10 max MP
Fire Opal Ring Fire Opal 1, Coal 5 +3 strength
Frost Brooch Frost Crystal 1, Cloth 5 +3 defense
Star Pendant Star Fragment 1, Paper 5 +5 max HP, +5 max MP
Onyx Band Onyx 1, Iron Nugget 5 +2 strength, +2 defense
Moonstone Locket Moonstone 1, Herb 5 +15 max HP
Thunder Bracer Thunder Egg 1, Stone 5 +2 speed, +2 strength

Key (7): upgrades apply the moment they are crafted (no bag row). Tier n needs tier n-1; a tier the hero already has (bought or crafted) shows as built.

Recipe Effect Needs Source
Bigger Pouch I bag 30 stacks Cloth 5, Feather 3 shop hometown-market 60 GP
Bigger Pouch II bag 40 Cloth 8, Wood 4 shop pegasus-ranch 120 GP
Bigger Pouch III bag 60 Cloth 10, Iron Nugget 5, Frost Crystal 1 shop cloud-market 250 GP
Storage Chest I STORAGE_TIERS[0] Wood 6 shop hometown-market 80 GP
Storage Chest II STORAGE_TIERS[1] Wood 10, Iron Nugget 3 shop hermits-tent 150 GP
Storage Chest III STORAGE_TIERS[2] Wood 12, Iron Nugget 6, Stone 4 shop pond-of-life 300 GP
Storage Chest IV STORAGE_TIERS[3] Wood 15, Iron Nugget 8, Onyx 1 shop theia-city 600 GP

The bag size becomes per hero: bagTier (0 = 20 stacks, the old BAG_STACKS). Storage chests set the same storageTier the Gold Bank sells, so buying and crafting are two ways to one upgrade.

Furniture (18). Two per theme: a plain piece (drop of the theme) and a centrepiece with the rare (chest of the theme). Crafted furniture is a misc bag row { furniture: true } and is kept in the bag or Storage until the My Home epic lets it be placed.

Theme Plain (drop) Centrepiece (chest)
wind Feather Pillow: Feather 6, Cloth 2 Wind Chime: Zephyr Plume 1, Feather 4, Iron Nugget 1
earth Log Stool: Wood 6 Amber Lamp: Amber 1, Wood 4
water Fish Bowl: Spring Water 4, Stone 2 Pearl Mirror: Pearl 1, Spring Water 2, Iron Nugget 2
fire Coal Stove: Coal 4, Iron Nugget 2 Fire Opal Hearth: Fire Opal 1, Stone 4, Coal 2
ice Rag Rug: Cloth 6 Frost Chandelier: Frost Crystal 1, Iron Nugget 3
light Bookshelf: Paper 4, Wood 4 Star Globe: Star Fragment 1, Paper 2, Iron Nugget 1
shadow Pot Rack: Iron Nugget 5 Onyx Clock: Onyx 1, Wood 2, Iron Nugget 2
moon Herb Planter: Herb 4, Stone 2 Moonstone Nightlight: Moonstone 1, Cloth 2
storm Toy Chest: Wood 3, Stone 3 Thunder Lamp: Thunder Egg 1, Iron Nugget 2

Total: 33 foods + 8 battle + 9 accessories + 7 key + 18 furniture = 75 recipes.

7. The accessory slot

Nothing applies Accessory.bonusStats today. Each hero gets one equipped accessory (the bag row moves into the slot; unequipping moves it back). Its bonus adds to the hero's strength, defense, speed, max HP and max MP wherever the battle reads them: one place, found in src/lib/services/stats/ (StatEffects / EngineStatsService), not per screen. The slot shows in the equipment modal beside the hands. No nav bar changes.

8. Chests and shops

  • Boss first-clear of a temple drops one recipe card whose sources include a chest of that temple's theme (unknown preferred), in the boss chest beside the usual reward.
  • Temple creator: a chest's loot picker (RoomLootConfig) can also hold a recipe card or a material from the catalogue. Optional; nothing breaks when a GM never uses it.
  • Shops: ShopItemType gains Recipe and Ingredient. Region shops are stocked from the catalogue's shop sources by merging into the defaults (ShopsDb.seedDefaults / syncWithRegistry): a family's own shelves are never removed. Buying a recipe puts the card in the bag; buying an ingredient puts it in the bag.

9. Modules and state

src/lib/services/crafting/
  catalog/materials.ts   MATERIALS (commons, rares, ingredients: id, name, kind, theme, faIcon)
  catalog/recipes.ts     RECIPES (id, name, station, tab, makes, needs, sources, shopPrice?), foods built from FOOD_OPTIONS
  drops.ts               rollDrops, themeOf
  recipeBook.ts          learn, sell, knownOf
  crafting.ts            craftable, craft
  foodEffects.ts         foodGain(food, hero)

user.ts gains knownRecipes, bagTier, accessory (persisted in profileFields.ts) and the actions addLoot, learnRecipe, sellRecipeCard, craftRecipe, equipAccessory.

10. Testing

  • Catalogue integrity (jest): every need names a material; all 33 FOOD_OPTIONS have a recipe; every recipe has at least one source; every theme has at least one drop recipe; every shop source names a real shop id; 75 recipes.
  • Drops: seeded rolls for each rank and kind; first-victory guarantee; unknown-first card choice; theme fallback.
  • Recipe book and crafting: learn, duplicate sell, craft from bag then Storage, full bag refusal, tiered upgrades.
  • Food: favorite doubles; caps at max.
  • One Cypress run (--browser chrome): win a fight, a card drops, learn it, craft a Potion, drink it in battle.

11. Slices

  1. Catalogue and integrity spec.
  2. Drop engine.
  3. Recipe book, crafting engine, hero state.
  4. Loot on battle wins and on approvals (Enemy theme/elite, victory lines, lootRoll on held claims).
  5. Chests, boss first-clears, shop stock.
  6. Kitchen screen and food effects (My Goods eat, battle Goods sheet).
  7. Workbench screen (Battle tab, Key upgrades and bagTier, bombs in the Goods sheet). Waits for board #1285.
  8. Accessory slot with stats in battle.
  9. E2E loop.
  10. Later epic, own spec: placing furniture in My Home.

Out of scope

Per-beast loot overrides; gifting food to the party; trading between heroes; look pieces as drops (Look Unlocks project 3 can add a drop kind to rollDrops later); placing furniture.

⚠️ **GitHub.com Fallback** ⚠️