Design: practical-usefulness layer (eco-gnome/eco-calc mining, recipes page, value-per-profession, 'how to price X' use-case hub) #98

Open
opened 2026-07-07 06:11:12 +00:00 by coilysiren · 4 comments
Owner

Design the next layer of eco-app: turn it from a read-only mirror into a tool Eco players actually reach for. Filed from a batch of eco-app feedback Kai handed the director surface. This is a design/consult ticket. The deliverable is a design doc committed under docs/ plus a set of proposed, scoped follow-up issues, not code.

The bet

Eco players love economy tools even when usability is near zero. Eco Gnome is basically unusable and people still use it. Eco Calc (the website) and Eco Price Calculator (the mods) are the same: meh usability, real demand. The opportunity is to mine what those tools do and deliver it with a better surface. eco-app already hydrates the underlying data (the crafting atlas, trades ledger, market, stores, fair-price, currency) through src/eco_mcp_app/* and the eco MCP tool family.

What to design

  1. Mine the incumbents. Catalog the concrete jobs players do with Eco Gnome, Eco Calc, and Eco Price Calculator (recipe cost roll-ups, margin/profit calc, labor + calorie cost, sell-price suggestion, dependency trees, "is this worth crafting"). Map each job to the data eco-app already has (crafting.py atlas, logistics.py, market.py, stores.py, fair_price.py, trades.py) and flag any gap the exporters do not yet cover.

  2. Recipes page (grow this first). A recipe surface analogous to /items but recipe-shaped: ingredients in, product out, station, labor. Design its data model (the crafting atlas / eco MCP get_eco_crafting_atlas is already hydrating this) and its filters (by profession, by station, by ingredient, by product). This is the hub the use-case pages shoot arrows from.

  3. "Most valuable to craft, per profession" page. Jobs-page-like layout but leaning hard into the Supply-gaps style signal: for every profession, the highest-value things to craft. Open question Kai flagged: the definition of "valuable." Propose a definition (candidates: unit sell price, margin over ingredient+labor cost, unmet demand from buy orders / supply gaps, currency volume moved, or a blend) and recommend one with reasoning. This page is currently unbuilt precisely because the definition is unsettled, so settling it is the point.

  4. Use-case pages hub. Kai wants roughly a dozen use-case-focused pages, but they do NOT each get a homepage card. They share ONE page that lists them all (this is NOT the recipes page). Design that hub + the shape of an individual use-case page. Start with "how you should price <THING>" as the first use case, using Eco Gnome / Eco Calc / Eco Price Calculator as the inspiration for what a pricing page shows (cost breakdown, fair price band, current market comparison, margin). Then enumerate the other ~11 candidate use cases as a ranked list.

  5. Further practical-usefulness ideas. Beyond the above, propose other ways to make the site something players keep open, grounded in the incumbents.

Deliverable

  • A design doc at docs/practical-usefulness.md (or similar) covering 1-5, with the "valuable" definition recommended and the pricing-page spec concrete enough to build.
  • A ranked, scoped list of proposed follow-up issues (recipes page, value-per-profession page, use-case hub + pricing page, plus any exporter gaps found) that Kai can dispatch as engineer runs.
  • Post the design summary as a comment on this issue and commit the doc. Do not build the pages in this ticket.
Design the next layer of eco-app: turn it from a read-only mirror into a tool Eco players actually reach for. Filed from a batch of eco-app feedback Kai handed the director surface. This is a design/consult ticket. The deliverable is a design doc committed under `docs/` plus a set of proposed, scoped follow-up issues, not code. ## The bet Eco players love economy tools even when usability is near zero. Eco Gnome is basically unusable and people still use it. Eco Calc (the website) and Eco Price Calculator (the mods) are the same: meh usability, real demand. The opportunity is to mine what those tools *do* and deliver it with a better surface. eco-app already hydrates the underlying data (the crafting atlas, trades ledger, market, stores, fair-price, currency) through `src/eco_mcp_app/*` and the eco MCP tool family. ## What to design 1. **Mine the incumbents.** Catalog the concrete jobs players do with Eco Gnome, Eco Calc, and Eco Price Calculator (recipe cost roll-ups, margin/profit calc, labor + calorie cost, sell-price suggestion, dependency trees, "is this worth crafting"). Map each job to the data eco-app already has (`crafting.py` atlas, `logistics.py`, `market.py`, `stores.py`, `fair_price.py`, `trades.py`) and flag any gap the exporters do not yet cover. 2. **Recipes page (grow this first).** A recipe surface analogous to `/items` but recipe-shaped: ingredients in, product out, station, labor. Design its data model (the crafting atlas / eco MCP `get_eco_crafting_atlas` is already hydrating this) and its filters (by profession, by station, by ingredient, by product). This is the hub the use-case pages shoot arrows from. 3. **"Most valuable to craft, per profession" page.** Jobs-page-like layout but leaning hard into the Supply-gaps style signal: for every profession, the highest-value things to craft. **Open question Kai flagged: the definition of "valuable."** Propose a definition (candidates: unit sell price, margin over ingredient+labor cost, unmet demand from buy orders / supply gaps, currency volume moved, or a blend) and recommend one with reasoning. This page is currently unbuilt precisely because the definition is unsettled, so settling it is the point. 4. **Use-case pages hub.** Kai wants roughly a dozen use-case-focused pages, but they do NOT each get a homepage card. They share ONE page that lists them all (this is NOT the recipes page). Design that hub + the shape of an individual use-case page. **Start with "how you should price &lt;THING&gt;"** as the first use case, using Eco Gnome / Eco Calc / Eco Price Calculator as the inspiration for what a pricing page shows (cost breakdown, fair price band, current market comparison, margin). Then enumerate the other ~11 candidate use cases as a ranked list. 5. **Further practical-usefulness ideas.** Beyond the above, propose other ways to make the site something players keep open, grounded in the incumbents. ## Deliverable - A design doc at `docs/practical-usefulness.md` (or similar) covering 1-5, with the "valuable" definition recommended and the pricing-page spec concrete enough to build. - A ranked, scoped list of proposed follow-up issues (recipes page, value-per-profession page, use-case hub + pricing page, plus any exporter gaps found) that Kai can dispatch as engineer runs. - Post the design summary as a comment on this issue and commit the doc. Do not build the pages in this ticket.
Member

🔎 ward agent advisor

ward agent advisor --driver claude ran a one-shot standard research pass on this question:

Research and produce the practical-usefulness design described in this issue: mine Eco Gnome / Eco Calc / Eco Price Calculator for the concrete jobs players do, map each to the data eco-app already hydrates (crafting.py atlas, logistics.py, market.py, stores.py, fair_price.py, trades.py) and flag exporter gaps, design the recipes page + its data model and filters, recommend a concrete definition of 'valuable' for the value-per-profession page with reasoning, and spec the shared use-case-pages hub starting with the 'how to price ' page. Post the design plus a ranked list of scoped follow-up engineer issues as a comment on this issue.


Design: practical-usefulness layer (eco-app#98)

Research deliverable for the design/consult ticket. This is the design doc content to commit at docs/practical-usefulness.md plus a ranked follow-up list. All work lands in coilyco-gaming/eco-app (data-export mods paired with Python consumers live in mods/ here per AGENTS.md, not eco-mods), so there is no cross-repo fan-out - the follow-ups below are meant to be filed as sibling eco-app issues.

TL;DR - the reframe that drives everything

The incumbents (Eco Gnome, Eco Calc, Eco Price Calculator) are at their core recursive recipe-cost calculators: they take a recipe, roll up ingredient costs recursively, add labor and calorie cost, and emit a suggested sell price plus margin. I read the data layer end to end and the load-bearing finding is:

  • eco-app has the market/demand half and none of the recipe/cost half. market.py, trades.py, logistics.py, stores.py give rich price, volume, and unmet-demand signals from the action-exporter CSVs and live store offers. But there is no recipe definition anywhere (ingredients -> product, quantities, station, required skill, labor, calories) and no cost or margin roll-up.
  • crafting.py is not a recipe atlas. Despite the issue's framing, get_eco_crafting_atlas aggregates production events (what was crafted/gathered, by station/citizen, plus sankey flows) from ItemCraftedAction/HarvestOrHunt/ChopTree/DigOrMine CSVs. It has no Recipe/Ingredient/Skill/Labor/Calorie schema. It is a leaderboard, not a bill-of-materials.
  • fair_price.py is a FRED commodity benchmark, not a cost model. It pegs exactly 5 hard-coded items (copper, wheat, lumber PPI, iron, WTI oil) to real-world FRED series and reports trend, optionally labeling an in-game median over/under/fair. No ingredient/labor/calorie roll-up, no margin.
  • No profession attribution exists in any economy module. The jobs mod's /api/v1/skills (consumed by eco_spec_tracker) knows people -> skills -> levels, but nothing maps a recipe -> required skill, which is what "per profession" needs.

Consequence: the single keystone that unblocks the recipes page, the value-per-profession page, and the full pricing page is a recipe-definition exporter (a mods/ endpoint that dumps Eco's RecipeManager registry, plus a Python consumer and /preview/recipes.json). Everything recipe-shaped is gated on it. The demand-side use cases can ship now on data we already have.


1. Mining the incumbents -> data map + exporter gaps

Concrete jobs players do with the three tools, each mapped to eco-app data and the gap:

Incumbent job eco-app data today Status / gap
Recursive recipe cost roll-up none (no recipe BOM) GAP: recipe exporter + cost engine
Labor + calorie cost of a craft none GAP: recipe exporter must carry labor/calories
Dependency / crafting tree (BOM) crafting.py sankey is event-flows, not BOM GAP: recipe exporter (ingredient edges)
Margin / "is this worth crafting" none (no cost side) GAP: cost engine (depends on recipe exporter)
Sell-price suggestion market.py median/latest; fair_price FRED (5 items) Partial: have market median as a price anchor; need cost for a margin-based suggestion
Current market price comparison market.py buckets/median, stores.py avgUnitPrice, logistics.py cheapest/resale HAVE IT
What is in demand right now logistics.py supplyGaps (demandQty, buyerCount, reason) HAVE IT
Currency volume / liquidity per item trades.py byItem[i] = [item, tradeCount, currencyVolume] HAVE IT
Arbitrage (buy low / sell high) logistics.py arbitrage (spread, opportunity = spread x volume) HAVE IT
Which profession/skill a recipe needs jobs /api/v1/skills has people->skill, not recipe->skill GAP: recipe exporter must carry required skill
Fair-price band for an arbitrary item market.py per-day price buckets (median/min/max) HAVE IT (band = market median +/- IQR from buckets)

Net exporter gaps found (one root, three consequences):

  • Root gap - recipe registry is not exported. Eco defines recipes in C# (RecipeManager) and the server holds them, but no CSV/JSON exporter surfaces them. The datasets survey (docs/datasets/README.md) already notes the Eco source is checked out for exactly this class of "data the server holds but does not export." This is the keystone follow-up.
  • Consequence gaps (all fall out of the root): no bottom-up cost/margin, no recipe->skill (profession) mapping, no BOM dependency tree. Solving the root solves all three.

2. Recipes page (grow this first)

A recipe surface analogous to /items -> /item, using the established SPA patterns: URL-driven filter, query-param detail key, one hub card, optional nav entry.

Data model (the DTO the recipe exporter must produce)

This does not exist yet - it is the target contract for follow-up A. Shape it camelCase to match the /preview/*.json convention:

Recipe {
  id                                  // stable recipe id
  product: { item, pretty, quantity }
  byproducts: [{ item, pretty, quantity }]
  ingredients: [{ item, pretty, quantity, isTag }]   // isTag => category input (e.g. "Wood")
  station:  { item, pretty }
  skill:    { name, level }           // required specialty + level -> the profession join
  laborCost                           // calories to craft
  craftMinutes                        // time cost
  tableTierRequired
  isDefault, variantOf                // Eco recipe variants
}
RecipeIndex { fetchedAtISO, recipes: [RecipeSummary], stations: [...], skills: [...] }

Surfaces

  • /recipes - list page modeled on pages/Items.tsx: URL-driven ?q= filter (client-side lowercase-includes on product/ingredient pretty names, capped like LIST_ROWS), rows link to /recipe?id=.... Numbers via lib/format.ts formatCount/prettifyEcoName.
  • /recipe?id=... - detail modeled on pages/Item.tsx (query-param key + the fetched.id === id stale-guard). Shows the BOM tree, station, required skill+level, labor/calorie/time cost, and cross-links: product's current market price (market.py), who has crafted it (crafting.py by_crafted), and where to buy/sell it (logistics.py).

Filters (the hub the use-case pages shoot arrows from)

  • By profession/skill - group/filter on skill.name (needs the exporter's skill field).
  • By station - filter on station.item.
  • By ingredient (reverse lookup) - "what can I make with X" - the highest-value filter, index recipes by each ingredient.
  • By product - the default search.
  • By table tier - tableTierRequired.

Follow the decoupled-routing rule: add the <Route> in App.tsx, add exactly one hub card in Home.tsx, add a nav link in Layout.tsx only if it earns primary nav. /recipe stays URL-only (reached from /recipes), mirroring /item.


This is the flagged open question. My recommendation, with reasoning:

North star: margin-weighted opportunity = expected profit per unit x how much of it you can actually sell. Ship it in two phases because the profit term is blocked on the recipe exporter.

Reasoning through the candidates:

  • Unit sell price alone - rewards expensive items nobody buys (a 500-currency item with zero buyers ranks top). Rejected as the sole signal.
  • Currency volume moved alone - rewards cheap high-churn staples (wood, dirt) and buries the genuinely profitable niche crafts. Good as a liquidity tie-breaker, wrong as the headline.
  • Unmet demand from buy orders / supply gaps - the cleanest "will I be able to sell this" signal, and it is exactly the Supply-gaps signal Kai already likes in pages/Trade.tsx. This is the demand term.
  • Margin over ingredient + labor cost - the theoretically correct "valuable to craft" answer, and what the incumbents compute. But it needs the cost engine, which needs the recipe exporter. Cannot ship day one.

Recommended formula:

  • Phase 1 (data we have today) - revenue opportunity:
    opportunity = medianUnitPrice (market.py) x unmetDemandQty (logistics.py supplyGaps.demandQty), boosted when reason in {no_supply, thin_supply}, and gated by a liquidity floor from trades.py byItem currency volume so a single thin trade cannot top the board. This ranks by realizable revenue, and the page must label it honestly as revenue, not profit.
  • Phase 2 (after the recipe exporter + cost engine) - true margin:
    swap medianUnitPrice for margin = medianUnitPrice - rolledUpCost, where rolledUpCost is the recursive ingredient + labor + calorie roll-up. Same demand weighting. Now it answers the incumbents' actual question: "what earns me the most money to craft right now."

Grouping by profession requires the recipe -> skill mapping, so the whole page (even Phase 1) is gated on the recipe exporter for the grouping axis, even though the ranking signal is available now. Layout: model on pages/Jobs.tsx - one section per profession/specialty, reuse RankList bars, and reuse the SupplyGapRow glyph+label+color severity treatment for the "why this ranks" callouts (accessibility: never color alone).


4. Use-case pages hub + "how to price X"

The hub

  • /uses - one page listing all ~12 use cases as cards. This is the only homepage card the whole family gets (one hub card in Home.tsx, not one per use case). Individual use-case pages are URL-only, reached from the hub, mirroring how /item is only reached from /items. This is explicitly not the recipes page - /recipes is the data hub, /uses is the task hub.
  • Shape of an individual use-case page: a hero stating the job, one primary input (usually an item picker), then task-specific panels built by composing existing /preview/*.json clients. Each degrades independently via fetchJsonOrNull so one dead panel does not blank the page.

First use case - /uses/price "How should I price "

Input: an item. Panels, inspired by Eco Gnome / Eco Calc / Eco Price Calculator:

  • Cost breakdown - recursive ingredient cost + labor + calorie cost from the cost engine. Phase 2 (blocked on recipe exporter). Until then, show a "cost model pending" note and lead with the market panels below, which are fully buildable now.
  • Fair-price band - for arbitrary items this is the in-game market median +/- IQR computed from market.py price buckets (median/min/max per day). For the 5 FRED-pegged commodities, overlay fair_price.py's real-world benchmark and over/under/fair verdict as a bonus. This makes "fair price band" work for every item, not just 5.
  • Current market comparison - cheapest sell and best buy from logistics.py (cheapest/resale), plus trend/trendDeltaPct from market.py for direction.
  • Suggested price + margin - Phase 1: suggest the market median and show volume/liquidity so the player can undercut or hold. Phase 2: suggest cost x target-markup and show the resulting margin against the market band (the true Eco Gnome parity feature).

The other ~11 use cases, ranked (value x buildability on current data)

Tier A - buildable now on data we already hydrate:

  1. How to price X (above) - the anchor.
  2. What is in demand right now - logistics.py supplyGaps, the unmet buy orders, ranked. Pairs directly with #3's page.
  3. Where to buy X cheapest / sell X highest - logistics.py cheapest/resale boards for one item.
  4. Arbitrage finder - logistics.py arbitrage (spread x volume), "buy here, sell there."
  5. Is my shop priced right - paste a store, compare its avgUnitPrice (stores.py) against market.py median per item.
  6. What is holding its value - fair_price.py + currency.py inflation/trend watch for the commodity items.

Tier B - unlocked by the recipe exporter (follow-up A) and cost engine (follow-up C):

  1. Is this worth crafting - margin check on one recipe (cost vs market median).
  2. Cheapest way to get X - buy-vs-craft: compare market buy price against rolled-up craft cost down the BOM.
  3. What should I make with my skill - the value-per-profession page as a personal use case.
  4. Supply-chain planner - full BOM for a target item, what to stockpile and at which stations.
  5. Calorie / labor budget planner - "with N calories, the highest-margin things I can craft."

Tier C:

  1. New-player "which profession pays best right now" - value-per-profession rolled up to a per-profession headline number.

5. Further practical-usefulness ideas

Grounded in the incumbents and in what eco-app uniquely has (live colocated server data the incumbents lack):

  • Watchlist / alerts - extend watchers.py from trade watchers to price/demand alerts: "tell me when X crosses price Y" or "when a buy order appears for my product." This is the sticky "keep the tab open" feature Eco Gnome cannot do because it has no live server feed.
  • Shareable price cards - the SPA is already URL-driven and deep-linkable. A /uses/price?item=X link that renders a clean cost/price card is a drop-in-Discord artifact, which is how players actually share Eco Gnome screenshots today, but live and linkable.
  • My-shop dashboard - one page keyed on a store, showing every item's margin vs market and flagging underpriced stock, built from stores.py + market.py.
  • Discord bot / read-only API parity - the /preview/*.json plane already is a clean data API. A thin Discord command surface over it ("/price copper") reaches players where they coordinate.
  • Import-your-recipe-book - once the recipe exporter lands, let a player filter recipes to the skills they actually have (join to jobs /api/v1/skills), turning the generic recipes page into a personal "what can I make" view.

Ranked, scoped follow-up issues (to file as eco-app siblings)

Ordered by dependency. A blocks everything recipe-shaped, so it goes first.

A. Recipe-definition exporter (keystone). New mods/ endpoint that dumps Eco's RecipeManager registry (product, ingredients+quantities, station, required skill+level, labor, calories, time, variants) as JSON, a Python consumer (recipes.py) mirroring the crafting.py/trades.py streaming pattern, and a /preview/recipes.json surface. Source the shape from the Eco checkout noted in docs/datasets/README.md. Unblocks B, C, E and the profession grouping in D. No upstream dependency. Highest priority.

B. Recipes page (/recipes + /recipe?id=). List + detail per section 2, filters by profession/station/ingredient/product/tier. Depends on A for the data. Model on pages/Items.tsx/Item.tsx + a new lib/recipesApi.ts.

C. Bottom-up cost roll-up engine. Recursive ingredient-cost + labor + calorie roll-up over the recipe BOM, resolving leaf ingredient prices from market.py median. Powers margin everywhere. Depends on A. Pure Python, testable under tests/.

D. Value-per-profession page. Section 3. Ship Phase 1 (revenue-opportunity ranking) as soon as A lands (A provides profession grouping), then upgrade to margin once C lands. Depends on A (grouping), enhanced by C (margin). Model on pages/Jobs.tsx, reuse RankList + the SupplyGapRow severity treatment.

E. Use-case hub (/uses) + "how to price X" (/uses/price). Section 4. The hub + Tier-A market/fair-price/logistics panels are buildable now with no dependency - ship the demand-side pricing page first. The cost-breakdown and margin panels light up when C lands. One hub card in Home.tsx, use-case pages URL-only. This can start in parallel with A.

F. Demand-side use-case pages (Tier A: what-is-in-demand, where-to-buy/sell, arbitrage, shop-check). logistics.py/market.py/stores.py only, no dependency - cheap wins that fill the hub while A is in flight.

Suggested dispatch order: A and E/F in parallel first (A is the long pole, E/F ship value immediately with no blocker), then B, C, D once A lands, then the Tier-B use-case pages once C lands.

Note on the deliverable

The issue asks for a doc committed at docs/practical-usefulness.md. This comment is that doc's content. As a research/consult run I am not committing code or the doc - dispatch an engineer run to commit this design and open follow-ups A-F above.


Researched and posted automatically by ward agent advisor --driver claude (ward#179). This is one-shot research, not a carried change - verify before acting on it.

— Claude (she/her), via ward agent

### 🔎 ward agent advisor `ward agent advisor --driver claude` ran a one-shot **standard** research pass on this question: > Research and produce the practical-usefulness design described in this issue: mine Eco Gnome / Eco Calc / Eco Price Calculator for the concrete jobs players do, map each to the data eco-app already hydrates (crafting.py atlas, logistics.py, market.py, stores.py, fair_price.py, trades.py) and flag exporter gaps, design the recipes page + its data model and filters, recommend a concrete definition of 'valuable' for the value-per-profession page with reasoning, and spec the shared use-case-pages hub starting with the 'how to price <THING>' page. Post the design plus a ranked list of scoped follow-up engineer issues as a comment on this issue. --- # Design: practical-usefulness layer (eco-app#98) Research deliverable for the design/consult ticket. This is the design doc content to commit at `docs/practical-usefulness.md` plus a ranked follow-up list. All work lands in **coilyco-gaming/eco-app** (data-export mods paired with Python consumers live in `mods/` here per AGENTS.md, not eco-mods), so there is no cross-repo fan-out - the follow-ups below are meant to be filed as sibling eco-app issues. ## TL;DR - the reframe that drives everything The incumbents (Eco Gnome, Eco Calc, Eco Price Calculator) are at their core **recursive recipe-cost calculators**: they take a recipe, roll up ingredient costs recursively, add labor and calorie cost, and emit a suggested sell price plus margin. I read the data layer end to end and the load-bearing finding is: - **eco-app has the market/demand half and none of the recipe/cost half.** `market.py`, `trades.py`, `logistics.py`, `stores.py` give rich price, volume, and unmet-demand signals from the action-exporter CSVs and live store offers. But there is **no recipe definition anywhere** (ingredients -> product, quantities, station, required skill, labor, calories) and **no cost or margin roll-up**. - **`crafting.py` is not a recipe atlas.** Despite the issue's framing, `get_eco_crafting_atlas` aggregates production *events* (what was crafted/gathered, by station/citizen, plus sankey flows) from `ItemCraftedAction`/`HarvestOrHunt`/`ChopTree`/`DigOrMine` CSVs. It has no `Recipe`/`Ingredient`/`Skill`/`Labor`/`Calorie` schema. It is a leaderboard, not a bill-of-materials. - **`fair_price.py` is a FRED commodity benchmark, not a cost model.** It pegs exactly 5 hard-coded items (copper, wheat, lumber PPI, iron, WTI oil) to real-world FRED series and reports trend, optionally labeling an in-game median over/under/fair. No ingredient/labor/calorie roll-up, no margin. - **No profession attribution exists in any economy module.** The jobs mod's `/api/v1/skills` (consumed by `eco_spec_tracker`) knows people -> skills -> levels, but nothing maps a **recipe -> required skill**, which is what "per profession" needs. **Consequence:** the single keystone that unblocks the recipes page, the value-per-profession page, and the full pricing page is a **recipe-definition exporter** (a `mods/` endpoint that dumps Eco's `RecipeManager` registry, plus a Python consumer and `/preview/recipes.json`). Everything recipe-shaped is gated on it. The demand-side use cases can ship now on data we already have. --- ## 1. Mining the incumbents -> data map + exporter gaps Concrete jobs players do with the three tools, each mapped to eco-app data and the gap: | Incumbent job | eco-app data today | Status / gap | |---|---|---| | Recursive recipe cost roll-up | none (no recipe BOM) | **GAP: recipe exporter + cost engine** | | Labor + calorie cost of a craft | none | **GAP: recipe exporter must carry labor/calories** | | Dependency / crafting tree (BOM) | `crafting.py` sankey is event-flows, not BOM | **GAP: recipe exporter (ingredient edges)** | | Margin / "is this worth crafting" | none (no cost side) | **GAP: cost engine (depends on recipe exporter)** | | Sell-price suggestion | `market.py` median/latest; `fair_price` FRED (5 items) | **Partial**: have market median as a price anchor; need cost for a margin-based suggestion | | Current market price comparison | `market.py` buckets/median, `stores.py` avgUnitPrice, `logistics.py` cheapest/resale | **HAVE IT** | | What is in demand right now | `logistics.py` `supplyGaps` (demandQty, buyerCount, reason) | **HAVE IT** | | Currency volume / liquidity per item | `trades.py` `byItem[i] = [item, tradeCount, currencyVolume]` | **HAVE IT** | | Arbitrage (buy low / sell high) | `logistics.py` `arbitrage` (spread, opportunity = spread x volume) | **HAVE IT** | | Which profession/skill a recipe needs | jobs `/api/v1/skills` has people->skill, not recipe->skill | **GAP: recipe exporter must carry required skill** | | Fair-price band for an arbitrary item | `market.py` per-day price buckets (median/min/max) | **HAVE IT** (band = market median +/- IQR from buckets) | **Net exporter gaps found (one root, three consequences):** - **Root gap - recipe registry is not exported.** Eco defines recipes in C# (`RecipeManager`) and the server holds them, but no CSV/JSON exporter surfaces them. The datasets survey (`docs/datasets/README.md`) already notes the Eco source is checked out for exactly this class of "data the server holds but does not export." This is the keystone follow-up. - **Consequence gaps** (all fall out of the root): no bottom-up cost/margin, no recipe->skill (profession) mapping, no BOM dependency tree. Solving the root solves all three. --- ## 2. Recipes page (grow this first) A recipe surface analogous to `/items` -> `/item`, using the established SPA patterns: URL-driven filter, query-param detail key, one hub card, optional nav entry. ### Data model (the DTO the recipe exporter must produce) This does not exist yet - it is the target contract for follow-up **A**. Shape it camelCase to match the `/preview/*.json` convention: ``` Recipe { id // stable recipe id product: { item, pretty, quantity } byproducts: [{ item, pretty, quantity }] ingredients: [{ item, pretty, quantity, isTag }] // isTag => category input (e.g. "Wood") station: { item, pretty } skill: { name, level } // required specialty + level -> the profession join laborCost // calories to craft craftMinutes // time cost tableTierRequired isDefault, variantOf // Eco recipe variants } RecipeIndex { fetchedAtISO, recipes: [RecipeSummary], stations: [...], skills: [...] } ``` ### Surfaces - **`/recipes`** - list page modeled on `pages/Items.tsx`: URL-driven `?q=` filter (client-side lowercase-includes on product/ingredient pretty names, capped like `LIST_ROWS`), rows link to `/recipe?id=...`. Numbers via `lib/format.ts` `formatCount`/`prettifyEcoName`. - **`/recipe?id=...`** - detail modeled on `pages/Item.tsx` (query-param key + the `fetched.id === id` stale-guard). Shows the BOM tree, station, required skill+level, labor/calorie/time cost, and cross-links: product's current market price (`market.py`), who has crafted it (`crafting.py` `by_crafted`), and where to buy/sell it (`logistics.py`). ### Filters (the hub the use-case pages shoot arrows from) - **By profession/skill** - group/filter on `skill.name` (needs the exporter's skill field). - **By station** - filter on `station.item`. - **By ingredient (reverse lookup)** - "what can I make with X" - the highest-value filter, index recipes by each ingredient. - **By product** - the default search. - **By table tier** - `tableTierRequired`. Follow the decoupled-routing rule: add the `<Route>` in `App.tsx`, add exactly one hub card in `Home.tsx`, add a nav link in `Layout.tsx` only if it earns primary nav. `/recipe` stays URL-only (reached from `/recipes`), mirroring `/item`. --- ## 3. "Most valuable to craft, per profession" - recommended definition of "valuable" This is the flagged open question. My recommendation, with reasoning: **North star: margin-weighted opportunity = expected profit per unit x how much of it you can actually sell. Ship it in two phases because the profit term is blocked on the recipe exporter.** Reasoning through the candidates: - **Unit sell price alone** - rewards expensive items nobody buys (a 500-currency item with zero buyers ranks top). Rejected as the sole signal. - **Currency volume moved alone** - rewards cheap high-churn staples (wood, dirt) and buries the genuinely profitable niche crafts. Good as a liquidity tie-breaker, wrong as the headline. - **Unmet demand from buy orders / supply gaps** - the cleanest "will I be able to sell this" signal, and it is exactly the Supply-gaps signal Kai already likes in `pages/Trade.tsx`. This is the demand term. - **Margin over ingredient + labor cost** - the theoretically correct "valuable to *craft*" answer, and what the incumbents compute. But it needs the cost engine, which needs the recipe exporter. Cannot ship day one. **Recommended formula:** - **Phase 1 (data we have today) - revenue opportunity:** `opportunity = medianUnitPrice (market.py) x unmetDemandQty (logistics.py supplyGaps.demandQty)`, boosted when `reason in {no_supply, thin_supply}`, and gated by a liquidity floor from `trades.py byItem` currency volume so a single thin trade cannot top the board. This ranks by realizable *revenue*, and the page must label it honestly as revenue, not profit. - **Phase 2 (after the recipe exporter + cost engine) - true margin:** swap `medianUnitPrice` for `margin = medianUnitPrice - rolledUpCost`, where `rolledUpCost` is the recursive ingredient + labor + calorie roll-up. Same demand weighting. Now it answers the incumbents' actual question: "what earns me the most money to craft right now." **Grouping by profession** requires the recipe -> skill mapping, so the whole page (even Phase 1) is gated on the recipe exporter for the *grouping* axis, even though the ranking signal is available now. Layout: model on `pages/Jobs.tsx` - one section per profession/specialty, reuse `RankList` bars, and reuse the `SupplyGapRow` glyph+label+color severity treatment for the "why this ranks" callouts (accessibility: never color alone). --- ## 4. Use-case pages hub + "how to price X" ### The hub - **`/uses`** - one page listing all ~12 use cases as cards. This is the only homepage card the whole family gets (one hub card in `Home.tsx`, not one per use case). Individual use-case pages are URL-only, reached from the hub, mirroring how `/item` is only reached from `/items`. This is explicitly **not** the recipes page - `/recipes` is the data hub, `/uses` is the task hub. - **Shape of an individual use-case page:** a hero stating the job, one primary input (usually an item picker), then task-specific panels built by composing existing `/preview/*.json` clients. Each degrades independently via `fetchJsonOrNull` so one dead panel does not blank the page. ### First use case - `/uses/price` "How should I price <THING>" Input: an item. Panels, inspired by Eco Gnome / Eco Calc / Eco Price Calculator: - **Cost breakdown** - recursive ingredient cost + labor + calorie cost from the cost engine. **Phase 2** (blocked on recipe exporter). Until then, show a "cost model pending" note and lead with the market panels below, which are fully buildable now. - **Fair-price band** - for arbitrary items this is the **in-game market median +/- IQR** computed from `market.py` price `buckets` (median/min/max per day). For the 5 FRED-pegged commodities, overlay `fair_price.py`'s real-world benchmark and over/under/fair verdict as a bonus. This makes "fair price band" work for every item, not just 5. - **Current market comparison** - cheapest sell and best buy from `logistics.py` (`cheapest`/`resale`), plus `trend`/`trendDeltaPct` from `market.py` for direction. - **Suggested price + margin** - Phase 1: suggest the market median and show volume/liquidity so the player can undercut or hold. Phase 2: suggest cost x target-markup and show the resulting margin against the market band (the true Eco Gnome parity feature). ### The other ~11 use cases, ranked (value x buildability on current data) Tier A - buildable now on data we already hydrate: 1. **How to price X** (above) - the anchor. 2. **What is in demand right now** - `logistics.py supplyGaps`, the unmet buy orders, ranked. Pairs directly with #3's page. 3. **Where to buy X cheapest / sell X highest** - `logistics.py` cheapest/resale boards for one item. 4. **Arbitrage finder** - `logistics.py arbitrage` (spread x volume), "buy here, sell there." 5. **Is my shop priced right** - paste a store, compare its `avgUnitPrice` (`stores.py`) against `market.py` median per item. 6. **What is holding its value** - `fair_price.py` + `currency.py` inflation/trend watch for the commodity items. Tier B - unlocked by the recipe exporter (follow-up A) and cost engine (follow-up C): 7. **Is this worth crafting** - margin check on one recipe (cost vs market median). 8. **Cheapest way to get X** - buy-vs-craft: compare market buy price against rolled-up craft cost down the BOM. 9. **What should I make with my skill** - the value-per-profession page as a personal use case. 10. **Supply-chain planner** - full BOM for a target item, what to stockpile and at which stations. 11. **Calorie / labor budget planner** - "with N calories, the highest-margin things I can craft." Tier C: 12. **New-player "which profession pays best right now"** - value-per-profession rolled up to a per-profession headline number. --- ## 5. Further practical-usefulness ideas Grounded in the incumbents and in what eco-app uniquely has (live colocated server data the incumbents lack): - **Watchlist / alerts** - extend `watchers.py` from trade watchers to price/demand alerts: "tell me when X crosses price Y" or "when a buy order appears for my product." This is the sticky "keep the tab open" feature Eco Gnome cannot do because it has no live server feed. - **Shareable price cards** - the SPA is already URL-driven and deep-linkable. A `/uses/price?item=X` link that renders a clean cost/price card is a drop-in-Discord artifact, which is how players actually share Eco Gnome screenshots today, but live and linkable. - **My-shop dashboard** - one page keyed on a store, showing every item's margin vs market and flagging underpriced stock, built from `stores.py` + `market.py`. - **Discord bot / read-only API parity** - the `/preview/*.json` plane already is a clean data API. A thin Discord command surface over it ("/price copper") reaches players where they coordinate. - **Import-your-recipe-book** - once the recipe exporter lands, let a player filter recipes to the skills they actually have (join to jobs `/api/v1/skills`), turning the generic recipes page into a personal "what can I make" view. --- ## Ranked, scoped follow-up issues (to file as eco-app siblings) Ordered by dependency. A blocks everything recipe-shaped, so it goes first. **A. Recipe-definition exporter (keystone).** New `mods/` endpoint that dumps Eco's `RecipeManager` registry (product, ingredients+quantities, station, required skill+level, labor, calories, time, variants) as JSON, a Python consumer (`recipes.py`) mirroring the `crafting.py`/`trades.py` streaming pattern, and a `/preview/recipes.json` surface. Source the shape from the Eco checkout noted in `docs/datasets/README.md`. **Unblocks B, C, E and the profession grouping in D.** No upstream dependency. Highest priority. **B. Recipes page (`/recipes` + `/recipe?id=`).** List + detail per section 2, filters by profession/station/ingredient/product/tier. **Depends on A** for the data. Model on `pages/Items.tsx`/`Item.tsx` + a new `lib/recipesApi.ts`. **C. Bottom-up cost roll-up engine.** Recursive ingredient-cost + labor + calorie roll-up over the recipe BOM, resolving leaf ingredient prices from `market.py` median. Powers margin everywhere. **Depends on A.** Pure Python, testable under `tests/`. **D. Value-per-profession page.** Section 3. Ship Phase 1 (revenue-opportunity ranking) as soon as A lands (A provides profession grouping), then upgrade to margin once C lands. **Depends on A** (grouping), **enhanced by C** (margin). Model on `pages/Jobs.tsx`, reuse `RankList` + the `SupplyGapRow` severity treatment. **E. Use-case hub (`/uses`) + "how to price X" (`/uses/price`).** Section 4. The hub + Tier-A market/fair-price/logistics panels are **buildable now with no dependency** - ship the demand-side pricing page first. The cost-breakdown and margin panels light up when C lands. One hub card in `Home.tsx`, use-case pages URL-only. This can start in parallel with A. **F. Demand-side use-case pages (Tier A: what-is-in-demand, where-to-buy/sell, arbitrage, shop-check).** `logistics.py`/`market.py`/`stores.py` only, **no dependency** - cheap wins that fill the hub while A is in flight. Suggested dispatch order: **A and E/F in parallel first** (A is the long pole, E/F ship value immediately with no blocker), then **B, C, D** once A lands, then the Tier-B use-case pages once C lands. ### Note on the deliverable The issue asks for a doc committed at `docs/practical-usefulness.md`. This comment is that doc's content. As a research/consult run I am not committing code or the doc - dispatch an engineer run to commit this design and open follow-ups A-F above. --- Researched and posted automatically by `ward agent advisor --driver claude` (ward#179). This is one-shot research, not a carried change - verify before acting on it. <!-- ward-agent-reply --> <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Owner

Director follow-up (correcting the keystone in the design above): Eco Gnome is itself a recipe exporter, which reshapes follow-up A.

  • eco-gnome-mod (https://github.com/Eco-Gnome/eco-gnome-mod) is a server-side DataExporter that dumps a server's modded recipes, skills, and items - exactly the recipe-definition data the design calls the keystone. The eco-gnome image also bundles ecocraft/eco_gnome_data.json (vanilla item/recipe data). See docs/calculator.md and #40.
  • So follow-up A should NOT be 'write a bespoke Eco RecipeManager dumper from scratch'. It should be 'ingest eco-gnome-mod's existing recipe/skill/item export (or the bundled eco_gnome_data.json shape) into a Python consumer + /preview/recipes.json'. Reuse the MIT tool's exporter rather than reinventing it. This makes the long pole much shorter.
  • Caveat that stands: eco-app does not hydrate this data today - the current Eco Gnome integration is only the homepage link-out card (Home.tsx), and the self-host + DataExporter path (#40) is blocked on kai-server mod-ops (ward#585 / eco-ops#30). So A's real work is landing the ingest path, which may ride on the same #40 mod rollout.

Everything downstream (B recipes page, C cost engine, D value-per-profession grouping) is unchanged - it just consumes A's recipe data whether A builds or ingests the exporter.

Director follow-up (correcting the keystone in the design above): **Eco Gnome is itself a recipe exporter**, which reshapes follow-up A. - `eco-gnome-mod` (https://github.com/Eco-Gnome/eco-gnome-mod) is a server-side DataExporter that dumps a server's **modded recipes, skills, and items** - exactly the recipe-definition data the design calls the keystone. The eco-gnome image also bundles `ecocraft/eco_gnome_data.json` (vanilla item/recipe data). See `docs/calculator.md` and #40. - So follow-up **A** should NOT be 'write a bespoke Eco `RecipeManager` dumper from scratch'. It should be 'ingest eco-gnome-mod's existing recipe/skill/item export (or the bundled `eco_gnome_data.json` shape) into a Python consumer + `/preview/recipes.json`'. Reuse the MIT tool's exporter rather than reinventing it. This makes the long pole much shorter. - Caveat that stands: eco-app does not hydrate this data **today** - the current Eco Gnome integration is only the homepage link-out card (`Home.tsx`), and the self-host + DataExporter path (#40) is blocked on kai-server mod-ops (ward#585 / eco-ops#30). So A's real work is landing the ingest path, which may ride on the same #40 mod rollout. Everything downstream (B recipes page, C cost engine, D value-per-profession grouping) is unchanged - it just consumes A's recipe data whether A builds or ingests the exporter.
Author
Owner

Dispatched the no-dependency slice as #99 (the /uses hub + the four demand-side use-case pages: what's-in-demand, buy/sell, arbitrage, shop-check). Kai is starting the practical-usefulness layer here since it needs no recipe data. The recipe-gated follow-ups (A ingest eco-gnome export, B recipes page, C cost engine, D value-per-profession, E 'how to price X') stay queued behind the recipe exporter.

Dispatched the no-dependency slice as #99 (the `/uses` hub + the four demand-side use-case pages: what's-in-demand, buy/sell, arbitrage, shop-check). Kai is starting the practical-usefulness layer here since it needs no recipe data. The recipe-gated follow-ups (A ingest eco-gnome export, B recipes page, C cost engine, D value-per-profession, E 'how to price X') stay queued behind the recipe exporter.
Author
Owner

Recipe/pricing roadmap now filed as tracked issues:

  • #100 - A, recipe data ingest (keystone), gated on the probe below.
  • #101 - B, recipes browse page (/recipes + /recipe). Depends on #100.
  • #102 - C, bottom-up cost roll-up engine. Depends on #100.
  • #103 - D, most-valuable-to-craft per profession. Depends on #100, enhanced by #102.
  • #104 - E, 'how to price X' page (/uses/price), under the #99 hub. Market panels ship early, cost/margin gated on #102.
  • #105 - probe: what recipe data is Eco Gnome actually giving us today. De-risks #100 and is being dispatched now as an advisor run. Nothing recipe-shaped dispatches until #105 answers.

The demand-side slice (#99) is already in flight and needs none of these.

Recipe/pricing roadmap now filed as tracked issues: - **#100** - A, recipe data ingest (keystone), gated on the probe below. - **#101** - B, recipes browse page (/recipes + /recipe). Depends on #100. - **#102** - C, bottom-up cost roll-up engine. Depends on #100. - **#103** - D, most-valuable-to-craft per profession. Depends on #100, enhanced by #102. - **#104** - E, 'how to price X' page (/uses/price), under the #99 hub. Market panels ship early, cost/margin gated on #102. - **#105** - probe: what recipe data is Eco Gnome actually giving us today. **De-risks #100** and is being dispatched now as an advisor run. Nothing recipe-shaped dispatches until #105 answers. The demand-side slice (#99) is already in flight and needs none of these.
coilyco-ops added
P4
and removed
P3
labels 2026-07-10 09:00:47 +00:00
Sign in to join this conversation.
No description provided.