Einstein-Engines icon indicating copy to clipboard operation
Einstein-Engines copied to clipboard

Physics Based Air Throws

Open VMSolidus opened this issue 1 year ago • 17 comments

Description

I've made it so that when a room is explosively depressurized(or when a body of high pressure air flows into one of lower pressure air), that entities inside are launched by the air pressure with effects according to their mass. An entity's mass is now used as an innate resistance to forced movement by airflow, and more massive entities are both less likely to be launched, and will launch less far than others. While lighter entities are launched far more easily, and will shoot off into space quite quickly! Spacing departments has never been so exciting! This can be made extraordinarily fun if more objects are given the ability to injure people when colliding with them at high speeds.

As a note, Humans are very unlikely to be sucked into space at a typical force generated from a 101kpa room venting into 0kpa, unless they happened to be standing right next to the opening to space when it was created. The same cannot be said for "Lighter-Than-Human" species such as Felinids and Harpies. I guess that's just the price to pay for being cute. :)

On a plus side, because the math behind this is simplified even further than it was before, this actually runs more efficiently than the previous system.

TODO

Nothing, this is basically done. I've spent a good 6 hours straight finely tuning the system until I was satisfied that it reflects something close to reality.

MEDIA

Before the Space Wind Rework:

https://github.com/Simple-Station/Einstein-Engines/assets/16548818/0bf56c50-58e6-4aef-97f8-027fbe62331e

With this Rework:

https://github.com/Simple-Station/Einstein-Engines/assets/16548818/6be507a9-e9de-4bb8-9d46-8b7c83ed5f1d

Changelog

:cl: VMSolidus

  • add: Atmospheric "Throws" are now calculated using object mass, and behave accordingly. Tiny objects will shoot out of rooms quite fast!

VMSolidus avatar Apr 29 '24 11:04 VMSolidus

