Power Segmenting Devices¶
A "segmenting device" is any device that holds two distinct cable / wireless network references AND has Input/Output power-flow semantics, so it bridges (segments) the power-flow graph. PowerGridPlus treats these as the level boundaries of its allocator cascade and as the edges of its cycle-detection graph. This page is the verified catalogue of the concrete classes, their namespaces, base chain, and the members the power simulation reads off them.
The seven real segmenting classes + one vestigial¶
Seven concrete instantiable classes segment the power graph. All seven derive from ElectricalInputOutput (so they expose InputNetwork / OutputNetwork / InputConnection / OutputConnection / OnOff / ReferenceId uniformly):
| Class | Namespace | Base chain | Decompile line |
|---|---|---|---|
| Transformer | Assets.Scripts.Objects.Electrical |
ElectricalInputOutput : Device | 403300 |
| Battery | Assets.Scripts.Objects.Electrical |
ElectricalInputOutput : Device | 370616 |
| AreaPowerControl | Assets.Scripts.Objects.Electrical |
ElectricalInputOutput : Device | 369509 |
| PowerTransmitter | Assets.Scripts.Objects.Electrical |
WirelessPower : ElectricalInputOutput : Device | 387065 |
| PowerReceiver | Assets.Scripts.Objects.Electrical |
WirelessPower : ElectricalInputOutput : Device | 386861 |
| RocketPowerUmbilicalMale | Objects.Rockets |
ElectricalInputOutput : Device | 148269 |
| RocketPowerUmbilicalFemale | Objects.Rockets |
ElectricalInputOutput : Device | 147895 |
Namespace correction worth noting: RocketPowerUmbilicalMale / RocketPowerUmbilicalFemale are in the bare Objects.Rockets namespace (decompile namespace Objects.Rockets at line 139947), NOT Assets.Scripts.Objects.Rockets. The bare-Objects namespace family is the same one that holds Objects.SwitchOnOff and Objects.DevicePart; Stationeers uses both Objects.* and Assets.Scripts.Objects.* for different classes.
PowerConnection : Electrical (line 386738) is the eighth two-network candidate but is vestigial dead code: no prefab, no recipe, no build-menu entry, never is-checked anywhere in vanilla or any surveyed mod, and it does NOT derive from ElectricalInputOutput (it derives from Electrical at line 373728, which has no InputNetwork/OutputNetwork; it carries a ConnectedCableNetworks list and a never-called GetOtherNetwork helper). PowerGridPlus ignores it entirely.
Shared base: ElectricalInputOutput¶
// line 373755
public class ElectricalInputOutput : Device, ISmartRotatable, ISubmergeable, IPowered, IDensePoolable, IReferencable, IEvaluable
{
[Header("Electrical I/O")]
public Connection InputConnection; // line 373758
public Connection OutputConnection; // line 373760
[ReadOnly] public CableNetwork InputNetwork; // line 373763
[ReadOnly] public CableNetwork OutputNetwork; // line 373766
public override bool IsPowerInputOutput => true; // line 373801
// Short-circuit gate (line 373803): both terminals on the same network -> not operable.
protected override bool IsOperable
{
get
{
if (OutputNetwork != null && InputNetwork == OutputNetwork) return false;
return base.IsOperable;
}
}
}
- The connected cable is reached via
InputConnection.GetCable()/OutputConnection.GetCable(), and the per-instance Watts cap via that cable'sMaxVoltagefield (seeCable.md). OnOffis apublic virtual booldeclared onDevice(line ~299160). Read it to know whether the device is switched on.- All seven override
GetGeneratedPower(CableNetwork)andGetUsedPower(CableNetwork)(public, returns float; the parameter is[NotNull]). Because each concrete class overrides these, a Harmony patch must target each concrete override, not the base. - Counterintuitive namespace: the base
Deviceclass isAssets.Scripts.Objects.Pipes.Device : SmallGrid(decompile line 349588), NOTAssets.Scripts.Objects.Device. Power devices, pipe devices, and chutes all derive from this oneDevicein thePipesnamespace.
Wireless pair anatomy (PowerTransmitter / PowerReceiver)¶
PowerTransmitter(line 387065):InputNetworkis the source cable network;OutputNetworkis the wireless network (WirelessOutputNetwork => OutputNetwork as WirelessNetwork, line 387087).public PowerReceiver LinkedReceiver(line 387089), null when unlinked.MaxPowerTransmission = 5000fstatic (387071);PowerLossOverDistanceAnimationCurve (387073).PowerReceiver(line 386861):OutputNetworkis the destination cable network;InputNetworkis the wireless network.private PowerTransmitter _linkedPowerTransmitter(386865) exposed viapublic PowerTransmitter LinkedPowerTransmitter(386871) whose setter also writesInputNetwork = value.OutputNetwork.- Because the setter ties
PR.InputNetworktoPT.OutputNetwork, every receiver linked to a transmitter shares that oneWirelessNetworkobject. The wireless link is therefore representable in a topology graph as the single sharedWirelessNetworknode bracketed byPT.InputNetwork(cable) andPR.OutputNetwork(cable); multi-PR fan-out from one PT all join through that shared node.
Internal-cell devices (Battery, AreaPowerControl, RocketPowerUmbilical*)¶
Battery(370616):public float PowerStored { get; set; }(370665, clamped[0, PowerMaximum]),public float PowerMaximum = 3600000f(370629).UsePower/ReceivePoweroverrides at 371098 / 371106. Prefabs: smallStationBatterySmall(PrefabNameStructureBattery), largeStationBatteryLarge(StructureBatteryLarge); the nuclear variant ships from the third-party MorePowerMod.AreaPowerControl(369509): inserted cell viapublic BatteryCell Battery => BatterySlot.Get<BatteryCell>()(369548);public float BatteryChargeRate = 1000f(369540, per-instance serialized);private float _powerProvided(369546) couples per-tick charge XOR discharge. No vanilla discharge-rate field.RocketPowerUmbilicalMale(148269) /RocketPowerUmbilicalFemale(147895): bothpublic float PowerMaximum = 10000fandpublic float PowerStored { get; set; }(clamped). The Female has NO OnOff interactable button on the device itself (fault state must be surfaced by hover text only); the Male has the on-button affordance. Prefab names (verified from a live save's<PrefabName>entries):StructurePowerUmbilicalMale/StructurePowerUmbilicalFemale. Power methods are battery-shaped:GetUsedPower(input)returnsUsedPower + clamp(PowerMaximum - PowerStored, ...)(the Male additionally gates on OnOff and returns justUsedPowerwhenError == 1 && OnOff);GetGeneratedPower(output)returnsmax(PowerStored, 0)(Female L148182-148199, Male L148744-148772). Logic-method declarations: the Male declaresCanLogicRead/CanLogicWrite/SetLogicValuebut NOTGetLogicValue; the Female declares none of them (both halves reachGetLogicValuethrough theDevicebase declaration). TheDevicebase also declares slot-keyed overloads ofCanLogicRead/GetLogicValue, so a Harmony patch on the base MUST pass an explicittypeof(LogicType)argument array or it raisesAmbiguousMatchExceptionand takes the wholePatchAlldown.
Power producer classes (not segmenters)¶
Producers are the rigid power sources on the graph (a generator produces its GetGeneratedPower value whether or not anything consumes it). They are NOT segmenters (single network). PowerGridPlus's producer-isolation rule (a producer may connect only to a transformer or to other producers, else it faults) classifies them as below. Namespaces and base chains verified from the decompile:
| Class | Namespace | Base | Has OnOff button? |
|---|---|---|---|
| SolarPanel | Assets.Scripts.Objects.Electrical |
Electrical, IPowerGenerator | No (hover/burn only) |
| WindTurbineGenerator | Objects |
Device, IPowerGenerator | No |
| LargeWindTurbineGenerator | Objects |
WindTurbineGenerator | No |
| RadioscopicThermalGenerator | Assets.Scripts.Objects.Electrical |
Electrical | No |
| PowerGeneratorPipe | Assets.Scripts.Objects.Electrical |
DeviceInputOutput, IThermal | Yes |
| GasFuelGenerator | Assets.Scripts.Objects.Electrical |
PowerGeneratorPipe | Yes (inherited) |
| PowerGeneratorSlot | Assets.Scripts.Objects.Electrical |
DeviceImport | Yes |
| SolidFuelGenerator | Assets.Scripts.Objects.Electrical |
PowerGeneratorSlot | Yes (inherited) |
| StirlingEngine | Assets.Scripts.Objects.Electrical |
DeviceInputOutput, IThermal | Yes |
WindTurbineGenerator and LargeWindTurbineGenerator are in the bare Objects namespace (like the umbilicals and Objects.SwitchOnOff), NOT Assets.Scripts.Objects. Because LargeWindTurbineGenerator : WindTurbineGenerator, GasFuelGenerator : PowerGeneratorPipe, and SolidFuelGenerator : PowerGeneratorSlot, a base-class is check covers each pair. "Has OnOff button" determines whether a producer-isolation fault can flash on the device (button-bearing producers) or must burn a cable / show hover only (SolarPanel, both wind turbines, RTG).
Two additional power-generating classes that the producer table above originally omitted:
| Class | Namespace | Base | Notes |
|---|---|---|---|
| TurbineGenerator | Assets.Scripts.Objects.Electrical |
Device, ISmartRotatable (line 403819) | The small wall wind turbine. Declares its own GetGeneratedPower (line 403973). No OnOff button. |
| PowerConnector | Assets.Scripts.Objects.Electrical |
Electrical (line 386798) | The dynamic-generator dock (portable generator connection point). Declares its own GetGeneratedPower (line 386810); supplies the network from the docked portable generator. Distinct from the vestigial PowerConnection. |
GetGeneratedPower override map¶
Every class that supplies power to a cable network declares its own GetGeneratedPower(CableNetwork) override; none of the producer classes inherit it from an intermediate base. The complete declaration list in the 0.2.6228.27061 decompile (grep "float GetGeneratedPower", 16 hits):
| Line | Declaring class |
|---|---|
| 350696 | Device (virtual base) |
| 138898 | WindTurbineGenerator (inherited by LargeWindTurbineGenerator) |
| 148191 | RocketPowerUmbilicalFemale |
| 148761 | RocketPowerUmbilicalMale |
| 370000 | AreaPowerControl |
| 371127 | Battery |
| 375517 | PowerGeneratorPipe (inherited by GasFuelGenerator) |
| 386810 | PowerConnector |
| 387028 | PowerReceiver |
| 387268 | PowerTransmitter |
| 395580 | RadioscopicThermalGenerator |
| 400139 | SolarPanel |
| 400512 | PowerGeneratorSlot (inherited by SolidFuelGenerator) |
| 402686 | StirlingEngine |
| 403496 | Transformer |
| 403973 | TurbineGenerator |
Implication for Harmony: a postfix aimed at a producer class resolves to that class's own declared method (no inherited-method trap for these), and one patch on WindTurbineGenerator / PowerGeneratorPipe / PowerGeneratorSlot covers the respective subclass for free. The full producer patch set is 8 declared methods: SolarPanel, WindTurbineGenerator, RadioscopicThermalGenerator, PowerGeneratorPipe, PowerGeneratorSlot, StirlingEngine, TurbineGenerator, PowerConnector.
Verification history¶
- 2026-06-09: Page created (0.2.6228.27061). Class catalogue and members gathered during the PowerGridPlus power refactor from the 0.2.6228.27061 decompile;
Objects.Rocketsnamespace for the umbilical classes confirmed directly (nearestnamespacedecl above line 148269 isnamespace Objects.Rocketsat line 139947, correcting an earlierAssets.Scripts.Objects.Rocketsguess). - 2026-06-09: Added the power-producer class catalogue (namespaces, base chains, OnOff-button presence) verified from the same decompile, for the producer-isolation rule.
- 2026-06-10: Added the
GetGeneratedPoweroverride map (all 16 declarations) and the two previously-omitted power-generating classesTurbineGenerator(small wall wind turbine, line 403819) andPowerConnector(dynamic-generator dock, line 386798). Both declare their ownGetGeneratedPower; both are single-network suppliers and therefore subject to producer-isolation, neither has an OnOff button. - 2026-06-10 (correction):
Batteryis inAssets.Scripts.Objects.Electrical, NOTAssets.Scripts.Objects.Pipesas this page previously stated. Two independent machine witnesses: the C# compiler rejectedAssets.Scripts.Objects.Pipes.Batterywith CS0234 during the PowerGridPlus build, and the nearestnamespacedeclaration above the class at decompile line 370616 readsnamespace Assets.Scripts.Objects.Electrical. The fresh-validator sub-agent step was skipped because compiler evidence is conclusive; recorded here per the conflict-resolution rule. - 2026-06-10: Added the rocket umbilical prefab names (
StructurePowerUmbilicalMale/StructurePowerUmbilicalFemale, read from a live save's PrefabName entries), their battery-shaped power-method bodies (Female L148182-148199, Male L148744-148772), the logic-method declaration map for both halves, and the slot-keyed-overloadAmbiguousMatchExceptiontrap onDevice.CanLogicRead/Device.GetLogicValuebase patches (hit live: it silently disabled every PowerGridPlus patch until the argument-type array was added).
Open questions¶
- None outstanding for the segmenting-device catalogue itself. Per-class power-method formulas (the bodies of
GetGeneratedPower/GetUsedPower) are documented on the individualGameClasses/pages where present.