# Rivers, lakes and lava in your game (world.water) ## What it is for `world.water` turns documents of the `water_bodies` collection into bodies of water: a river (a centre line and a width), a lake (a disc) or a waterfall (a sheet). Each body has a preset (`river`, `lake`, `swamp`, `lava`, `ice`) that sets its colours, current, waves, slowdown and damage. The kit computes the surface height with its waves, slows and splashes whoever walks in it (the player through the character motor), burns in lava, and makes tagged entities float. The renderer draws one animated surface per body. Colliders, swimming and buoyancy forces are not part of it. It is one of the environment kits: see also [Environment of your world](guide:world-environment). ## Turn it on Install `world.water` (it requires `game.engine@^1`) and add bodies to the project, or to a scene (`data.water_bodies`). A scene may also set the defaults in `layers["world.water"]`. ```json { "id": "pond", "preset": "lake", "at": [0, 0], "radius": 5, "waves": 0 } ``` ## First example With the `pond` above, `at(3, 0)` answers `"pond"` and `at(6, 0)` answers `null`; `heightAt(0, 0)` is `0.05`; `speedAt(0, 0)` is `0.68` (the lake slows walkers by 32 %). Setting the live setting `level` to `500` is clamped to `200`, `heightAt` becomes `200.05`, and the level is saved and restored by a load. ## Settings and defaults | Setting | Type | Default | Meaning | |---|---|---|---| | `preset` | string | `river` | Look of a body that names none: `river`, `lake`, `swamp`, `lava`, `ice`. | | `flow` | number | `1.2` | Default current, metres per second (0 to 10). | | `opacity` | number | `0.82` | Default opacity in the middle; banks are clearer (0.1 to 1). | | `foam` | boolean | `true` | Foam along the banks. | | `waves` | number | `0.07` | Default wave height in metres (0: flat). | | `slow` | number | `0.2` | Default share of speed walkers lose in water (0 to 0.9). | | `splashes` | boolean | `true` | Whoever moves through water throws splashes. | | `floatTag` | string | `floating` | Entities with this tag float. | | `rise` | number | `0` | Metres added to every surface at start (-200 to 200). | The preset scales these defaults: a lava body flows slowly (a `flow` of `1.2` becomes `0.42`) and slows walkers more (a `slow` of `0.2` becomes `0.3`) and deals `40` damage per second. A document may override `preset`, `points`, `width`, `at`, `radius`, `level` (default `0.05`), `flow`, `shallow`, `deep`, `foam`, `opacity`, `kind`, `yaw`, `height`, `waves`, `slow` and `damage`. A body is a river when it has `points`, a lake when it has `at` and `radius`, a waterfall with `kind: "waterfall"` (`at`, `yaw`, `width`, `height`). A document without a shape is ignored. ## Services, events, variables - `world.water` (service): `bodies()`, `at(x, z)` (the id of the body there, or `null`), `heightAt(x, z)` (the surface with its waves, `null` outside water), `speedAt(x, z)` (`1` outside water), `float(entity, { draft?, drift? })`, `rise()`. - `world.water.settings` (service): `keys()`, `get(key)`, `set(key, value)`; the only key is `level`, metres added to every surface (-200 to 200). `world.bindings` can drive it from a variable. - `water.splash` (event): `{ entity, body, position, strength }`. - `water.entered`, `water.left` (events): `{ entity, body }`. - `water.changed` (event): `{ rise }`, when the level moves. ## Hooks and modding The hook `water.enter` runs when a walker steps into a body, before `water.entered`, with `{ entity, body, preset, slow, damage }`. `slow` and `damage` are mutable for this walker until it leaves, and the hook is cancellable: a cancelled walker is not in the water for the kit (no event, slowdown, splash or damage) until it has left that body. ```json { "id": "fireproof", "hook": "water.enter", "match": { "preset": "lava" }, "if": [{ "var": "suit.on", "op": "==", "value": true }], "set": { "damage": 0 } } ``` A mod can override `preset`, `flow`, `opacity`, `foam`, `waves`, `slow`, `splashes` and `rise`, change the `water_bodies` collection and the setting `level`. Another kit can hand over waterways it owns through `world.waterways`. ## Engines The logic is the same Rust implementation on the web and in the native player. The surface and the splashes are drawn by the kit's presentation module. Water is delivered for the web and Rust targets. ## When it does not do what you expect - A body does not appear: it has neither `points` nor a disc (`at` and `radius`), or no `id`. - Walkers are not slowed: `slow` is `0`, or the game is not in the playing phase, or a tap cancelled `water.enter`. - An entity does not float: it needs the `floatTag` tag or a `float(entity)` call. ## Limits Floating is a height and a drift, not buoyancy: nothing sinks. A river lies at one level and does not run down a slope. Waterfalls are decoration (no current at their foot). ## Versions Kit 1.4.0, service `world.water` 1.1.0. The live level exists since 1.2.0, the `water.enter` hook since 1.3.0, and the saved refusal of a cancelled `water.enter` since 1.4.0.