Skip to main content

Scripting

The module is one ModuleScript, ReplicatedStorage.Ocean, that works on the server and on every client. Its two child scripts start it; you only require it.

local Ocean = require(game.ReplicatedStorage.Ocean)

The full list of methods, properties and events is in the API reference. This page shows the patterns.

Where is the surface?​

Works on both sides, and always agrees between them: the wave function is a pure function of the settings, the weather state and server time.

local y = Ocean:GetHeight(position)          -- world Y of the surface above/below the point
local depth = Ocean:GetDepth(position) -- studs under the surface, negative above
local under = Ocean:IsUnderWater(position) -- false inside an OceanDry region
local normal = Ocean:GetSurfaceNormal(position)

GetHeight accounts for weather, zones, obstacles and FlatSea. It is cheap enough to call per frame for a handful of things; for hundreds of parts, sample every few frames.

Water events​

Player characters are tracked automatically. Tag anything else OceanTrack (or OceanFloat, which also floats it) or call Ocean:Track(instance).

Ocean.EnteredWater:Connect(function(instance) end)   -- dry -> wet
Ocean.ExitedWater:Connect(function(instance) end) -- wet -> dry
Ocean.WentUnderWater:Connect(function(instance) end) -- fully submerged
Ocean.WentAboveWater:Connect(function(instance) end) -- surfaced

local state = Ocean:GetWaterState(instance) -- { Touching, Under, Depth, Surface } or nil
for _, thing in Ocean:GetInstancesInWater() do end

A server Script gets server-side events, a LocalScript client-side ones.

Weather​

A weather is a named table of setting overrides. Only weather settings count (waves, colours, foam, spray, the underwater tint); other keys are ignored, which is why a preset can be passed straight in. Server only.

Ocean:CreateWeather("Storm", Ocean.Presets.Ocean["Pirate Seas"])
Ocean:CreateWeather("Glassy", { WaveHeight = 0.25, FoamOpacity = 0 })

Ocean:SetWeather("Storm", 30) -- cross-fade the whole sea over 30 s
Ocean:SetWeather("Default") -- back to the module's own attribute values, instantly
print(Ocean:GetWeather()) -- "Default"

The state lives in one attribute on the module, so late joiners get it for free, and the fade is timed on server time so nothing drifts.

Scripted zones​

A disc of sea with its own weather, blended into the surroundings across its rim:

Ocean:CreateZone("Bay", { Position = Vector3.new(0, 0, 2000), Radius = 800, Blend = 200, Weather = "Glassy" })
Ocean:SetZoneWeather("Bay", "Storm", 10)
Ocean:RemoveZone("Bay")
print(Ocean:GetWeatherAt(position)) -- the weather with the most influence there

For zones built in Studio, tag a part OceanZone instead: see Tags. Those can carry any setting, not only weather ones, and the Zones addon handles Lighting for them.

Settings from code​

Settings are attributes on the module. On the server, either write them directly or through the validated setter:

local Settings = Ocean.Settings
Settings.Set("WaveHeight", 1.4) -- clamped to the spec; returns the value stored, or nil
Ocean:SetAttribute("FoamStyle", "Solid") -- also fine
Settings.OnChanged(function(name) end) -- fires on either side

for _, entry in Settings.List do -- the spec the plugin panel is built from
print(entry.Name, entry.Section, entry.Default, entry.Hint)
end

On a client, Settings.SetLocalOverride(name, value) makes that client use a value without replicating it (the Zones addon uses this to give a player inside a zone that zone's look).

Tags from code​

The tag helpers are plain CollectionService tags underneath, so instance:AddTag("OceanFloat") does the same thing.

Ocean:AddFloat(part)                  -- floats (Buoyancy addon)
Ocean:AddObstacle(pier) -- calms the water around it (OceanShore, OceanCalmness attributes)
Ocean:AddDryRegion(submarineInterior) -- no water inside its box
Ocean:Track(buoy) -- events only

The tag names follow the FloatTag, ObstacleTag, DryTag, TrackTag and ZoneTag settings; Ocean.Tags.Float and friends give the current names.

Driving the plugin​

In Studio, the plugin exposes shared.InfiniteOcean from the command bar and from MCP agents: Install(), Preset("Pirate Seas"), Set("WaveHeight", 1.2), Addon("Swimming", true), Preview(true) and more. The AgentSupport addon's README lists every command.