Certainly very impressive, and I like the effect a lot. I am concerned by the sheer number of variables being discarded (I didn't even note them all!). Even if we feel they aren't required here, they also may just be unused now, and modifying them may not have the implied effect.

Any idea why the items on the table to the left of the breach in the video seem to be unaffected, while things much further away in the room are blasted?

That one's an interesting thing to look at. Since objects can only be moved if the force of the air flow is greater than the square of their mass, objects that are lightweight are pulled from farther away(If you look at the top right, you can see that the pens from the Dev medbay were transported all the way from medical to the hole), while objects that are heavier need to be relatively close. The force being applied scales inversely with distance, and the size of the hole in question has an effect on how much force can be applied. The C4 made a very large hole, which in turn spread the force out over a much wider area. The heavier steel on the left wasn't affected because the force wasn't great enough.

I've also noticed that the relative geometry of the hallways leading up to the hole have their own effects on the airflow.

VMSolidus avatar Apr 29 '24 13:04 VMSolidus

image

I haven't actually removed the variables from the system, reasoning that someone may inevitably try to use them. But they were all either Constants or CVars, not really true math variables. I'm actually not modifying any variables that get passed back, just usingh what information was already available to the function via its access to PhysicsComponent. Another function elsewhere already derives the force of a pressure differential. I did however need to keep some of the exit conditions, because technically the equation I have replaced this with is a parametric equation, it must have some form of limit.

image

Actually, now that you mention it, because I am dividing by true variables and not constants, I now need to go back and address potential divide by zero exits.

VMSolidus avatar Apr 29 '24 13:04 VMSolidus

https://github.com/Simple-Station/Einstein-Engines/assets/16548818/75f74969-5da0-4bf9-8bdf-70ce158b8b9e

https://github.com/Simple-Station/Einstein-Engines/assets/16548818/23de7a87-dcd7-48b8-9768-b7c20f9666d5

VMSolidus avatar Apr 29 '24 13:04 VMSolidus

Psprite don't merge this yet, I have a pretty good idea how I'm going to reimplement the speed clamp. It basically just means I need to test constants. In ApplyLinearImpulse(uid, vector, physicscomponent), vector is given in the form r(costhetai + sinthetaj), and in this case dirVec is a vector based on an r=1 circle, and moveForce is my value for r. I simply need to replace these two uses of moveForce with Math.Clamp(moveForce, 0, constant)

And then brute force test constants in a dev environment until I find one where it's impossible to fling a sheet of paper through a steel wall.

VMSolidus avatar Apr 29 '24 15:04 VMSolidus

hahahahahaha this fucking rules, oh my god

bit odd that the mouse and the urist arent affected, though

rosieposieeee avatar Apr 29 '24 15:04 rosieposieeee

Okay! I've added the clamp back in, and did some rather extreme limit testing to determine that this actually is a good number to set the velocity limit to, which is to say it cannot exceed 30 meters per second of acceleration.

VMSolidus avatar Apr 29 '24 18:04 VMSolidus

This is now ready for some excellent reviews.

VMSolidus avatar Apr 29 '24 18:04 VMSolidus

While examining the equations, I figured out another small optimization. Physics components contain an Inverse Mass, equal to 1/Mass. Since multiplication runs faster than division, I can make a small optimization to the equation by multiplying by InvMass instead of dividing by Mass, achieving the same result faster. Since this is a physics system that runs hundreds of times per tick, every small improvement matters a lot.

Getting rid of the division sign means its also no longer possible to divide by zero, so we no longer need to check if mass is 0 to prevent division by zero errors.

VMSolidus avatar May 01 '24 20:05 VMSolidus

I've added a Before and After video demonstration to this PR, showing what exactly has been changed.

VMSolidus avatar May 14 '24 18:05 VMSolidus

A solution needs to be thought of to prevent human-mobs from being untouched. The realism of it is quite unimportant- people need to be able to get flung into space.

This could be making the amount that mass impacts diminishing so that very heavy things can still be flung, or it could be giving mobs Components to change how they're impacted by depressurization.

I will outright refuse this Psprite because that is extremely, ridiculously out of scope for this PR, because it would necessitate completely rewriting how air flow is calculated in the first place. The original system literally just generated a random number and then used that random number to decide if a human was to be thrown. As a stopgap for the equations for air flow simply being not up to par.

VMSolidus avatar May 15 '24 04:05 VMSolidus

A solution needs to be thought of to prevent human-mobs from being untouched. The realism of it is quite unimportant- people need to be able to get flung into space.

This could be making the amount that mass impacts diminishing so that very heavy things can still be flung, or it could be giving mobs Components to change how they're impacted by depressurization.

Additionally, I attempted solutions in testing for creating a stopgap to throw humans more consistently, and it had run into many of the same problems the original creator did, where if even the tiniest of player character throws happened, it made the game feel extremely awful to play due to the system constantly wresting control from the player. Fixing that is also out of scope for this PR.

VMSolidus avatar May 15 '24 04:05 VMSolidus

A solution needs to be thought of to prevent human-mobs from being untouched. The realism of it is quite unimportant- people need to be able to get flung into space.

This could be making the amount that mass impacts diminishing so that very heavy things can still be flung, or it could be giving mobs Components to change how they're impacted by depressurization.

So I'll, give it an attempt to find a solution to this, but I'll preface it with this. This is an extremely tick intense physics system. This function I optimized runs thousands of times per tick, and every individual line added to it runs up the frametime on an already incredibly frametime hungry system. Adding unnecessary component checks won't do, adding even more math checks here won't do. That improvement you're asking for is going to take making a significant improvement elsewhere, namely in airflow. Airflow pathfinding is extremely bad, creating unusually deep pockets of ultra-fast moving air, while vast portions of the station don't receive anywhere close to the pressure differential that physics dictates they should. For one airflow is only orthogonal adjacent. If I can free it up to perform diagonal movement too, that should in turn dramatically improve the ability of it to throw objects in unusual places, or for heavier objects. That would also allow air to throw objects diagonally, instead of just orthogonal.

For me to accommodate this specific request, I am not going to find a satisfactory solution for it in the function this PR touches.

VMSolidus avatar May 15 '24 05:05 VMSolidus

This function I optimized runs thousands of times per tick

That should not happen for anything, no wonder it sucks for performance

DEATHB4DEFEAT avatar May 15 '24 05:05 DEATHB4DEFEAT

This function I optimized runs thousands of times per tick

That should not happen for anything, no wonder it sucks for performance

I managed to find a extremely common exit condition that bypasses almost 200 lines of script. It should run about 1/100th as often now.

VMSolidus avatar May 16 '24 04:05 VMSolidus

@Pspritechologist I have implemented most of your requested changes, but one in particular is essentially impossible to do within the scope of this PR.

  • [x] Added an extremely early exit condition that bypasses the ENTIRE high pressure differential system if the input pressure differential is less than the square of the MinimumCalculatedMass. It should significantly cut down on the frametime of this system to an almost comical degree.
  • [x] Added a MaximumCalculatedInverseMass, which acts as a hard limit on how massive an entity can be before it no longer has any increased resistance to space wind. Humans are still unlikely to be thrown by space wind at standard atmospheric pressures unless they stand in one of the zones of high airflow, but it's better than it was before at least.
  • [x] OUT OF SCOPE: Fixing the underlying issues with air flow itself is not possible within the scope of this PR, and would require refactoring pretty much all of atmos. I'd rather refactor atmos in piecemeal, with more manageable bite sized chunks.
  • [x] DECLINED: Declined to move math functions into a separate variable. Normally I would agree to this, if this wasn't a physics system where every hundredth of a millisecond matters for server performance.

VMSolidus avatar May 16 '24 18:05 VMSolidus

  • [x] Added an optional CVar that increases the simulation complexity of air flow, which in turn fixes the issue of objects being trapped in an infinite loop of slamming into a wall repeatedly
  • [x] Fixed the issue of animals not having the correct mass, and thus not being consistently thrown by space wind
  • [x] Fixed a 7 month old bug in the temperature code that made animals with a mass < 1kg boil themselves to death in standard atmosphere.

VMSolidus avatar May 16 '24 19:05 VMSolidus

This pull request has conflicts, please resolve those before we can evaluate the pull request.

github-actions[bot] avatar May 20 '24 06:05 github-actions[bot]

This pull request has conflicts, please resolve those before we can evaluate the pull request.

github-actions[bot] avatar May 29 '24 03:05 github-actions[bot]

This is ready for review. @DEATHB4DEFEAT @Pspritechologist @DangerRevolution @Peptide90 @OldDanceJacket

VMSolidus avatar Jul 01 '24 23:07 VMSolidus

I believe when we last talked about this, the maxvelocity cvar wasn't working correctly, and you were going to reimplement it after changing up some of the math as it currently does nothing.

Aidenkrz avatar Jul 02 '24 02:07 Aidenkrz

I believe when we last talked about this, the maxvelocity cvar wasn't working correctly, and you were going to reimplement it after changing up some of the math as it currently does nothing.

Thanks for the reminder, re implementing the max velocity was actually pretty easy. image

VMSolidus avatar Jul 02 '24 03:07 VMSolidus

I believe when we last talked about this, the maxvelocity cvar wasn't working correctly, and you were going to reimplement it after changing up some of the math as it currently does nothing.

Actually, do you mind passing me your improvements to TileRipping? I'd like to bring them here if they work well enough there.

VMSolidus avatar Jul 02 '24 03:07 VMSolidus

Actually, do you mind passing me your improvements to TileRipping? I'd like to bring them here if they work well enough there.

Already deleted the branch, it was pretty terrible code that I just threw together in five minutes for a proof of concept. IIRC essentially all i did was add a counter that ticked up from the start of it being called, multiply it by a random float, and then multiply the delta by that.

Aidenkrz avatar Jul 02 '24 03:07 Aidenkrz

Going to play around with this pre-review; while I do like the DS14 version, still worth testing. This should be held off from merging until @DEATHB4DEFEAT and/or @Pspritechologist review it too due to the importance/scale :)

DangerRevolution avatar Jul 03 '24 22:07 DangerRevolution