Swimming is a movement type similar to flight but restricted to deep water areas. Player movement behaves just as in flight: +moveup and +jump both propel the player upwards, +movedown inversely propels the player downwards. Forward and backward movement likewise take free look view pitch into account, allowing to scale walls up and down quickly.
The differences with flight is that the player is still subjected to gravity when idle. As long as the player is moving forward, backward, or sideways, gravity is not applied; however is the player remains motionless in water, gravity starts dragging the player pawn towards the depths. However, the speed increase from gravity is divided by 16 if the player is lightly submersed (waterlevel at 1), by 8 for deeper submersions (waterlevel at 2 or 3). Furthermore, the speed will not accelerate past one sixth of a map unit per tic for a corpse, and one half map unit per tic for non-corpse actors.
Each actor has a waterlevel variable that can be set at 0, 1, 2 or 3. This originates from Boom and is used to track immersion in deep water effects created through Transfer_Heights, though ZDoom extended it to also work with 3D floors. This variable can be referenced in DECORATE expressions as well as in ACS with APROP_Waterlevel.
- 0: Not submerged at all (e.g. standing on solid ground or on shallow TERRAIN-based water)
- 1: Less than half submerged ("ankle deep")
- 2: At least half submerged ("waist deep")
- 3: Entirely submerged (completely underwater)
Water level is set to 3 if standing in an underwater sector (featuring a WaterZone), if the water surface is above the top of the actor, or if the actor is a player and the water surface is above the player's view height. (So a player that is not entirely submersed can still have waterlevel set to 3 if the player's camera is under water. This can become relevant as the default player view heights are generally below where it should be judging from the player sprites.) It is set to 2 if the water surface is not above the top of the actor, but still above half the actor's height. It is set to 1 if the water surface is not above half the actor's height, but still above the actor's foot level. Not that footclip from TERRAIN effects are not taken into account for this computation. Water level is set to 0 in all other cases.
When a player's waterlevel is increased to 3, the "*dive" sound is played on the player pawn's VOICE channel. Inversely, if it is decreased from 3, the "*surface" sound is played, or the "*gasp" sound if the player was drowning before surfacing. If snd_waterreverb is true, a underwater reverberation effect is automatically applied.
In addition to the simpler WaterLevel variable. Actors also have a WaterDepth variable, which returns the exact depth the actor is at in map units.