The block solver links fluids by name and ignores temperature, so different-temperature fluids are treated as interchangeable. The data layer already models temperatures fully (recipe_products.temperature, recipe_ingredients.min_temp/max_temp, and synthesize's per-temperature generate recipes) — the solve just doesn't use them for identity.
Concrete failure (a real fusion block)
A block with b-h (neutron @4000°), dt-he3 (neutron @3000°), and generate-mdh-4000 (neutron, min=max 4000°, 9.6 GJ per 24k neutrons):
- The solver pools BOTH neutron temperatures into the 4000° generator, so the 3000° neutrons earn 4000°-tier energy (9.6 GJ instead of 7.2 GJ via
generate-mdh-3000) — the plan overstates power output vs what the game will do.
- The existing
tempWarnings check is silent here: it only warns when NO in-block-produced temperature satisfies the consumer's range, so one matching producer (b-h @4000°) masks the mismatched one (dt-he3 @3000°).
- Adding
generate-mdh-3000 doesn't help: with one pooled "neutron" good, the solver can't route 3000° to one generator and 4000° to the other — the split is arbitrary.
A second shape in the same block: enriched-water accepts water ≤101°, enriched-water-distillation produces water @125°. By-name linking closes a recycle loop the game won't run (this one at least trips the existing warning, since no in-block temp matches).
Direction
YAFC's model: each (fluid, temperature) is a distinct good; a consumer with a temp range draws from the set of variants whose temperature falls inside it. In the block solve that means expanding fluid components to per-temperature identities when temperature data exists, with range consumers pooling over matching variants. Range-pooling is awkward to express in the current least-squares equation set and natural in an LP, so this likely lands with or after #91 (solver v2). Boundary flows and the coherence/factory aggregates need the same identity treatment (an exported 125° water is not the same good as 15° water).
Cheap interim step (worth doing before the full model)
Fix the tempWarnings blind spot: warn per-producer rather than per-consumer-range — if ANY in-block producer of a consumed fluid has a temperature outside the consumer's accepted range, flag it ("part of this block's water is 125°, which X can't accept"). That turns today's silent wrong answers into visible ones without touching the solver.
Part of #31's successor scope; closely related to #91.
The block solver links fluids by name and ignores temperature, so different-temperature fluids are treated as interchangeable. The data layer already models temperatures fully (
recipe_products.temperature,recipe_ingredients.min_temp/max_temp, and synthesize's per-temperature generate recipes) — the solve just doesn't use them for identity.Concrete failure (a real fusion block)
A block with
b-h(neutron @4000°),dt-he3(neutron @3000°), andgenerate-mdh-4000(neutron, min=max 4000°, 9.6 GJ per 24k neutrons):generate-mdh-3000) — the plan overstates power output vs what the game will do.tempWarningscheck is silent here: it only warns when NO in-block-produced temperature satisfies the consumer's range, so one matching producer (b-h @4000°) masks the mismatched one (dt-he3 @3000°).generate-mdh-3000doesn't help: with one pooled "neutron" good, the solver can't route 3000° to one generator and 4000° to the other — the split is arbitrary.A second shape in the same block:
enriched-wateraccepts water ≤101°,enriched-water-distillationproduces water @125°. By-name linking closes a recycle loop the game won't run (this one at least trips the existing warning, since no in-block temp matches).Direction
YAFC's model: each (fluid, temperature) is a distinct good; a consumer with a temp range draws from the set of variants whose temperature falls inside it. In the block solve that means expanding fluid components to per-temperature identities when temperature data exists, with range consumers pooling over matching variants. Range-pooling is awkward to express in the current least-squares equation set and natural in an LP, so this likely lands with or after #91 (solver v2). Boundary flows and the coherence/factory aggregates need the same identity treatment (an exported 125° water is not the same good as 15° water).
Cheap interim step (worth doing before the full model)
Fix the
tempWarningsblind spot: warn per-producer rather than per-consumer-range — if ANY in-block producer of a consumed fluid has a temperature outside the consumer's accepted range, flag it ("part of this block's water is 125°, which X can't accept"). That turns today's silent wrong answers into visible ones without touching the solver.Part of #31's successor scope; closely related to #91.