Skip to content

Commit

Permalink
Add atmos time compression (space-wizards#21954)
Browse files Browse the repository at this point in the history
Add atmos.speedup which is effectively a atmos-only time compression
CVar. This adjusts heat capacities and transfer rates to effectively
globally speed up the time constants of atmos.

This allows faster response to heating/cooling changes and faster
cleanups (by buffing scrubbers, pumps, and everything else) that is
tunable through one global time compression CVar.

It also achieves this without any thermodynamic unsoundness.
  • Loading branch information
Partmedia authored and BasedUser committed Dec 16, 2023
1 parent 46ed3f0 commit cfe558f
Show file tree
Hide file tree
Showing 16 changed files with 35 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Content.Server/Atmos/EntitySystems/AirFilterSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ private void OnFilterUpdate(EntityUid uid, AirFilterComponent filter, AtmosDevic
if (!GetAir(uid, out var air))
return;

var ratio = MathF.Min(1f, args.dt * filter.TransferRate);
var ratio = MathF.Min(1f, args.dt * filter.TransferRate * _atmosphere.PumpSpeedup());
var removed = air.RemoveRatio(ratio);
// nothing left to remove from the volume
if (MathHelper.CloseToPercent(removed.TotalMoles, 0f))
Expand Down
2 changes: 2 additions & 0 deletions Content.Server/Atmos/EntitySystems/AtmosphereSystem.CVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public sealed partial class AtmosphereSystem
public bool ExcitedGroupsSpaceIsAllConsuming { get; private set; }
public float AtmosMaxProcessTime { get; private set; }
public float AtmosTickRate { get; private set; }
public float Speedup { get; private set; }

/// <summary>
/// Time between each atmos sub-update. If you are writing an atmos device, use AtmosDeviceUpdateEvent.dt
Expand All @@ -49,6 +50,7 @@ private void InitializeCVars()
_cfg.OnValueChanged(CCVars.Superconduction, value => Superconduction = value, true);
_cfg.OnValueChanged(CCVars.AtmosMaxProcessTime, value => AtmosMaxProcessTime = value, true);
_cfg.OnValueChanged(CCVars.AtmosTickRate, value => AtmosTickRate = value, true);
_cfg.OnValueChanged(CCVars.AtmosSpeedup, value => Speedup = value, true);
_cfg.OnValueChanged(CCVars.ExcitedGroups, value => ExcitedGroups = value, true);
_cfg.OnValueChanged(CCVars.ExcitedGroupsSpaceIsAllConsuming, value => ExcitedGroupsSpaceIsAllConsuming = value, true);
}
Expand Down
12 changes: 11 additions & 1 deletion Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,17 @@ private float GetHeatCapacityCalculation(float[] moles, bool space)

Span<float> tmp = stackalloc float[moles.Length];
NumericsHelpers.Multiply(moles, GasSpecificHeats, tmp);
return MathF.Max(NumericsHelpers.HorizontalAdd(tmp), Atmospherics.MinimumHeatCapacity);
// Adjust heat capacity by speedup, because this is primarily what
// determines how quickly gases heat up/cool.
return MathF.Max(NumericsHelpers.HorizontalAdd(tmp), Atmospherics.MinimumHeatCapacity) / Speedup;
}

