Referenced from this post, I use three different waves with this Gerstner Wave formula to get waves. The SampleTick is on the server and read by the clients to render the ocean but the server can also read it itself to get positions on the server if need-be.
function GerstnerWave(SamplePosition ,Wavelength, Direction, Steepness, Gravity, SampleTick)
local k = (2 * math.pi) / Wavelength
local a = Steepness/k
local d = Direction.Unit
local c = math.sqrt(Gravity / k)
local f = k * d:Dot(Vector2.new(SamplePosition.X,SamplePosition.Z)) - c * SampleTick
local cosF = math.cos(f)
--Displacement Vectors
local dX = (d.X * (a * cosF))
local dY = a * math.sin(f)
local dZ = ( d.Y * (a * cosF))
return Vector3.new(dX, dY, dZ)
end
However, the boat is always off compared to the client, I want to find a way to sync them up to look fluid-ish, I don’t want perfection, I want something that’s presentable, but my current method is anything but.