From 84a873f3bce926c30b1167a07f2be128d2927cea Mon Sep 17 00:00:00 2001 From: Dominik Roth Date: Thu, 8 Oct 2026 10:42:16 +0200 Subject: [PATCH] tools/chain.py: add --consumers to list what eats a material Reverse of the existing make-vs-buy tree: given a ticker, find every recipe that consumes it as an input, with each output's live market depth. Answers "is there a deeper downstream product worth chaining into" without an ad-hoc fio.recipes() scan each time (did this by hand for BOR, BSE and BBH this session). Co-Authored-By: Claude Sonnet 5 --- tools/chain.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tools/chain.py b/tools/chain.py index e8f31b7..5bf3fa3 100755 --- a/tools/chain.py +++ b/tools/chain.py @@ -3,6 +3,7 @@ Cost to make = inputs at min(buy, make) per output unit; wages/capex excluded unless --wages. tools/chain.py DEC # AI1 tools/chain.py BHP --depth 3 --qty 13 + tools/chain.py BOR --consumers # what recipes EAT this ticker as an input, with the output's market depth """ import argparse, sys from pathlib import Path @@ -18,6 +19,7 @@ def main(): ap.add_argument("--qty", type=float, default=1.0, help="units/day you would make (sourcing check)") ap.add_argument("--wages", action="store_true", help="add wage cost per output unit (both luxuries at ask)") ap.add_argument("--cogc") + ap.add_argument("--consumers", action="store_true", help="list recipes that consume this ticker as an input, with the output's market depth, instead of the make-vs-buy tree") a = ap.parse_args() snap = market.snapshot() @@ -28,6 +30,24 @@ def main(): for o in r["Outputs"]: by_out.setdefault(o["Ticker"], []).append(r) + if a.consumers: + tk = a.ticker.upper() + found = False + for r in fio.recipes(): + if not any(i["Ticker"] == tk for i in r["Inputs"]): + continue + found = True + ins = " ".join(f"{i['Amount']}{i['Ticker']}" for i in r["Inputs"]) + outs = " ".join(f"{o['Amount']}{o['Ticker']}" for o in r["Outputs"]) + print(f"{r['BuildingTicker']:4} {ins} -> {outs}") + for o in r["Outputs"]: + q = Q(o["Ticker"]) + mk = f"ask {q.ask:.0f} bid {q.bid:.0f} sup {q.supply:.0f} dem {q.demand:.0f} flow {sat.tref(q.traded7, q.traded30):.1f}/d" if q and q.ask and q.bid else "no market" + print(f" {o['Ticker']:5} {mk}") + if not found: + print(f"nothing consumes {tk} as an input") + return + def wage_per_day(b): tot = 0.0 for t in econ.TIERS: