Grass

Usage guide of world.grass: an instanced, wind-swept meadow kept off routes, clearings and water; settings and defaults, the coverage live setting, service, the grass.place hook, saves and engines.

Source: module-kits:kits/world_grass/usage/en.mdView Markdown source

Also read offline — CLI: grip-forge docs world-grassMCP tool: gripforge_docs { "topic": "world-grass" }

A meadow over your ground (world.grass) #

Thousands of grass tufts over the ground, placed once and drawn instanced. Readable offline: gripforge docs world-grass, or the MCP tool gripforge_docs (topic world-grass). The other environment kits are in the environment guide.

What it is for #

world.grass collects what the world declares (the ground or terrain extent, the routes, the clearings, the water, the thickets) and places the meadow once, deterministically from a seed: a jittered grid over the ground, emptied on routes, clearings and water, taller and denser in the thickets. The presenter draws each tuft as a pair of crossed quads that bend in the wind, darker at the roots, fading with the distance to the camera. The placement runs over the first ticks, a slice of cells at a time.

Turn it on #

{ "id": "world.grass", "config": { "density": 1 } }

It requires game.engine. It needs a ground to grow on: world.ground, an arena or a terrain (size 0 uses its extent).

First example #

<!-- test: kits/game_engine/host/tests/world_scenery.rs::the_shares_are_live_settings --> A project with an arena and world.grass at density 1. After one tick the meadow is placed; setting coverage to 0.5 hides about half of it, and the tufts that stay are the same ones in the same order.

{ "op": "step", "ticks": 1 }
{ "op": "call", "service": "world.grass.settings", "method": "set", "args": ["coverage", 0.5] }
{ "op": "call", "service": "world.grass", "method": "placements", "args": [] }

Settings and defaults #

SettingTypeDefaultMeaning
densitynumber2tufts per square metre (0.02 to 8)
maxCountinteger40000ceiling of tufts; beyond it the grid is thinned evenly (100 to 120000)
sizenumber0side of the ground in metres; 0 takes the ground or terrain extent
seedinteger11random seed
clearancenumber5.5metres kept free on each side of a route
banknumber1.5metres kept free along the water
heightnumber0.7height of a tuft in metres (thickets are half as tall again)
widthnumber0.8width of a tuft in metres
colorstring#5f9a3ebase colour of the blades
tipColorstring#a9cc60colour of the tips
variationnumber0.35colour variation between tufts (0 to 1)
windnumber0.8sway strength (0 to 3)
fadeDistancenumber140metres from the camera beyond which the grass fades out
thicketsbooleantruetaller, denser grass in the thickets the world declares
coveragenumber1share of the meadow shown at the start (0 to 1)
everywherebooleanfalseon a terrain, grow on any ground layer, not only grass, meadow and moss

Services, events, hooks #

  • world.grass (service): placements() the tufts shown, look() the colours, size and wind, regenerate() places the meadow again (answers the number of tufts), coverage(share?) reads or sets the share shown (clamped to 0 to 1).
  • world.grass.settings (service): the live settings other kits can drive, with keys(), get and set. One key today: coverage, so world.bindings can grow the meadow from a variable.
  • grass.changed (event): the meadow was placed again; payload count. Presenters redraw on it.
  • scene.entered, terrain.edited (events, listened to): the meadow is placed again, so a scene change or a terrain edit re-grows it.
  • grass.place (hook): { size, seed, density, maxCount }, asked before each placement; seed, density and maxCount can be changed. It cannot be cancelled: a meadow is always placed (coverage 0 shows none).
{ "id": "winter", "hook": "grass.place", "set": { "density": 0.5 } }

Modding #

Every setting above is moddable, as is the live setting coverage. Without a tap on grass.place the kit plays as before.

Saves #

The save keeps only coverage; the meadow itself is rebuilt from the config and the world.

Engines #

Web and the native player. There is no separate Godot, Unity or Unreal delivery.

When it does not do what you expect #

  • No grass: the ground has no extent (size 0 and no ground or terrain), or coverage is 0.
  • Grass on a road: the route is not declared by lanes.routes; raise clearance.
  • Grass missing on sand or rock: on a terrain, only grass, meadow and moss layers grow; set everywhere to true.
  • Too few tufts for the density: maxCount thins the grid; raise it.
  • A change of config has no effect: call regenerate().

Limits #

One meadow per game, no per-tuft collision or interaction, no trampling. Beyond maxCount tufts the grid is thinned, not extended.

Versions #

Kit 1.3.0 (service contract 1.2.0). coverage since 1.1.0, live settings since 1.2.0, the grass.place hook since 1.3.0.