fix: v3.0.0 -- thresholds on the free-fraction scale the assembly actually uses
Disassembling Cosmoteer.dll (tools/ildump.py) shows PartThresholdToggle compares plain floats with no percent logic, and that a NetworkResourceInput's Value is the free fraction (0..1) of the connected network. v2.1.0 compared that against 2000000, so it always vented. Thresholds are now 5% / 10% free as local constants. New guard test_threshold_amounts_match_value_scale fails on the old values. README corrects the earlier wrong diagnosis of v2.0.0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oLWY1G6S8U35bi2FxVWni
This commit is contained in:
@@ -18,41 +18,41 @@
|
||||
|
||||
// --- Is the heat network running out of room? -------------------------------
|
||||
//
|
||||
// Measured locally, exactly the way the heat exchanger decides whether it can
|
||||
// still push heat into the network (heat_exchanger.rules: IsNetworkHeatNonFull
|
||||
// reads a bare NetworkResourceInput). A NetworkResourceInput's value is how much
|
||||
// the network can still accept.
|
||||
// Measured locally with a bare NetworkResourceInput, the same component an
|
||||
// overclocked part pushes its heat through (base_part_overclock.rules:
|
||||
// NetworkHeatInput), so this is exactly the producer's view of the network.
|
||||
//
|
||||
// Reading a thermal battery's own HeatStorage does NOT work for this. That
|
||||
// storage is wrapped by a NetworkResourceStore, and v2.0.0 held heat forever --
|
||||
// batteries visibly full, parts cooking -- because a local percentage threshold
|
||||
// on it never crossed. This measures the network itself instead, from the part
|
||||
// that acts on the answer, so no cross-part broadcast is involved at all.
|
||||
//
|
||||
// Amounts are resource units: 1 status heat = 1000 resource units
|
||||
// (statuses/heat/heat.rules: STATUS_TO_RESOURCE_RATIO).
|
||||
// Its Value, from Cosmoteer.dll (PartNetworkResourceInput.get_Value, see
|
||||
// tools/ildump.py), is the FREE FRACTION of the connected heat storage:
|
||||
// 1 - stored / total capacity -> 1.0 empty, 0.0 full, 0 if nothing attached
|
||||
// and a ThresholdToggle compares that against MinAmount/MaxAmount as plain
|
||||
// floats, so the amounts below are fractions too ("5%" is 0.05).
|
||||
|
||||
AutoRad_NetworkSpace
|
||||
{
|
||||
Type = NetworkResourceInput
|
||||
ResourceType = heat
|
||||
Mode = DistributeProportionallyByAvailable
|
||||
Categories = [ thermal_storage ]
|
||||
}
|
||||
|
||||
// Under ~2000 status heat of headroom left: vent.
|
||||
// Vent while less than VENT_BELOW_FREE of the network is still free.
|
||||
AutoRad_SpaceLow
|
||||
{
|
||||
Type = ThresholdToggle
|
||||
ValueFrom = AutoRad_NetworkSpace
|
||||
MaxAmount = 2000000
|
||||
VENT_BELOW_FREE = 5%
|
||||
MaxAmount = &VENT_BELOW_FREE
|
||||
}
|
||||
|
||||
// Back above ~6000 status heat of headroom: safe to bank heat again.
|
||||
// Hold heat again once at least HOLD_ABOVE_FREE is free. The gap between the
|
||||
// two is a deadband so radiators do not chatter at the threshold.
|
||||
AutoRad_SpaceAmple
|
||||
{
|
||||
Type = ThresholdToggle
|
||||
ValueFrom = AutoRad_NetworkSpace
|
||||
MinAmount = 6000000
|
||||
HOLD_ABOVE_FREE = 10%
|
||||
MinAmount = &HOLD_ABOVE_FREE
|
||||
}
|
||||
|
||||
AutoRad_LowTrigger
|
||||
|
||||
Reference in New Issue
Block a user