Animal taming

Usage guide of animal.taming: per-handler trust, fear, confirmed feeding and soothing, ownership, bond loss, release and transfer, with settings, commands, events, hooks and presets.

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

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

Animal taming (animal.taming) #

What it is for #

Taming rules for a game: each animal keeps a trust value per handler and a fear value. Feeding and soothing raise trust, harm and time lower it, and once a handler’s trust reaches the taming threshold that handler becomes the owner. The game stays authoritative over inventory and the world: an interaction is only a request until the game confirms it.

Turn it on #

gripforge_gamekit_install   { project_id: "gkp_…", id: "animal.taming" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "animal.taming", config: { "tameTrust": 0.7, "feedTrust": 0.25 } }

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_taming/tests/animal_taming.rs::feeding_asks_for_one_item_and_trust_grows_only_when_the_engine_confirms --> A handler feeds a wild animal. The kit asks the game to consume one item; trust grows only when the game confirms with the token (here feedTrust is 0.45).

request ["default", { "op": "interact", "actor": "ann", "kind": "feed", "distance": 1, "visible": true, "safe": true, "alive": true }]
   -> { "action": { "kind": "feed", "amount": 1, "token": 1 }, "relationships": { "ann": 0 }, ... }
request ["default", { "op": "resolve", "token": 1, "success": true, "amount": 1 }]
   -> { "relationships": { "ann": 0.45 }, "action": null, ... }

Settings and defaults #

SettingDefaultMeaning
maxHandlers16Maximum remembered handlers per animal (use forget to free a slot)
interactionRange2Maximum observed distance for feeding or soothing
feedTrust0.2Trust gained for one confirmed unit of acceptable food
sootheTrust0.05Trust gained when a soothing interaction is confirmed
sootheFear0.15Fear removed by a confirmed soothing interaction
tameTrust0.8Trust that makes a handler the first owner, if the animal has none
breakTrust0.1An owner loses the bond when harm brings their trust to this value or below (below tameTrust)
maxFear0.4Highest fear that still permits an interaction
fearDecay0.1Fear recovered per safe living simulation second
trustDecay0.001Trust lost per second by non-owners (an owner’s trust does not decay)
harmTrust0.5Trust lost from the reported aggressor at severity 1
interactionCooldown1Minimum seconds between issued interactions, failed attempts included
receiptTimeout2Simulation seconds the game has to confirm an interaction

Commands #

interact { actor, kind, distance, visible, safe, alive } asks for a feed or soothe interaction; it needs range (interactionRange), visibility, safety, a free handler slot and a fear not above maxFear, and answers with an action and a token. resolve { token, success, amount } confirms it: a failed receipt or a zero amount gives nothing, and a receipt that comes after receiptTimeout or for another token is stale. harm { actor, severity } (0 to 1) costs the aggressor trust, raises fear and can break the owner’s bond at breakTrust. step { dt, alive, safe } lets fear and trust decay; danger cancels a pending interaction. The owner can release { actor } the animal or transfer { actor, to } it (the trust goes with the animal); forget { actor } frees a handler slot but never removes the owner. preview, status, config, save and load read and restore; the status holds owner, tamed, fear and the relationships (trust per handler).

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.taming.createdAn instance was created; payload { instance, preset }.
animal.taming.removedAn instance was removed; payload { instance }.
animal.taming.changedA decision command was applied; payload { instance, op, result }.
animal.taming.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.taming.create: before an instance is created; payload { instance, preset, config }; a tap may replace config, or cancel (creation then fails with creation refused).
  • animal.taming.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_transfer", "hook": "animal.taming.request", "match": { "op": "transfer" }, "cancel": true, "reason": "bound to its owner" }

Presets and scripts #

Presets. A document { "id": "<name>", "config": { … } } in the project data collection animal_taming_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_taming_request { instance?, command } (instance defaults to default) and test it with the condition animal_taming_exists { instance? }.

When it does not do what you expect #

  • Trust does not grow: the interaction was never confirmed (no resolve, a failed receipt, a zero amount, or a receipt after receiptTimeout).
  • An interaction is refused: check range, visibility, safe, the cooldown, the fear against maxFear and the number of handlers against maxHandlers; only the owner can release or transfer.

Limits #

  • The kit never touches inventory, food or the world: the game consumes the items and confirms. Ownership is mirrored by the game; trust of a handler fades with time unless the handler is the owner.
  • 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.