import type { AxisInput } from "../input/axisInput.js"; /** How the boat turns: a rudder needs water flowing past it; an outboard swings its own thrust. */ export type BoatSteering = { kind: "rudder"; /** Rudder area, m². */ area: number; /** Largest rudder angle, rad (default `0.6`). */ maxAngle?: number; /** Share of prop thrust that washes over the rudder as flow, `0..1` (default `0.5`) — steering at low speed. */ propWash?: number; } | { kind: "outboard"; /** Largest thrust angle, rad (default `0.5`). */ maxAngle?: number; }; /** * A powered hull in physical units. Drag rises toward hull speed (`√(g·L)·1.34`) and then falls away once the hull * planes, the keel resists sliding sideways, and the prop's thrust fades as the boat approaches the prop's speed. */ export interface BoatTuning { /** Displacement, kg. */ massKg: number; /** Waterline length, m; sets hull speed and the rudder's lever arm. */ length: number; /** Beam, m; sets the visual roll response. */ beam: number; /** Peak prop thrust, N. */ maxThrust: number; /** Speed at which prop thrust reaches zero, m/s. */ propSpeed: number; /** Reverse thrust as a share of `maxThrust` (default `0.4`). */ reverseScale?: number; /** Hull drag coefficient × wetted frontal area, m², before planing (default `0.3 · beam`). */ dragArea?: number; /** Speed where the hull planes and drag drops, m/s; omit for a displacement hull that never planes. */ planingSpeed?: number; /** Drag multiplier once fully planing, `0..1` (default `0.35`). */ planingDrag?: number; /** Keel lateral resistance, N per (m/s)² of sideways speed (default `massKg · 6`). */ keel?: number; /** Extra yaw damping, N·m per rad/s, on top of the keel resisting rotation along the hull (default `0`). */ yawDamping?: number; steering: BoatSteering; /** Rudder or outboard slew rate, rad/s (default `2`). */ steerRate?: number; /** Largest bow-up pitch while climbing onto the plane, rad (default `0.12`). */ bowRise?: number; /** Largest heel in a hard turn, rad (default `0.15`); planing hulls lean into the turn. */ maxHeel?: number; /** Integration substep, s (default `1/240`). */ maxSubstep?: number; } /** World hooks for a boat instance. */ export interface BoatOptions { position?: readonly [number, number, number]; heading?: number; /** Water surface height, m, under a point at a time (waves); default flat at the spawn height. */ waterHeight?: (x: number, z: number, time: number) => number; /** Surface current, m/s, `[vx, vz]`; the hull drags toward it. */ current?: (x: number, z: number) => readonly [number, number]; } /** Serializable boat state. */ export interface BoatState { x: number; y: number; z: number; heading: number; vx: number; vz: number; yawRate: number; steerAngle: number; time: number; bodyPitch: number; bodyRoll: number; } /** One boat tick: pose plus the telemetry wake, spray and engine sound read. */ export interface BoatStep { position: readonly [number, number, number]; heading: number; forwardSpeed: number; lateralSpeed: number; yawRate: number; /** Rudder or outboard angle, rad, positive steers like `steer > 0`. */ steerAngle: number; /** `0` displacement … `1` fully planing. */ planing: number; /** Thrust in use as a share of `maxThrust`, `0..1` — engine load. */ engineLoad: number; bodyPitch: number; bodyRoll: number; /** Always `0`: the hull rides the water surface. Present so `tickDrivableVehicle` can drive it. */ airOffset: number; airborne: boolean; } /** A force-based powered hull on the same tick/snapshot/retune contract as `VehicleDynamics`. */ export interface BoatDynamics { tick(dt: number, input: AxisInput): BoatStep; pose(): { position: readonly [number, number, number]; heading: number; }; velocity(): readonly [number, number]; applyImpulse(dvx: number, dvz: number): void; retune(next: BoatTuning): void; tuning(): BoatTuning; snapshot(): BoatState; restore(state: BoatState): void; resetTo(position: readonly [number, number, number], heading: number): void; } /** * Creates a {@link BoatDynamics}: throttle drives the prop, brake reverses it, steer swings the rudder or outboard. * A rudder boat barely turns at rest unless the prop is washing over it; an outboard turns at rest because it swings * the thrust itself. Deterministic for a given `dt` sequence. * @capability boat-dynamics force-based powered hull — hull-speed drag hump, planing, keel, rudder that needs flow or outboard thrust */ export declare function createBoatDynamics(initial: BoatTuning, options?: BoatOptions): BoatDynamics;