-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Model static fires equalizing with the local atmosphere #32760
base: master
Are you sure you want to change the base?
Conversation
Please be aware that our pull request guidelines ask that you split up unrelated refactoring changes (e.g. removing |
In place of |
Stepping back a bit and considering gameplay design issues: What problem does this solve? If it's about finding a way to supply the station with gas that isn't a miner, isn't this like a super beefed gas canister? Now I can see why you want to make burning the candles require a bit more work. But I see two issues here:
|
Would it be possible to name the candles something realistic? Like real Oxygen candles used in submarines are sodium chlorate that on burning produce oxygen and salt. For nitrogen it could be ammonium nitrate since it thermally decomposes into nitrogen and water. |
Okay, so I got clued into more of this bug with the run away temps when I noticed that the temperatures between the flammable entities and the local atmos weren't equalizing at all. It turns out that AtmosExposed entities were just creating energy and not conserving it with the atmos tile they were on. I addressed that, so although this isn't "superconduction" its... conduction lmao. Stepping back a bit from the gas candles specifically, and thinking more about what this means for flammable things -- ya know, big ol' fires -- with these changes fires will now be scary not just because you might catch fire, but they can be scary just to be near them. |
@@ -107,7 +107,7 @@ public override void Update(float frameTime) | |||
var query = EntityQueryEnumerator<AtmosExposedComponent, TransformComponent>(); | |||
while (query.MoveNext(out var uid, out _, out var transform)) | |||
{ | |||
var air = GetContainingMixture((uid, transform)); | |||
var air = GetContainingMixture((uid, transform), false, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would need to be in a separate PR if we make this change. I need to spend some time looking at this and see if exciting the mixture is really needed to get temperature to transfer correctly with AtmosExposed
, but this may have significant detrimental performance impacts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a nitpick, please name the optional non-default arguments (e.g. GetContainingMixture((uid, transform), excite: true)
. This makes it a lot more apparent what the argument is, especially if someone is reviewing from a diff/GitHub/anything but Rider.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I tested it without exciting it did work, but then the room's gas mix could have different temperatures in different tiles that wouldn't change until something else excited the gas in the room.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would need to be in a separate PR if we make this change.
In the interest of fixing the bug, Ill move the gas emission stuff to another PR, I think for it to work I need burning to have temperature behave reasonably so it makes more sense to start there. I do agree that its kind of soaped into something else in supporting making static fires modeled now.
This is pretty closely related to #319 because it implements temperature as a more interactive atmos mechanic. |
@@ -107,7 +107,7 @@ public override void Update(float frameTime) | |||
var query = EntityQueryEnumerator<AtmosExposedComponent, TransformComponent>(); | |||
while (query.MoveNext(out var uid, out _, out var transform)) | |||
{ | |||
var air = GetContainingMixture((uid, transform)); | |||
var air = GetContainingMixture((uid, transform), ignoreExposed: false, excite: true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default arguments need not be re-specified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not all atmos exposed devices necessarily need to be excited. Things only need to be excited if the mixture is changed. So this call should be delayed until it's guaranteed that the mix is changed.
var tempBump = MathF.Sqrt(maxDeltaT * temp.SpecificHeat * physics.Mass) * flammable.FireStacks; //monotonic function, slows as it reaches maxT | ||
_temperatureSystem.ChangeHeat(uid, tempBump, false, temp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a really roundabout way to do _temperatureSystem.ForceChangeTemperature
.
I still don't think this is necessarily the right way to do this, because it does not respect energy conservation in terms of energy supplied by the candle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked into this a bit more, if we do this (which is something like was originally there):
It does eventually equalize like we would expect, and so we can output a constant* amount of energy while burning into the room, and as long as something is burning the room will continue to get arbitrarily hotter.
However, as it turns out, most things contain a simply ludicrous amount of energy. irl we're talking like 15,000,000j (15megajoules) per kg of wood. In irl this doesnt turn your fireplace into a nuclear bomb because most of the heat is lost to the sky, but a spacestation is an enclosed box, so it conserves all the energy. This would mean if we used real values almost any fire is immediately ultra-deadly.
Understanding that, I think we have two alternatives.
- We can go with a constant joule output, and just make up (much lower than irl) joule quantities for entities to make fires not immediately awful, but rooms will continue to heat if you burn more stuff.
- We can do some sort of asymptoting function and have the room reach a maximum temperature based on whatever the burned entity is.
Both solutions seem fine to me, I do think the asymtote would be easier to maintain and harder to abuse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, so superconduction is the thing that makes the station not an ideal enclosed box. The built-in "asymptoting function"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or I guess we can do a hybrid, and have it asymptote with a smaller minimum joule gain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well hold on. That might be total joules contained in the entity. So then, ~3hr burn time, we would get something like 1,400j/s Thats still pretty high, but not as high.
Okay sure, lets try it just with no asymptote, and just see how it feels.
ChangeHeat(uid, heat * temperature.AtmosTemperatureTransferEfficiency, temperature: temperature); // move heat to entity | ||
_atmosphere.AddHeat(args.GasMixture, -1 * heat * temperature.AtmosTemperatureTransferEfficiency); // remove heat from air |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separate PR, because this is a bug fix to TemperatureSystem
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its necessary for temp-emitting fires.
Without it, temperatures cant equalize and run away.
firestackFade: -0.01 | ||
damage: | ||
types: | ||
Heat: 0.1 | ||
- type: Temperature | ||
- type: AtmosExposed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not need to be added here, because you EnsureComp
it when it gets lit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its not strictly necessary, and probably fine if we drop it, but it does mean that the temperature of flammable things will be wrong when they initially catch fire. Could lead to weird behavior like catching fire initially cooling the room before heating it again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is that?
This would mean that every single candle gets called in the AtmosUpdate
event.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They would have whatever the prototype temperature is (usually 20C) until they gain the AtmosExposedComponent and equalize. So if the room is already hot, say 50C, when the candle is lit it will initially be colder than the room and pull heat from the air until it reaches room temp.
Although now I'm saying that, I can probably just fake it by setting the entitie's temperature to the air temp when it first ignites.
Everything said, I think the presently-PR'd heat-addition approach ( |
About the PR
Previously, burning things would become very hot, however, and then they might break from taking heat damage. This was about all that happened.
Now, burning things heat up to a maximum temperature, while doing so, they emit heat into the local atmosphere. The local atmosphere can also cool flammable entities, effectively equalizing their temperature over time. This means being near burning things could be a bad idea, it also means you can use burning things to heat a cold room, or a cold room to cool burning things down.
Why / Balance
If you're burning, you're still gonna die, and the damage from actually burning has not changed. The difference is you will no longer become the surface of the sun hot from being briefly on fire. This might lead to less ashings as high temperature (which are very hard to alleviate in game) also cause heat damage. However, although you are not on fire, burning things may still heat up the room, and a hot room may still hurt you.
The big balance change here, is that now the temperature is more realistically simulated, which means, Atmos now needs to pay attention to what the temperature is in different parts of the station. If the only thing contributing to temperature changes is player homeostasis rooms should equalize to ~37C, and no one will likely notice. However, flaming things may be way more dangerous.
Technical details
I changed the logic of how the flammable component handled increasing heat. Previously it was just additive and lead to absurd temperatures approaching - or surpassing - the surface of the sun in a matter of minutes. Now that doesn't happen.
I added a limit to the temperature that a burning entity will increase to. This limit can be changed, and might be a good idea to do so depending on accelerants splashed or other factors, but I leave that as an exercise for the reader.
Part of this was enuring that flammable entities are AtmosExposed.
I also changed how AtmosExposed works to make the temperature of the entity not just be effected by the gas around it, but force them to find an equilibrium by conserving the energy when the atmos tile tries to heat an entity. This might mean that its more likely for atmos tiles to become and stay excited.
Media
Requirements
Breaking changes
Flammable prototypes may need to have their Temperature and Flammable component setting adjusted to account for heat transfer between them and the local atmosphere.
Changelog
🆑