DEMIENGINEPACKAGE STORE Everything is free
← Explore packages
Gameplay

Water Gameplay

Published by DemiEngine · Version 1.0.0

About this package

Water Gameplay

Opt-in fixed-step buoyancy, flow-relative drag and dynamic-body swimming over prepared terrain water. No renderer, automatic listeners or fluid simulation. Import the specific service you need:

local Buoyancy = require("demi.gameplay.water.buoyancy")
local Swimming = require("demi.gameplay.water.swimming")
local float = Buoyancy.new("boat", {half_height = .5, density_ratio = 1.05})
local swimmer = Swimming.new("player", {speed = 3, min_depth = 1.5, max_flow = 2.5})

function Behaviour:on_fixed_update(dt)
  local floating = float:fixed_update(dt)
  local swimming = swimmer:fixed_update(dt, {1, 0, 0}) -- world-space direction
end

A game owns input/camera conversion, character animation, oxygen, transitions between land and swimming controllers, and choosing which entities participate. These modules do not change gravity, position, collider shape or body type. Use Rigidbody3D dynamic bodies with authored colliders. Static, kinematic, disabled and missing bodies receive no forces. A missing/dry water column also receives no force. Native contacts remain authoritative.

Buoyancy

Buoyancy.new(entity_id, options) accepts half_height (world units, default 0.5), density_ratio (default 1.05), linear_drag (per second, default 2), gravity (world acceleration vector, default {0,-9.81,0}), and optional terrain_id. Density ratio scales displacement lift relative to configured body mass; larger values make the virtual body float higher. It is a gameplay ratio, not a measurement of the collider's true displaced volume.

The virtual volume is a constant cross-section upright segment centred on the body origin. Its overlap with surface-to-bed water is measured along native column_up, including transformed terrain placements. It does not sample hull vertices, apply torque or stabilize rotation. Gravity acceleration is explicit: match it to the game's physics gravity and body gravity scale when seeking neutral equilibrium. Lift still acts if native body gravity is disabled; the package never toggles or silently restores that property.

Drag damps velocity relative to authored water flow using an exponential step; its drag-only response is independent of timestep subdivision and cannot reverse relative velocity. Buoyancy plus native contact/gravity remains a fixed-step approximation. Both lift and drag use Rigidbody3D.add_force, not teleportation.

Swimming

Swimming.new(entity_id, options) accepts speed (world units/second, default 3), acceleration (world units/second squared, default 8), linear_drag (default 2), min_depth (default 1.5 world units), max_flow (default 2.5 world units/second), and optional terrain_id. These are game policy, not native water eligibility rules. The body origin must be immersed; shallow water or a flow above the chosen limit leaves land movement to the caller.

fixed_update(dt, world_direction) clamps direction length to one, accelerates toward the chosen velocity relative to flow, then applies water drag. Drag can reduce the attained speed. Vertical input permits ascent/descent. Gravity is unchanged: add Buoyancy if desired, or author the swimming body's gravity policy. Do not simultaneously apply a separate land controller's movement force.

Both update methods return a retained state table (active, sample, and for buoyancy submersion). Read it immediately; the next update replaces its values. Copy values that a game needs to retain. Use demi.terrain.water.tracker directly for point enter/stay/exit events; these modules do not invent collider events.

All options, fixed timesteps and input directions must be finite. Fixed timestep and half-height must be positive; rates and thresholds are nonnegative. Call exactly once per physical step, in on_fixed_update; calling twice adds forces twice. Shader water ripples change shading normals only, so gameplay samples and floating objects use the same underlying flat/follow-bed surface.

examples/water_interaction_3d demonstrates real native contacts, buoyancy and swimming with deterministic E2E assertions. Package tests exercise math and configuration; demi-water-gameplay-tests exercises these same Lua modules through the actual Lua/physics runtime without a window.

Tags

Dependencies

No additional package dependencies.

Related packages