diff --git a/CLAUDE.md b/CLAUDE.md index 0ed2eea..19e7bf0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -48,12 +48,15 @@ Run as `puga ...` (e.g. `puga scan --min-n 3`, `puga plan pull `); - `tools/buy.py --days N` cash-aware shopping list: construction gap (plan vs empire state's built buildings) plus N days of the plan's NET operating stock (via `simulate()`, so self-produced inputs like AL net against consumption), priced at real fill cost, checked against cash/reserve. Pass a plan covering the WHOLE base for restocking, not just a new addition (see `docs/library.md`). - `tools/sell.py TICKER QTY [--tight]` where to post an ask, expected hours to clear, and a self-contained tranche split: aggressive (undercut) tranche capped at the median 30d-volume quantile (or 80th pct with `--tight`, for when a payment is imminent and stockout risk outweighs a few points of margin), patient tranche priced just under the next competitor tier. `--show-bid` for the instant-bid comparison (off by default; usually worse). - `tools/network.py ` models a MULTI-BASE chain (e.g. mine LST at Nike, ship it, make BSE at Deimos): simulates each base, nets a transferred material's producer-surplus against consumer-need, charges real freight only on what's moved (`puga/network.py`). Spec and worked example in `plans/chains/`. `cm_free: true` per base for a new founding covered by a Core Module Kit. profit/day per base is the WHOLE plan, not the marginal addition - diff against the base's plan without the addition for a true marginal ROI. -- `tools/whatif.py [--add BUILDING:AMOUNT[:RECIPE]] [--infra HB1:+1] [--after after.yaml]` marginal ROI of adding to a base you already run (whole-plan diff, same rule as buy/runway - pass the WHOLE base, not just the addition). `--add` mutates a copy of `before` in-memory (reuses an existing building's recipe if omitted, e.g. `--add POL:1`); `--after` takes a second full spec instead. Flags any workforce tier the addition newly overloads (vs. a pre-existing one, which it won't flag) - this is what caught the PP2/pioneer-housing and 2nd-CHP/pioneer-housing surprises by hand before this tool existed. +- `tools/whatif.py [--add BUILDING:AMOUNT[:RECIPE]] [--infra HB1:+1] [--after after.yaml]` marginal payback of adding to a base you already run (whole-plan diff, same rule as buy/runway - pass the WHOLE base, not just the addition). `--add` mutates a copy of `before` in-memory (reuses an existing building's recipe if omitted, e.g. `--add POL:1`); `--after` takes a second full spec instead. Flags any workforce tier the addition newly overloads (vs. a pre-existing one, which it won't flag) - this is what caught the PP2/pioneer-housing and 2nd-CHP/pioneer-housing surprises by hand before this tool existed. Charges marginal freight too (real fuel model, CX-to-planet, via `puga.shipping`): only the EXTRA round trips this addition needs beyond the base's existing traffic, so a small addition riding along on already-necessary hauls correctly costs ~0, while one that meaningfully adds to shipped tonnage doesn't get a free pass - this is what would catch a recipe whose ROI looks great only because its freight cost was left out. - `tools/runway.py [--no-inbound]` days of runway per material before a base stalls: real NET consumption via `simulate()` (self-produced inputs excluded), base storage, PLUS (by default) any ship currently flying to that planet, auto-detected from live flight data (`tools/state.py` tags each ship with its flight origin/destination). Pass the WHOLE base plan (see `docs/library.md`). - `tools/undervalued.py [--cx AI1] [--min-vol 5] [--top 20]` manufactured goods currently priced below implied production cost - buy-and-hold-for-reversion candidates, not build candidates. **Expected ROI is much lower than production builds** (~0.10-0.24%/day backtested, vs 14-29%/day for the builds this toolkit recommends) - only worth it for excess idle capital once better-yielding builds are exhausted. Library: `puga/undervalued.py`. - `tools/chain.py TICKER` make-vs-buy cost tree plus sourcing depth of inputs. `--consumers` flips it: what recipes EAT this ticker as an input, with each output's market depth - for "is there a deeper downstream product worth chaining into" questions (e.g. checking BOR/BSE/BBH for further processing). - `tools/planet.py RESOURCE [--min-factor X] [--from PLANET] [--top N]` ranks planets for a raw resource by extraction factor, with founding cost straight from FIO's own `BuildRequirements` (real environment-extras materials, not guessed temperature/pressure thresholds - PRUNplanner's own calculations don't model those either) and optional jump distance via `tools/route.py`. Pure-factor ranking alone is misleading - the best-factor planets are often thousands of ly away; always pass `--from` an existing base. Library: `puga/planet.py`. - `tools/route.py ` jump-distance route (not a PRUNplanner feature - built from FIO's `/systemstars` graph, Dijkstra by straight-line ly since that's what FTL fuel/time scale with, jump count reported alongside). Accepts planet natural IDs, system natural IDs, or names. Library: `puga/route.py`. +- `tools/shiptrip.py SHIP FROM TO [--v0 X --v1 Y]` the simple ship-trip tool: give a ship registration + start + stop, it works out jumps/charges/landing fuel itself via `tools/route.py`'s jump graph and reports fuel cost (defaults to max sliders). Direct-jump routes only - an unconnected pair means gateway-only, and it tells you exactly what to read off the live APEX Ship Flight Control screen (the LOCK fee - genuinely not available via FIO/PRUNplanner, confirmed by inspecting both) and what to run instead (`tools/shipcost.py`). Warns if the given ship's live specs (FIO `/ship/ships/{user}`) don't match the calibrated hull/reactor. +- `tools/shipcost.py [--jumps N --charges N] [--v0 X --v1 Y] [--gateways N --lock-fee AMOUNT:CURRENCY] [--to PLANET]` the explicit/manual version: fuel/AIC cost of a ship trip from physics parameters you already know (jump count, slider values, gateway LOCK fees read off the live game) - use `tools/shiptrip.py` instead if you just want "ship X from A to B". Landing fuel is a measured-planet lookup via `--to`, independent of whether the route used jumps or gateways. Both tools scoped to this account's one hull/reactor (blueprint BP-STRT-0000, shared by both ships AVI-07JFB/AVI-07JFC); open caveats (v0 relative to current fuel load, landing fuel confounded with gravity/distance, no second hull to cross-check) are in `puga/shipping.py`'s module docstring - don't trust magnitudes beyond what's there. Raw calibration data (APEX DOM reads, 2026-10-09): `empire/data/shipping_calibration/`. Also wired into `tools/network.py`'s freight cost (direct-jump transfers use the real model; gateway transfers need an explicit `trip_cost` in the chain YAML, else a 9250 AIC fallback). Library: `puga/shipping.py` (`trip_fuel()`, `round_trip_cost()`). +- `tools/lmscan.py PLANET [--direction source|destination] [--min-margin X]` live Local Market hauling-ad scan (FIO, public/no-auth - real player-posted freight jobs, not the CONTD player-contract system), ranked by margin after real fuel cost (`puga.shipping.leg_cost`). One-way cost only - margin assumes the next job is picked up near the destination, not an empty flight home. A small measured gateway-fee table covers ANT<->HRT/BEN; other gateway routes can't be priced (LOCK fee isn't available via any API). Library: `puga/contracts.py`. - `tools/price.py` prices across exchanges with VWAP, volume, fill price for a quantity; `tools/book.py` order-book ladder. - `tools/prun_scan.py`, `tools/prun_cxarb.py` legacy top-of-book scans; overstate thin markets. Baseline only. `tools/arb.py` replacement is on the roadmap. - `puga/econ.py` pure formulas ported from PRUNplanner (efficiency stack, workforce, extraction, production I/O, hab optimizer); `tests/test_econ.py` holds the reference values. diff --git a/docs/library.md b/docs/library.md index d345334..3cbed35 100644 --- a/docs/library.md +++ b/docs/library.md @@ -49,6 +49,23 @@ EOF -> SystemId), `shortest_path(src, dst, graph=None)` (Dijkstra by straight-line ly over FIO's `/systemstars` jump graph; returns jumps, distance_ly, path). Not a PRUNplanner feature, built for this project since travel isn't modelled anywhere else. CLI: `tools/route.py`. +- **`puga.shipping`** — `cruise_leg_fuel(v0)`, `jump_fuel(v1)`, `charge_fuel(v1)`, + `gateway_hop_cost(lock_fee_amount, lock_fee_currency)`, `landing_fuel(planet_natural_id)` (lookup + only, `None` if unmeasured), `trip_fuel(...)` (one-way total, shared by the CLIs), + `leg_cost(src, dst, sf_price, ff_price, v0=1.0, v1=1.0)` (one-way AIC cost; uses + `KNOWN_GATEWAY_ROUTES` when the pair has a measured gateway chain, else the direct-jump graph; + `None` if neither applies), `round_trip_cost(...)` (there-and-back via two `leg_cost` calls, + `None` if either leg is unpriceable or carries a non-AIC fee - used by `tools/network.py`'s + freight cost): real ship flight fuel model, linear in the fuel-usage (v0) / reactor-usage (v1) + sliders, additive/no cross-term. Scoped to this account's one hull/reactor (BP-STRT-0000, both + ships confirmed identical); see the module + docstring for confirmed-vs-open caveats before trusting a number. CLIs: `tools/shiptrip.py` + (ship+from+to, auto-computes everything via `puga.route`), `tools/shipcost.py` (explicit + jumps/sliders/gateway-fees, for when you already know the breakdown). Raw calibration data: + `empire/data/shipping_calibration/`. +- **`puga.contracts`** — `scan(planet, direction, sf_price, ff_price, v0=1.0, v1=1.0)`: live + Local Market hauling ads (FIO `/localmarket/shipping/{source,destination}`), each enriched with + real one-way fuel cost (`puga.shipping.leg_cost`) and margin. CLI: `tools/lmscan.py`. - **`puga.undervalued`** — `manufacturing_candidates()`, `current_margin(ticker, recipe, cx)`, `scan_current(cx, min_vol=5.0)`: manufactured goods priced below implied production cost, for a buy-and-hold-for-reversion trade, not a build decision. Backtested expected return is diff --git a/docs/mechanics.md b/docs/mechanics.md index 53480ad..9463dde 100644 --- a/docs/mechanics.md +++ b/docs/mechanics.md @@ -59,6 +59,13 @@ Sources: Prosperous Universe dev log #239 "Enlisting Labor" (https://prosperousu - Report cadence seen on one planet: weekly, Wednesdays ~08:00 UTC (report #289 on 16 Sep 2026). - The old handoff detail "bases keep 75% of workforce between reports" is not in these sources; treat as unverified. +## Gateway (GTW) jump transit time (measured 2026-10-09) +Sources: our own live APEX Ship Flight Control DOM reads (`empire/data/shipping_calibration/{hrt,ben}.json`) and the official handbook (handbook.apex.prosperousuniverse.com/wiki/infrastructure-gateway). The PrUn forum thread "Gateway Question Roundup" (Oct 2024) quotes a dev (molp) saying the team was "considering a fixed transit time, independent of the link length" during pre-launch design. +- Our measured GTW segment durations contradict that design intent, if it shipped as described: 17 parsecs -> 5h41m and 5h43m; 15 parsecs -> 5h1m and 5h3m; 10 parsecs -> 3h18m. All five data points land within 19.8-20.2 minutes per parsec - a tight linear fit, not a fixed duration. +- Treat GTW transit time as scaling ~linearly with the link's parsec distance (~20 min/parsec) until a wider sample says otherwise (n=3 distinct distances, 2 routes, not independently varied against other factors). The forum statement is 2024 pre-launch discussion, not a current source - our own measurement wins per this project's source-of-truth order. +- No fuel or time model for GTW duration exists yet in `puga/shipping.py` (fuel-only); this is a documented fact for whoever builds that next, not wired into any tool. +- Per the handbook: LOCK fees have no public formula (gateway-operator-set, displayed in SFC); some gateway links are one-way; each gateway has its own max per-jump cargo volume (m3), separate from ship hold size - none of these are modelled anywhere in this project yet. + ## HQ in game vs PRUNplanner's "HQ" flag (observed 2026-09-21) - The HQ screen (level 1, base permits 1 / 2) shows "Efficiency gains: Electronics 20.0%", and 23.3% for the next level (permits 1 / 3). That is exactly the faction bonus formula (Antares electronics 5% x 2 x (3 - 2 x used/total)), so the HQ display is the faction bonus. - PRUNplanner's plan flag "HQ" (x1.1 on every building) is NOT visible in live efficiencies (smelters 1.3361, HWP 1.0696 both match the model without it). Keep it off. The HQ upgrade adds a base permit and raises the faction bonus. diff --git a/docs/roadmap.md b/docs/roadmap.md index 70778f5..2349600 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -13,6 +13,8 @@ Legend: [ ] todo, [x] done. Build order matters; each step is usable on its own. 8. [x] `tools/planet.py`: rank planets for a resource (FIO bulk `Resources`/`BuildRequirements` data), founding cost from real environment-extras materials, jump distance via `tools/route.py`. `tools/found.py` (full founding workflow/writeback) still todo. 13b. [x] `puga/network.py` + `tools/network.py`: multi-base chain modelling (per-base simulate, net transfers against real freight, `cm_free` for kits). Worked example: `plans/chains/nike_deimos_lst.yaml` (Nike LST -> Deimos PP2/BSE). Known gap: reports whole-plan profit per base, not the marginal addition; caller must diff manually. 9. [x] `tools/route.py`: jump graph (FIO `/systemstars`, Dijkstra by straight-line ly, jump count alongside). `tools/haul.py` (fuel cost, profit per trip) still todo. +9c. [x] `puga/shipping.py` + `tools/shipcost.py` (explicit params) + `tools/shiptrip.py` (just ship/from/to) + `puga.shipping.round_trip_cost()` wired into `tools/network.py`'s freight cost: real ship flight fuel/cost model (STL cruise + FTL jump/charge, linear in the fuel-usage/reactor-usage sliders, additive/no cross-term; gateway hops free-fuel + manual LOCK fee read off the live game, not lookupable via any FIO/PRUNplanner endpoint - checked; landing fuel a measured per-planet lookup). Calibrated 2026-10-09 on this account's one hull/reactor (blueprint BP-STRT-0000, shared by both ships AVI-07JFB/AVI-07JFC, confirmed identical specs via FIO) via a controlled 4x4-slider-grid sweep across 5 real destinations, read from the live APEX Ship Flight Control DOM. Raw data: `empire/data/shipping_calibration/`. Open gaps (see `puga/shipping.py` docstring): departure-side gravity dependence untested (every calibration DEP left the same origin), landing fuel vs gravity/distance confounded (n=3), no second hull/reactor to cross-check generalization. `tools/scan.py --trip-cost` still uses the flat 9250 AIC placeholder (not yet wired to the real model - needs a per-recipe destination planet, not just a CX code). +9d. [x] `puga/contracts.py` + `tools/lmscan.py`: live Local Market hauling-ad scan (FIO `/localmarket/shipping/{source,destination}`, public/no-auth - real player-posted freight jobs, not the CONTD player-contract system) ranked by margin after real fuel cost (`puga.shipping.leg_cost`, one-way, with a small measured gateway-fee table `KNOWN_GATEWAY_ROUTES` for ANT<->HRT/BEN). Ship cargo hold confirmed 500t/500m3 via FIO for both ships. 9b. [x] (dry-run default, --apply after user yes) `tools/plan_push.py`: create/update `[PuGa]` plans in PRUNplanner from YAML (Api-Key auth; see decisions.md for guardrails). 10. [x] `tools/state.py sync` (sites, production efficiency, storage, ships, cash, permits): inventory, production, ships into `state/`. 11. [ ] Docs to fill: `docs/apex.md`, `docs/fio.md`, `docs/playbook.md` (question type -> tool), `docs/decisions.md`.