# 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 ```text 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 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`. ```text 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 | Setting | Default | Meaning | |---|---|---| | `capacity` | 64 | Maximum registered animals plus reserved offspring (dead ones count until removed) | | `maturityAge` | 60 | Minimum parent age; age advances only through `step` | | `gestation` | 30 | Time from a successful mating to a birth ready for confirmation | | `breedingCooldown` | 60 | Minimum interval after mating for both parents; a pregnancy also reserves both | | `litterSize` | 1 | Offspring reserved at mating and confirmed together (1 to 8); `capacity` must fit two parents plus the litter | | `matingRange` | 3 | Maximum full three-dimensional distance between the parents | | `minimumHealth` | 0.8 | Minimum normalized health (0 to 1) for mating | | `minimumNutrition` | 0.6 | Minimum normalized nutrition (0 to 1) for mating | | `mutation` | 0.05 | Uniform variation added around the parental mean of each trait, clamped to 0..1 | | `seed` | 1 | Nonzero 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 | Name | Detail | |---|---| | `animal.breeding.created` | An instance was created; payload `{ instance, preset }`. | | `animal.breeding.removed` | An instance was removed; payload `{ instance }`. | | `animal.breeding.changed` | A decision command was applied; payload `{ instance, op, result }`. | | `animal.breeding.refused` | A 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. ```json { "id": "no_twins", "hook": "animal.breeding.request", "match": { "op": "mate" }, "cancel": true, "reason": "season closed" } ``` ## Presets and scripts Presets. A document `{ "id": "", "config": { … } }` in the project data collection `animal_breeding_presets` names a ready-made tuning. `create(id, { "preset": "", … })` 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.