Skip to content

PassiveVent

Vanilla PassiveVent : Pipe, the pipe piece that opens a pipe network to the cell it stands in. It has no settings, no power and no direction: every atmospheric tick it pools the network's gas with its cell's and splits the total back by volume, so the two end each tick at the same composition, pressure and temperature. Read in the 0.2.6428.27798 decompile; nothing on this page was measured.

Declaration and registration

public class PassiveVent : Pipe
{
    public RoboticArmDockAtmos DockedAtmosArm { get; set; }

    public override void OnRegistered(Cell cell)
    {
        base.OnRegistered(cell);
        AtmosphericsManager.Instance.Register(this);
    }
    ...

(389931-389939). Pipe.OnRegistered (390818-390836) already registers every pipe with AtmosphericsManager and caches the crew module the pipe's cell is in (_crewModule), so the vent's own Register call is a second add to the same pool. It does not tick the vent twice: AtmosphericsManager.Register adds to the AtmosphericThings dense pool (446756-446763), DensePool.Add asks the item first (234439-234457), and Thing.OnAddToPool refuses a pool the Thing already has a slot in (324424-324447).

That pool is what the atmospheric tick walks (the dispatch in full is on AtmosphericThingTickDispatch). GameManager.GameTick calls AtmosphericsManager.ThingAtmosphereTick() (209935), which runs OnAtmosphericTick on every Thing in it (446681-446684), inside an if (RunSimulation) block, after the same tick's world atmosphere mixing (DoAtmosphereMixJobs, 209929). So only the simulating side runs a vent: single player, a host, a dedicated server. A joined client never does, and CloneGlobalAtmosphere, which the vent reaches, throws on a client (201933-201936).

Every atmospheric tick mixes the network with the vent's cell

OnAtmosphericTick (389947-389984):

public override void OnAtmosphericTick()
{
    if (!base.HasOpenGrid)
    {
        return;
    }
    bool flag;
    switch (base.RocketNetwork?.Rocket?.RocketState)
    {
    case RocketState.Launching:
    case RocketState.Landing:
        flag = true;
        break;
    default:
        flag = false;
        break;
    }
    if (flag)
    {
        RegisterCurrentGrids();
    }
    else if ((object)_crewModule == null)
    {
        _crewModule = (Cell.IsInCrewModule(base.WorldGrid, out var crewModule) ? crewModule : null);
    }
    if (!(DockedAtmosArm != null) || DockedAtmosArm.ArmState != ArmState.Down)
    {
        Atmosphere workingAtmosphere = GetWorkingAtmosphere();
        if (AtmosphereHelper.IsSubmerged(base.Position, workingAtmosphere))
        {
            AtmosphereHelper.Mix(base.PipeNetwork?.Atmosphere, workingAtmosphere, AtmosphereHelper.MatterState.All);
        }
        else
        {
            AtmosphereHelper.Mix(base.PipeNetwork?.Atmosphere, workingAtmosphere, AtmosphereHelper.MatterState.Gas);
        }
    }
}
  • Nothing happens when the vent's cell cannot hold an atmosphere. HasOpenGrid is GridController.CanContainAtmos(WorldGrid) (SmallGrid, 318002).
  • A robotic arm dock can stop it. A docked RoboticArmDockAtmos whose arm is Down suspends the mix.
  • Gas only, unless the vent is submerged. MatterState.Gas mixes gases and leaves liquids where they are; when IsSubmerged finds the vent's position under liquid in its working atmosphere, MatterState.All mixes liquids too.
  • The working atmosphere is the vent's own cell. Pipe.GetWorkingAtmosphere (390838-390845) returns the crew module's internal atmosphere when the pipe is inside one, and otherwise AtmosphericsController.CloneGlobalAtmosphere(WorldGrid, 0L). Despite the name that is the cell's live atmosphere, not a copy: CloneGlobalAtmosphere (201931-201955) returns the atmosphere already registered at the cell, and only when there is none creates one, seeded with the planet's gas for that volume (PlanetaryAtmosphereSimulation.CloneGlobalGasMix, 221552-221570, which adds nothing at or above the space height). The new one registers itself in Atmosphere.Init (AtmosphericsManager.Register(this), 443336-443377), so it is a real world atmosphere from then on.

AtmosphereHelper.Mix (445505-445522) is the whole exchange:

public static void Mix(Atmosphere inputAtmos, Atmosphere outputAtmos, MatterState matterState)
{
    if (inputAtmos != null && outputAtmos != null)
    {
        GasMixture gasMixture = GasMixtureHelper.Create();
        VolumeLitres zero = VolumeLitres.Zero;
        gasMixture.Add(inputAtmos.GasMixture, matterState);
        zero += inputAtmos.GetVolume(matterState);
        gasMixture.Add(outputAtmos.GasMixture, matterState);
        zero += outputAtmos.GetVolume(matterState);
        GasMixture gasMixture2 = new GasMixture(gasMixture);
        gasMixture2.Scale((inputAtmos.GetVolume(matterState) / zero).ToFloat(), matterState);
        inputAtmos.GasMixture.Set(gasMixture2, matterState);
        GasMixture gasMixture3 = new GasMixture(gasMixture);
        gasMixture3.Scale((outputAtmos.GetVolume(matterState) / zero).ToFloat(), matterState);
        outputAtmos.GasMixture.Set(gasMixture3, matterState);
    }
}

Both mixtures are pooled and each side gets the pool scaled by its share of the combined volume. There is no rate, no pressure threshold and no direction: one call leaves the network and the cell at the same composition, pressure and temperature. A network with no atmosphere (PipeNetwork?.Atmosphere null) mixes nothing. All of these members are textually identical in the dedicated server's compile.

A network that vents in two places joins them

Read from the source above, not measured. Each vent on a network runs the same mix with its own cell, every tick, so a network whose vents stand in different places carries gas between those places without anything else on it: every tick each vent's cell and the network end level with each other, and the network then levels with the next vent's cell. A network with one vent inside a pressurised room and another outside in vacuum therefore takes gas out of the room every tick and hands it to the outside cell, and keeps doing so while the room holds more than the outside. What happens to gas once it is in a cell outside any room is the world atmosphere's business, not the vent's (see Atmosphere).

Verification history

  • 2026-09-27: page created (game version 0.2.6428.27798) from the decompile of both compiles, while curating why a Spray Paint Plus playtest's sealed room lost pressure. Source reading only; the drain rate of a room through a vent pair was not measured.

Open questions

None.