Biomes
Split one map into named regions with their own habitat, local world counters, an opening condition and effects on survival gauges, and ask which region a point is in.
Regions of your map (world.biomes) #
Readable offline: gripforge docs world-biomes, or the MCP tool gripforge_docs (topic world-biomes). The kit is also summarised in the family guide Environment of your world.
What it is for #
world.biomes divides one map into regions. A biome is a document of the biomes collection: a disc or a rectangle on the ground plane, a habitat (land, water or both), offsets on the world counters (a pole 30 degrees colder), an optional opening condition (closed until a counter reaches a mark) and effects on the survival gauges of whoever stands in it.
The kit places nothing and walls nothing. It answers questions (which biome is here, what is a counter worth there, is it land or water, give me a random point inside) and follows the player a few times a second to set a variable, emit events and apply the gauge effects. What a closed biome means (a barrier, nothing growing) is the game's decision. Everything it reads from other kits is optional: without world.stages the counters are 0, without survival.needs the gauges are left alone.
Turn it on #
gripforge_gamekit_install { project_id: "gkp_…", id: "world.biomes" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "world.biomes",
config: { "default": { "name": "Wilds", "modifiers": { "heat": -2 } } } }
Then add documents to the biomes collection of the project. The kit requires game.engine.
First example #
<!-- test: kits/game_engine/host/tests/world_biomes.rs::the_highest_priority_then_the_smallest_biome_covers_a_point --> Four biomes, with world.stages holding a heat counter that starts at 1 and default set as above:
[
{ "id": "plain", "name": "Plain", "shape": { "rect": [-10, -10, 10, 10] }, "modifiers": { "heat": 3 } },
{ "id": "pond", "name": "Pond", "habitat": "water", "shape": { "center": [5, 5], "radius": 2 } },
{ "id": "peak", "name": "Peak", "priority": 5, "shape": { "center": [0, 0], "radius": 3 },
"opensWhen": { "counter": "heat", "atLeast": 5 } }
]
at(0, 0) answers peak (highest priority), at(5, 5) answers pond, at(-8, 8) answers plain and at(50, 50) answers nothing. habitatAt(5, 5) is water. local("plain", "heat") is 4 (the counter 1 plus the biome's 3) and local(null, "heat") is -1 (the counter plus the default's -2). randomPoint("pond") gives a point for which contains("pond", x, z) is true.
Biome documents #
| Field | Meaning |
|---|---|
id, name | required; name is what biome.current shows |
shape | required: a disc { center: [x, z], radius } or a rectangle { rect: [minX, minZ, maxX, maxZ] } |
habitat | land (default), water or both |
priority | where biomes overlap the highest wins (default 0), then the smallest |
modifiers | offsets added to world counters: { "heat": -30 } |
opensWhen | { counter, atLeast?, atMost? }: closed until the counter is in range, then open for good |
needs | on survival gauges: { "<need>": { "drain": 2, "supply": 0.5 } }, a drain multiplier and / or units per second |
color, tags | for maps and the HUD |
world | the only world this biome exists in (with travel.worlds); absent: every world |
Settings and defaults #
| Setting | Type | Default | Meaning |
|---|---|---|---|
default | object | none | name, habitat and modifiers of everywhere no biome covers |
announce | boolean | true | emit biome.entered and biome.left when the player changes biome |
Services, events, variables #
world.biomes(service):biomes(),at(x, z)(a biome id or null),of(entity),current(),get(id),isOpen(id),local(id | null, counter),habitatAt(x, z)(landorwater;bothcounts as land; water where the terrain or a water body says so),randomPoint(id, rng?),contains(id, x, z),scope(id)andscopeId().biome.entered(event):{ biome, name }, the player walked into a biome.biome.left(event):{ biome }, the player walked out of one.biome.opened(event):{ biome, name }, a closed biome opened (once).biome.current(variable): the name of the biome the player stands in, or the name of the default.in_biomeandbiome_open(conditions for scripts and rules):{ "in_biome": "north_pole" },{ "biome_open": "deep_sea" }.biome(HUD view): a chip with the name of the biome the player is in.
The opened biomes and the player's biome are saved.
Hooks and modding #
biome.enter{ biome, name, from }: asked when the player steps into a biome, before the variable,biome.enteredand the gauges. Mutablebiomenames another biome of the live world the player counts in instead; cancelled, the player counts in no biome (a sealed suit: no gauge effect). The position queries (at,of,current,in_biome) keep answering by position.biome.open{ biome, name }: asked when the opening condition is met. Cancelled, the biome stays closed until the condition stops holding and holds again.
{ "id": "sealed_suit", "hook": "biome.enter", "match": { "biome": "waste" },
"if": [{ "var": "suit", "op": "==", "value": true }], "cancel": true }
A mod may override default and announce, and add, patch or remove documents of biomes.
Worlds #
With travel.worlds, a biome carrying world exists only in that world and the opened biomes are kept per world. scope(id) makes a world's biomes the live ones; scopeId() returns the live world (empty before any is named).
Engines #
The rules run in the Rust kit host, on the web player and the native player. The HUD chip is a web UI view.
When it does not do what you expect #
- A biome never opens: the counter named in
opensWhenis not in range, or noworld.stagescounter has that name. biome.currentshows the default's name: the player is outside every shape, or abiome.entertap cancelled.- A closed biome can be entered: the kit does not wall it; test
biome_openorisOpen(id)in your own rules. - A biome of another world never matches: its
worlddiffers from the livescopeId().
Limits #
No terrain, no spawning and no collision: it describes regions. Shapes are discs and rectangles on the ground plane (x, z).
Versions #
Kit 1.3.0. 1.1.0 added worlds, 1.2.0 the hooks and moddable config, 1.3.0 the saved continuous decision of biome.open.