/// <summary>
/// Return speedup factor for pumped or flow-based devices that depend on MaxTransferRate.
/// </summary>
public float PumpSpeedup()
{
return MathF.Sqrt(Speedup);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public float PassiveTransferVol(GasMixture inlet, GasMixture outlet)
return 0;
}
float overPressConst = 300; // pressure difference (in atm) to get 200 L/sec transfer rate
float alpha = Atmospherics.MaxTransferRate / (float)Math.Sqrt(overPressConst*Atmospherics.OneAtmosphere);
float alpha = Atmospherics.MaxTransferRate * _atmosphereSystem.PumpSpeedup() / (float)Math.Sqrt(overPressConst*Atmospherics.OneAtmosphere);
return alpha * (float)Math.Sqrt(inlet.Pressure - outlet.Pressure);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ private void OnVolumePumpUpdated(EntityUid uid, GasVolumePumpComponent pump, Atm
return;

// We multiply the transfer rate in L/s by the seconds passed since the last process to get the liters.
var removed = inlet.Air.RemoveVolume(pump.TransferRate * args.dt);
var removed = inlet.Air.RemoveVolume(pump.TransferRate * _atmosphereSystem.PumpSpeedup() * args.dt);

// Some of the gas from the mixture leaks when overclocked.
if (pump.Overclocked)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ private void OnFilterUpdated(EntityUid uid, GasFilterComponent filter, AtmosDevi
}

// We multiply the transfer rate in L/s by the seconds passed since the last process to get the liters.
var transferVol = filter.TransferRate * args.dt;
var transferVol = filter.TransferRate * _atmosphereSystem.PumpSpeedup() * args.dt;

if (transferVol <= 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private void OnUpdate(EntityUid uid, PressureControlledValveComponent comp, Atmo
else
{
comp.Enabled = true;
transferRate = Math.Min(control * comp.Gain, comp.MaxTransferRate);
transferRate = Math.Min(control * comp.Gain, comp.MaxTransferRate * _atmosphereSystem.PumpSpeedup());
}
UpdateAppearance(uid, comp);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ private void OnOutletInjectorUpdated(EntityUid uid, GasOutletInjectorComponent i
var timeDelta = args.dt;

// TODO adjust ratio so that environment does not go above MaxPressure?
var ratio = MathF.Min(1f, timeDelta * injector.TransferRate / inlet.Air.Volume);
var ratio = MathF.Min(1f, timeDelta * injector.TransferRate * _atmosphereSystem.PumpSpeedup() / inlet.Air.Volume);
var removed = inlet.Air.RemoveRatio(ratio);

_atmosphereSystem.Merge(environment, removed);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ private void OnVentScrubberEnterAtmosphere(EntityUid uid, GasVentScrubberCompone

private void Scrub(float timeDelta, GasVentScrubberComponent scrubber, GasMixture? tile, PipeNode outlet)
{
Scrub(timeDelta, scrubber.TransferRate, scrubber.PumpDirection, scrubber.FilterGases, tile, outlet.Air);
Scrub(timeDelta, scrubber.TransferRate*_atmosphereSystem.PumpSpeedup(), scrubber.PumpDirection, scrubber.FilterGases, tile, outlet.Air);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Content.Server/Atmos/Portable/PortableScrubberSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ private void OnDestroyed(EntityUid uid, PortableScrubberComponent component, Des

private bool Scrub(float timeDelta, PortableScrubberComponent scrubber, GasMixture? tile)
{
return _scrubberSystem.Scrub(timeDelta, scrubber.TransferRate, ScrubberPumpDirection.Scrubbing, scrubber.FilterGases, tile, scrubber.Air);
return _scrubberSystem.Scrub(timeDelta, scrubber.TransferRate * _atmosphereSystem.PumpSpeedup(), ScrubberPumpDirection.Scrubbing, scrubber.FilterGases, tile, scrubber.Air);
}

private void UpdateAppearance(EntityUid uid, bool isFull, bool isRunning)
Expand Down
1 change: 1 addition & 0 deletions Content.Server/Atmos/Reactions/FrezonCoolantReaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, Atmos
energyReleased = burnRate * Atmospherics.FrezonCoolEnergyReleased * energyModifier;
}

energyReleased /= atmosphereSystem.Speedup; // adjust energy to make sure speedup doesn't cause mega temperature rise
if (energyReleased >= 0f)
return ReactionResult.NoReaction;

Expand Down
1 change: 1 addition & 0 deletions Content.Server/Atmos/Reactions/PlasmaFireReaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, Atmos
mixture.AdjustMoles(Gas.CarbonDioxide, plasmaBurnRate * (1.0f - supersaturation));

energyReleased += Atmospherics.FirePlasmaEnergyReleased * plasmaBurnRate;
energyReleased /= atmosphereSystem.Speedup; // adjust energy to make sure speedup doesn't cause mega temperature rise
mixture.ReactionResults[GasReaction.Fire] += plasmaBurnRate * (1 + oxygenBurnRate);
}
}
Expand Down
1 change: 1 addition & 0 deletions Content.Server/Atmos/Reactions/TritiumFireReaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, Atmos
mixture.ReactionResults[GasReaction.Fire] += burnedFuel;
}

energyReleased /= atmosphereSystem.Speedup; // adjust energy to make sure speedup doesn't cause mega temperature rise
if (energyReleased > 0)
{
var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture);
Expand Down
9 changes: 9 additions & 0 deletions Content.Shared/CCVar/CCVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,15 @@ public static readonly CVarDef<bool>
public static readonly CVarDef<float> AtmosTickRate =
CVarDef.Create("atmos.tickrate", 15f, CVar.SERVERONLY);

/// <summary>
/// Scale factor for how fast things happen in our atmosphere
/// simulation compared to real life. 1x means that a room takes as
/// long to heat up in game as real life. Players typically expect
/// things to happen faster in-game.
/// </summary>
public static readonly CVarDef<float> AtmosSpeedup =
CVarDef.Create("atmos.speedup", 64f, CVar.SERVERONLY);

/*
* MIDI instruments
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@
True: { state: freezerOn }
False: { state: freezerOff }
- type: GasThermoMachine
coefficientOfPerformance: -64
coefficientOfPerformance: -3.9
- type: ApcPowerReceiver
powerDisabled: true #starts off
- type: Machine
Expand Down Expand Up @@ -334,7 +334,7 @@
True: { state: heaterOn }
False: { state: heaterOff }
- type: GasThermoMachine
coefficientOfPerformance: 32
coefficientOfPerformance: 0.95
- type: ApcPowerReceiver
powerDisabled: true #starts off
- type: Machine
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
# It fires processing on behalf of its connected circulators.
- type: AtmosDevice
- type: TegGenerator
powerFactor: 0.025

- type: DeviceNetwork
deviceNetId: AtmosDevices
Expand Down

0 comments on commit cfe558f

Please sign in to comment.