Vixen
c7401864
csharp
public sealed class BuoyancySystem

Floats every BuoyancyBody on the one surface everything else reads.

Read the guide page for this →

As a system

Phase
FixedUpdate

Remarks

[35 § D10](../../docs/plan/35-water.md#d10-buoyancy-is-pontoons-over-jolt-evaluated-at-the-fixed-steps-water-time), and the whole of what this assembly is for. Per fixed step, per pontoon: ask the surface where it is, work out how much of the sphere is under it, and apply the force at the pontoon's own world position — which is what makes a hull pitch when somebody stands at the bow rather than bob level.

⚠ Before PhysicsStepSystem and after PhysicsSyncSystem, and both halves of that matter. Jolt accumulates forces and clears them at the step, so a force applied after the step is a force that is thrown away — a boat that sinks with the system visibly running. And a force applied before the sync is a force on a body the sync is about to create, which is the first frame of every boat lost.

⚠ It reads the simulation's water time off IWaterSurface and never its own GameTime. A force computed from a frame time changes when the frame rate does, which in a networked game is a client and a server disagreeing about where a boat is — [16](../../docs/plan/16-networking.md)'s determinism requirement applied to a force. WaterClockSystem is what advances that clock, and it does so in EarlyUpdate precisely so that this can read it.

⚠ Jolt has a buoyancy impulse of its own and it is deliberately not used. It takes a plane, which is exactly the approximation a wave surface is not — and using it would put a second definition of the water surface inside the physics engine, where § D2's seam test cannot reach it.

⚠ Ripples are not passed, and the omission is the design. The closed-form sum is exact and answerable at any time; a ripple field is a simulation whose state is its history, and a rollback re-simulating six ticks cannot ask it where the surface was. So the force a server computes and the force a client predicts are the same function of the same arguments. A wake that pushed a boat around would be a wake that desynced it.

Fields and properties (10)

  • public WaterDisturbances? Disturbances

    Where this step's wakes and splashes go, or null to produce none.

  • public float WakeSpeed

    How fast a pontoon has to move through water before it makes a wake, in m/s.

  • public float SplashSpeed

    How fast a pontoon has to enter the water before it splashes, in m/s.

  • public IWaterSurface Surface

    Where the water is, and the clock it is at.

  • public SystemAccess Access
  • public int Floating

    How many bodies the last step floated — those with at least one wet pontoon.

  • public int Pontoons

    How many pontoons it evaluated, across every body.

  • public int WetPontoons

    How many of those touched water.

  • public ReadOnlySpan<BuoyancyForce> Forces

    The forces the last body evaluated produced, for a debug draw.

  • public int LastCount

    How many of Forces are the last body's.

Methods (3)

Used by (4)

  • BuoyancyDebugDrawVixen.Water.Physics
  • BuoyancyDebugDrawTestsVixen.Water.Physics.Tests
  • BuoyancySystemTestsVixen.Water.Physics.Tests
  • WaterSceneRunsTestsVixen.Editor.Assets.Tests