Animal breeding

Usage guide of animal.breeding: mating eligibility, reserved litters, gestation, deterministic trait inheritance and confirmed births, with settings, commands, events, hooks and presets.

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

Also read offline — CLI: grip-forge docs animal-breedingMCP tool: gripforge_docs { "topic": "animal-breeding" }

Animal breeding (animal.breeding) #

What it is for #

Individual animal reproduction for a game: you register the animals, the kit checks that a pair may mate (mature, healthy, fed, in range, not related, not on cooldown), reserves room for the litter, runs the gestation and computes the offspring traits. The newborns exist only when the engine creates them and confirms their identities.

Turn it on #

gripforge_gamekit_install   { project_id: "gkp_…", id: "animal.breeding" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "animal.breeding", config: { "litterSize": 2, "gestation": 120, "seed": 7 } }

Only the keys that differ from the defaults need to be written. Each animal is one named instance, created by the game; a fresh game already has one instance called default.

First example #

<!-- test: kits/animal_breeding/tests/animal_breeding.rs::mating_creates_a_pregnancy_with_a_litter_and_cooldowns --> Two fit, mature animals are registered; mating them reserves a litter of two and puts both parents on cooldown. The animals here are described by age, health, nutrition, alive, fertile, position and traits.

config  { "capacity": 6, "maturityAge": 10, "gestation": 2, "breedingCooldown": 5, "litterSize": 2, "matingRange": 3, "seed": 7 }
request ["default", { "op": "register", "animal": { "id": "doe", "species": "deer", "role": "carrier", "age": 20, "health": 1,
                      "nutrition": 1, "alive": true, "fertile": true, "position": [0,0,0], "traits": { "size": 0.2, "speed": 0.8 } } }]
request ["default", { "op": "register", "animal": { "id": "stag", "species": "deer", "role": "donor", ...same fields } }]
request ["default", { "op": "mate", "carrier": "doe", "donor": "stag" }]
   -> pregnancies[0] = { carrier: "doe", donor: "stag", ready: false, offspring: [2 entries] }, reserved: 2, each parent cooldown 5

Settings and defaults #

SettingDefaultMeaning
capacity64Maximum registered animals plus reserved offspring (dead ones count until removed)
maturityAge60Minimum parent age; age advances only through step
gestation30Time from a successful mating to a birth ready for confirmation
breedingCooldown60Minimum interval after mating for both parents; a pregnancy also reserves both
litterSize1Offspring reserved at mating and confirmed together (1 to 8); capacity must fit two parents plus the litter
matingRange3Maximum full three-dimensional distance between the parents
minimumHealth0.8Minimum normalized health (0 to 1) for mating
minimumNutrition0.6Minimum normalized nutrition (0 to 1) for mating
mutation0.05Uniform variation added around the parental mean of each trait, clamped to 0..1
seed1Nonzero deterministic seed for inherited traits and offspring roles

Commands #

register { animal } adds an animal (id, species, role of carrier, donor or either, plus the fields above); duplicates, bad values and a full population are refused. observe updates an animal’s observed state, remove drops one (a pregnancy of a removed parent is cancelled). mate { carrier, donor } starts a pregnancy when the pair is eligible: mature, fit, in matingRange, not direct relatives, not in cooldown or pregnancy, with room for the litter. step { dt } advances ages, cooldowns and gestations; a dead carrier loses the pregnancy. When a pregnancy is ready, the engine creates the newborns and sends resolveBirth { token, success, ids } with one new identity per offspring (the whole litter, no duplicates); a failed birth keeps the pregnancy so it can be tried again. Offspring traits are the parents’ average plus the mutation variation. preview, status, config, save and load read and restore.

Services #

The kit is a driver service: it decides only when the game calls it, never on its own tick.

  • create(id, config): creates a named instance (config is checked; at most 128 instances; an existing id is refused); returns the id.
  • request(id, command): sends one command object to an instance and returns its answer (unknown instance or invalid command: an error).
  • remove(id): removes an instance; returns whether it existed.
  • ids(): lists the instance ids.

status, config, save, preview and load are reads and state operations; step is the fixed-step command the game sends every tick. Every other command is a decision and goes through the request hook below.

What it announces #

NameDetail
animal.breeding.createdAn instance was created; payload { instance, preset }.
animal.breeding.removedAn instance was removed; payload { instance }.
animal.breeding.changedA decision command was applied; payload { instance, op, result }.
animal.breeding.refusedA tap of the request hook cancelled a decision; payload { instance, op, by, reason }.

Hooks and modding #

A game or a mod taps a hook with a document of its hooks list, without touching the kit:

  • animal.breeding.create: before an instance is created; payload { instance, preset, config }; a tap may replace config, or cancel (creation then fails with creation refused).
  • animal.breeding.request: before a decision command is applied; payload { instance, op, command }; a tap may replace command, or cancel: the call then answers { ok: false, cancelled: true, by, reason } and the refused event is emitted.
{ "id": "no_twins", "hook": "animal.breeding.request", "match": { "op": "mate" }, "cancel": true, "reason": "season closed" }

Presets and scripts #

Presets. A document { "id": "<name>", "config": { … } } in the project data collection animal_breeding_presets names a ready-made tuning. create(id, { "preset": "<name>", … }) starts from it; the keys given next to preset win (shallow merge). An unknown preset is an error; the created event carries the preset name.

Scripts and rules can drive an instance with the action animal_breeding_request { instance?, command } (instance defaults to default) and test it with the condition animal_breeding_exists { instance? }.

When it does not do what you expect #

  • mate is refused: read the message — capacity (no room for the litter), gestation, a cooldown, relatives or a distance beyond matingRange; fix the animal data or the settings.
  • resolveBirth is refused as stale, premature or incomplete: use the token of the pregnancy, wait until it is ready, and give exactly one new identity per offspring.

Limits #

  • The kit creates no entity: the engine spawns the newborns, owns the world and the persistence of the entities; juveniles mature only as step advances their age.
  • No hidden tick: nothing happens between two step commands, and time passes only by the dt the game sends.
  • Instances are saved and restored with the game (including the random generator, so a reload replays the same choices); a pending action must be resolved first.
  • Targets: the native kit host and the web player, from the same Rust core. The kit has no display module.

Versions #

1.1.0 (2026-10-19): game.engine hooks, presets, outcome events and script verbs; 1.0.0 (2026-10-16): first release. Requires no other kit.