41 KiB
Executable File
Fauna: evidence, calendar time and integration contract
Reviewed 2026-11-04. Scope includes the catalogue, wildlife runtime, direct in-game interaction panel and focused Lua tests. No engine run or visual-quality acceptance is claimed by this change.
Public interfaces
The catalogue is a factory: dofile(modpath.."/fauna.lua")(hearth,api).
It returns VERSION, SECONDS_PER_DAY, list() / catalog() (ordered record
arrays), get(id_or_entity), kind(id_or_entity), source(id) (URL array),
phase(id,born_at,utc), breeding_window(id,month) and
can_breed(id,born_at,utc,sex,season?). Unknown IDs return nil or deny breeding.
All catalogue records and lists are defensive copies. Records expose id,
entity, common, latin, source_url, wikipedia_url, sources, confidence,
profile (unaltered lifecycle evidence), foods, prey, medium, activity,
bounds, mesh, texture, clips, fps, frames, eye_height and policy caps.
Main may construct hearth.fauna before wildlife. Otherwise wildlife loads the
fixed sibling factory via api.get_modpath("hearth"); no caller-supplied path or
saved asset name is accepted. The catalogue uses hearth.lifecycle or loads the
fixed sibling lifecycle module. Main should inject lifecycle so seeded cohort ages
use its duration() selection consistently. No network request occurs at runtime.
Wildlife returns fauna, species (legacy hare entity), global_cap,
player_cap, local_cap, ai_budget, status(). Status includes legacy
total, hare, deer, fox, plus a copied counts dictionary containing all
23 IDs, species_count=23, actions, births, meals, grazed, dung,
deaths, pollinations, dispersals, detritus, and the three caps.
It also exposes a defensive recruitment diagnostics copy: interval=5,
scan_nodes=648, attempts, successes, scans, last_reason, and reasons
(reason-to-count dictionary). The /ecosystem survey displays all species plus
admission attempts, successes and the latest outcome; it remains observation-only.
Reasons include waiting,
invalid_player, global_cap, no_surface, observer_near,
blocked_or_unloaded, habitat_unloaded, no_active_food_match,
population_cap, unsafe_body, activation_rejected, admitted,
registry_unavailable, region_budget, and region_seeded.
status().residents is a fresh diagnostics table containing storage_ok,
regions, region_limit=4096, region_size=48, founders_per_region=4, and
the persistent individual counter. Counts describe loaded residents, not the
entire unloaded population. Diagnostics do not expose mutable journal records.
Field journal and ambient grouping
Right-clicking a live, pointable animal records that species in the observing player's metadata under a versioned, bounded, canonical species-ID list. The species guide marks recorded and not-yet-encountered identities; opening a catalogue-only profile never unlocks an encounter. This is a private per-player field-journal convenience, not a local census, achievement reward, or change to the animal/world state. Invalid saved journal text fails closed and is never overwritten. Active robins, blackbirds, blue tits and mallards also use a small, local cohesion/separation bias when choosing wander direction. It is computed from loaded same-species residents only—there are no persisted flock IDs, unbounded entity scans, or forced spawn groups.
These are original adaptations of ambient grouping and encounter journaling ideas visible in Animalia's public bird behavior, AI, and Libri source. Last Hearth does not include that mod's code, models, textures or audio.
Runtime API integration
The managed package pins the MIT-licensed Creatura 0.2.10 release from ContentDB
release 34130; the downloaded archive SHA-256 and upstream commit are recorded
in mods/creatura/UPSTREAM.md. Creatura supplies
animal-focused pathfinding, boid algorithms and its ABM spawn scheduler.
Last Hearth supplies species identities, original meshes/textures, habitat and
diet policy, caps, protected/provenance-aware admission, persistent resident
IDs, feeding transactions and player interactions. Creatura spawn callbacks do
not bypass Last Hearth's on_activate checks. Ambient ABMs are restricted to
common species, small groups, natural soil types and fixed per-species caps; no
drops, taming, combat or livestock systems are enabled. The bounded Last Hearth
recruitment path remains available as a fallback and does not award food when
vegetation serves only as an ambient habitat signal.
Engine API: entity/globalstep registration, connected players, loaded-only
get_node_or_nil, node definitions, node metadata, protection, add_entity,
parse_json / write_json, mod storage (hearth.storage, otherwise
api.get_mod_storage()), and normal ObjectRef position, velocity, yaw,
acceleration, armor and animation methods. Optional api.now() is an integer UTC
epoch test seam; otherwise os.time() is used. Climate uses
hearth.climate_at(utc).season; qualitative habitat seasons may be accelerated
by climate configuration, but animal ages and activity hours never are.
Direct in-game interaction
Registered animal entities are natively pointable while retaining their
existing physical collision envelope. Luanti's normal object picking dispatches
right-clicks to hearth.inspect_fauna(clicker, species_id, snapshot); this is
not a HUD raycast or a node-placement change. Wildlife verifies that the entity
is currently active and that the exact clicker is an online player with a
session, then passes a detached snapshot of calendar birth time, modeled
reserve, origin, persistence-ID availability and current rest/awake animation
observation. The callback is looked up at interaction time so wildlife does not
own formspec registration. The interface checks the online player and session
again, and escapes/bounds displayed catalogue and snapshot text. Species-guide
selection can also open a species-only profile; it is not a local animal census.
The panel reports Latin identity and source URLs, lifecycle phase and real calendar age when available, currently modeled diet and prey, activity/sleep and winter-rest policy, and whether reproduction is enabled for the profile or disabled for incomplete evidence. Food reserve is explicitly labelled as a coarse game policy, not biology. Persistent residency and current animation are observations only; no position is displayed. A direct animal encounter adds one species ID to the observing player's bounded field journal; catalogue browsing does not. Neither action changes animal state, ecology, inventory or terrain. Punching continues to trigger flee movement; immortal armor and the lack of damage/drop handlers prevent combat or item rewards. Collision and crafting/node placement remain unchanged. Native mesh appearance and animation quality were not visually verified in an engine session.
Required succession transaction contract
These are required transactional hooks; the current succession supplies them. Wildlife does not replace or bypass their shared budgets. Missing hooks or anything other than literal boolean true gives no feeding credit and no ecological-success count. Wildlife performs no direct vegetation/node mutation or inventory operation. Main must repeat all loaded/protection/provenance checks inside each transaction. Forage/deposit's entire 3x3 neighbourhood is guarded by wildlife before invocation.
| Hook | Exact required semantics |
|---|---|
habitat(pos) |
Loaded observation with loaded, grass, cover, canopy, moisture, water, near_water. Unknown/unloaded must fail recruitment. |
forage(pos) -> boolean |
Existing metadata-only natural browse debit, finite and seasonal, not inventory/crop consumption. |
deposit(pos) -> boolean |
Existing bounded metadata-only dung/nutrient receipt. One pending receipt per earned meal; no item or offline queue. |
pollinate(pos) -> boolean |
Atomically debit legitimate nectar from a mature, currently flowering natural plant and apply bounded pollination. Persist shared succ_nectar_ready_at before any callback; all bees compete for the same budget. Reject invalid timestamps. Use an explicit nectar replenishment policy; wildlife's 300-second inter-meal throttle is NOT evidence for floral replenishment. No seed generation. |
frugivore(pos, species_id) -> boolean |
Verify exact botany identity and fruiting season, then atomically debit the same botany_ready_at used by human botany.harvest. Set its existing annual (365.2425 * 86400 seconds) resource deadline before callbacks. Never maintain a parallel animal-only berry budget; reject invalid/future readiness, nonnatural/planted nodes and immature shrubs. No inventory output. |
detritivore(pos) -> boolean |
Consume a finite unit of existing natural litter and transfer only conserved organic/mineral material. Reject empty substrate. Never an infinite soil fertility aura. |
granivore(pos, species_id) -> boolean, optional_cache_id |
Debit an existing finite seasonal seed/nut resource. True grants one meal; optional "hazel" or "oak" grants a second separately debited viable nut, not the eaten seed. No token if the second nut was unavailable. |
disperse_seed(pos, species_id) -> boolean |
Accept one immediately preceding, separately debited cache nut; check loaded natural viable destination and bounded seed metadata. Only squirrel hazel/oak caches invoke this hook. Consume authority once even if the destination fails (lost nut, never duplicated). No persistent token, offline planting, pollinator seed aura, or arbitrary new species. |
The cache hook must track immediate granivore authority in succession, rather than trust arbitrary callers. Both source and destination are guarded; successful consumption and successful caching are different counters. Seed-eating mice, voles and birds are not automatically awarded dispersal. Fruit transport/gut passage is not implemented and must not be presented as simulated.
Time, provenance and deliberately unknown biology
Six profiles now enable reproduction: bank vole, wood mouse, blackbird, mallard, European hare and red fox. The sourced hare profile uses 365-day maturity, 42-day gestation, one leveret per litter and a 30-day care lock; its broad reported season is represented as Winter/Spring/Summer. The fox profile uses 304-day maturity, 53-day typical gestation, one pup per litter, and a conservative 300-day postpartum lock; its coarse breeding season is Winter. ADW reports 56-70 days of fox nursing/weaning, but the existing generic dependent-care loop cannot represent paternal provisioning or fox den care, so this species is not a complete family-behavior simulation.
Registration (pending=false for all 23) is independent
of evidence completeness. This is not whole-ecosystem true-life certification.
The following pages were retrieved on 2026-11-03; ranges are original factual
summaries, not bundled article text. Runtime uses conservative upper development
and maturity endpoints and the lower sourced litter/clutch count.
| Species | Maturity | Development to birth/hatch | Count | Sources and limitations |
|---|---|---|---|---|
| bank vole | 42-56 d sex envelope; runtime 56 d for both | 17-24 d gestation; runtime 24 d | 3-5, runtime 3 | ADW gives 17-24 d, 20-25 d weaning, late April-September; Woodland Trust supplies conservative 6/8-week maturity; Wildlife Trusts supplies the chosen 3-5 count. ADW reports a wider 1-10, typically 4-8; these are not silently merged. |
| wood mouse | 65-71 d; runtime 71 d | 21-26 d gestation; runtime 26 d | 4-8, runtime 4 | ADW gives maturity, gestation and 21 d weaning, but 4-7 young; retained 4-8 is from Wildlife Trusts. Wikipedia reports February-October season and 23-27 d gestation, differing from ADW. |
| blackbird | about one year | 13-14 d incubation; runtime 14 d | 3-4, runtime 3 | ADW gives first breeding at one year, 13-day prose/14-day summary and 13-14 d leaving nest. RSPB supplies clutch/nesting window. Fledging is not full independence. |
| mallard | 365 d both sexes | 26-28 d incubation; runtime 28 d | 9-13, runtime 9 | ADW gives these values; Wikipedia gives 50-60 d to flight and spring nesting. Unknown lifespan does not prevent breeding. |
| European hare | 236-365 d; runtime 365 d | 30-42 d gestation; runtime 42 d | 1-8 leverets, runtime 1 | ADW reports maturity at 8 months-1 year, one-month weaning, 30-42 d gestation and 1-8 per litter; winter through midsummer breeding. One-month care lock is a conservative policy. |
| red fox | about 304 d; runtime 304 d | 51-53 d typical gestation; runtime 53 d | 1-9 in ADW summary, runtime 1 | ADW reports 10-month maturity, winter mating in central-range populations, 51-53 d typical gestation and 56-70 d nursing/weaning. Its prose says 1-13 while its summary table says 1-9; the narrower table range is retained. A 300-day postpartum lock approximates its once-yearly seasonal cycle; this is policy. |
Breeding requires same-species female and male within two nodes, both mature, safe, recently fed (within twice their feeding throttle), reserve at least 0.7, and loaded food-bearing habitat. Conception spends 0.2 reserve from each parent; each delivered young spends another 0.1 from the mother and starts with 0.1. These are explicit normalized energy policies, not biological calorimetry. Only successful succession transactions earn reserve. There is no feeding-count shortcut to maturity, free fertility command, item reward or player attack.
hearth.climate_at(utc).season (or an explicitly supplied season) determines the
hemisphere-aware season gate: Spring/Summer for the four original profiles,
Winter/Spring/Summer for hare, and Winter for fox. Northern reference months remain research
observations, not a simultaneous northern-month veto on southern spring. These
coarse season policies omit some legitimate early-autumn breeding;
it is not exact local phenology. Missing climate denies new conception. Calendar
age and due times always use real epoch seconds, never climate-speed multipliers.
Pregnancy and incubation use a common persisted deadline field; eggs are a bounded maternal brood state, not mammalian pregnancy or separate nest nodes. Egg laying, nest construction, exact incubation attendance and clutch failure are not simulated. Dependent young rest rather than hunt/browse as adults; nearby loaded mothers transfer 0.05 reserve at the ordinary feeding cadence. This is coarse care accounting, not milk chemistry or a species-specific chick diet. Maternal postpartum locks are 25 d (vole), 21 d (mouse), 42 d (blackbird), 81 d (mallard), 30 d (hare) and 300 d (fox) after the last admitted young. Bird locks deliberately include an extra 21 d beyond the conservative dependency/fledging allowance. They do not claim measured inter-clutch intervals. Assets still use the authored species mesh, not visually distinct baby models.
Seventeen profiles stay reproduction-disabled, including three legacy slots. Blue tit now has BTO 8-10 typical eggs, about 14 d incubation and 18-21 d fledging; first breeding is described as the next spring, not an accepted exact day threshold, and represented caterpillar provisioning is missing. ADW's Cyanistes URL was missing and its older Parus URL contained taxonomy only; neither validates numerical overrides. Common frog adds about 3-year maturity and 14-21 d incubation, but aquatic eggs/tadpoles and their food remain absent. Brown trout needs female mass for its approximately 2000 eggs/kg, a gravel redd and temperature-dependent development. Bumblebee requires queen/worker/ male castes and colony care; a single litter timer would be misleading. Rabbit maturity, squirrel conception season, roe deer/stoat implantation, other mammal profiles, robin/barn owl care, newt larvae and worm cocoons remain incomplete. No missing values are filled with guesses. Lifespan averages never trigger death.
One-time regional founders represent existing wild individuals, not reproduction.
Where maturity is sourced, the estimated initial age uses its upper endpoint;
born_at=utc-estimated_age_days*86400, origin="established" explicitly labels
the estimate. Unknown maturity has no invented age offset and still remains an
established individual, not a purported newborn. origin="born" marks actual
admitted young with born_at=utc at delivery, including delayed admission after
an overdue pregnancy; it never creates an adult-aged catch-up cohort.
self.id remains an in-memory scheduling serial. state.resident_id is the
separate durable world-local positive integer allocated from mod storage;
state.founder_region identifies the founder's geographical cell, or is empty
for births and legacy-ID migration. Sex, selection seed, food reserve, birth
epoch and reproductive state survive normal unloading and restart. Position is
saved by the engine's static-object system, not copied into a second registry.
Feeding throttles (nectar five minutes, predators two hours, other plant food one
hour), movement speeds except earthworm, and normalized two-day energy reserves
are coarse simulation policies, not sourced metabolic measurements. Unknown
starvation durations are false: hunger can accumulate over hours/days but cannot
justify an invented death threshold. Rabbit is the sole enabled starvation
case: the fetched European rabbit account reports winter survival without food
of about 2-8 days; the conservative upper eight-day bound is used, counting
only represented loaded hunger (hunger_seconds), never an unloaded absence. This is
not a veterinary prediction for an individual. No free food appears because a
predator lacks prey. There are no modeled insect-larva, mayfly, beetle, parasite,
egg or nestling populations to feed on. Thus adult trout currently have no
supported live-prey recruitment resource; saved trout swim and remain otter prey
without pretending an unimplemented invertebrate biomass exists.
Persistence and bounds
static_save=true. Static state is version-1 JSON, at most 2048 bytes, with only
version, species, born_at, origin, sex, foodreserve, nextfeed,
pregnancy_until, last_seen, seed, last_meal, dung_pending, plus
conception_at, litter_total, litter_remaining, litter_delivered,
nextbreed, last_birth_at, parent_seed, parent_born_at, resident_id,
founder_region, hunger_seconds. No deserialize,
Lua evaluation, arbitrary asset names or paths. Exact entity/species match,
finite numeric types/ranges and coherent nonfuture observation/birth/meal clocks
are mandatory. Flat/nonnested input is checked before silent JSON decoding.
Pregnancies require an enabled female profile, mature conception, exact sourced
maximum development interval, coherent bounded integer litter counts, and a
deadline no further ahead than that interval. Overdue deadlines remain valid.
The old version-1 empty reproductive state migrates to zero counters; old nonzero
pregnancies without the new schema are refused. Next-feed deadlines are bounded to one day ahead; future birth or
observation data is rejected, never used for credit. Failed JSON encoding emits
an invalid sentinel rather than silently making a fresh cohort next load.
Validated existing residents always restore, even above species/global/local/
player caps, with no connected-player API, or on newly claimed, blocked,
foodless, nil/ignore unloaded terrain. Positive native dtime_s is expected
for restoration and is accepted. No habitat or collision read may delete a
validated existing resident merely because its surroundings changed. Invalid
snapshots, unknown fields/species, incoherent clocks or out-of-world coordinates
are still rejected, with bounded reason-only warnings (no raw payload logging).
Movement and ecological transactions stop safely inside new claims, ambiguous
claims, external protection or unknown/unsafe collision terrain. An animal on
still-safe but depleted ground can wander and become hungry rather than vanish.
There is no teleport/terrain-repair escape for an animal trapped by construction.
Deactivation forgets live counts only, idempotently; it never records a death or removes founder membership. Nothing deletes an existing animal to free admission slots. Dormant mapblock animals stay in the engine save and can return above the new-admission caps. Births and new founders, unlike restores, still require all current safety, habitat and cap checks. There is no 900-second lifetime or walk-away despawn/replenishment path.
Offline calendar ages/deadlines advance from saved epochs, but unloaded AI is frozen, not a whole-world ecological simulation. There are no replayed offline meals, mating cycles, founder admissions or dung/caching queues. An existing overdue brood is reconciled on budgeted AI after a player returns: at most one newborn per attempt, no more than its single stored litter total. Species/global/local/player caps, safe loaded positions, current habitat and maternal energy still apply. Full caps delay the original due time without redating; remaining/delivered counts survive normal save/reload. Failed admission does not spend a child; callback reservations and activation acknowledgement prevent synchronous reentry duplication. Once complete, the brood clears and postpartum lock prevents repeated deliveries. This is normal-save idempotence, not a cross-mapblock crash-atomic transaction or authenticated save format. Server-local static data is not exposed as client/admin fertility input. Schema validation rejects giant/incoherent payloads but cannot authenticate a coherently rewritten world save; operators must protect world files. No such bypass API is added. Energy/hunger work on each safe loaded observation is bounded to 60 seconds; restoration preserves reserve and accumulated hunger, resets the observation clock and clears the pending dung attempt. A successful meal or maternal feeding resets loaded hunger. Legacy snapshots start hunger at zero because their historical loaded/unloaded intervals cannot be reconstructed. Unsafe or player-absent AI turns freeze energy/hunger. No force-loading or emergence.
One-time, geographically bounded founder registry
The separate mod-storage key is wildlife_residents_v1. This does not change
the game's world-schema version. Its flat JSON envelope has version=1,
counter (last allocated individual ID), and sparse r_<x>_<z> fields.
Cell coordinates are floor(world_x/48), floor(world_z/48), including negatives;
they do not depend on player, session, Y, current population or visit count.
Each region value is a canonical bounded string:
attempts/last_attempt_utc/resident_id=species;resident_id=species;....
Both the decoder and encoder enforce the 1,048,576-byte registry ceiling;
each region value is at most 256 bytes with at most four founder memberships.
The decoder requires exact version, known species, valid bounded cell keys,
finite integral clocks/counter/IDs, unique founder IDs and no extra fields.
Nested/deep JSON is rejected before parsing; no code evaluation, assets, paths,
credentials or client-provided allocation authority are stored.
At most 4096 region records can ever be admitted automatically. Records are never evicted, reset on return, silently truncated or recycled after death. New regions beyond this permanent budget are refused; existing records and saved animals remain intact. Attempts (saturating at one billion) and last UTC are persisted even for a loaded search that has no surface, unavailable food, or unloaded/invalid candidates; these attempts do not fill founder quota. An incomplete cell remains retryable on later valid observations, with no timeout that marks an empty/unloaded area permanently populated. A full cell never fills a dead, eaten, migrated-away or currently unloaded animal's slot. Different eligible species may share its four slots; their IDs and types are retained permanently, not inferred from live counts. This is a one-time founder quota, not a continuously restored carrying-capacity target. Natural births remain independently funded by the existing calendar/food/cap rules and do not spend or refund founder slots.
Membership and monotonic ID allocation are written/read-verified before
the new animal is acknowledged. Storage read/write failure, silent dropped
writes, invalid JSON/version, duplicate/unknown membership, or any exceeded
bound disables all new admissions (including births), without deleting validated
existing residents. Missing storage also disables new admissions. A known saved
ID above a missing/rolled-back counter fails closed instead of reusing its ID.
Legacy snapshots without ID fields receive an ID and empty founder_region
when storage is healthy; with failed storage they remain valid residents without
an allocated ID, rather than being destroyed. They can migrate on a later restore
after operator repair. Never clear this key to make animals reappear: restore
world/mod-storage backups together. A process/storage crash after reservation
can conservatively spend a founder slot or burn an ID without creating an animal;
there is no cross-mapblock crash-atomic population transaction or automatic refill.
New-admission global cap is 64; player-neighbourhood cap 16 within 48 nodes;
local cap 12 within 16 nodes. Per-species caps range 2-8. Overlapping player
neighbourhoods are all checked for new founders/births only, never movement or
restoration. Loaded counts can exceed these limits after restoration; this
delays further admissions without erasing any resident. AI and founder searches share 24 actions/second,
maximum one second of accrued work; entities are visited in serial round-robin
order. Recruitment spends one action every five active seconds, with no credit
banked while players are absent. It rotates players and eight search patches,
queries one 9x9x8 box through find_nodes_in_area_under_air (648 cells maximum),
and checks one round-robin surface candidate per attempt. This is at most 12
queries / 7,776 queried cells per active minute, not a whole-map scan. Habitat,
body-envelope and ordinary AI observations are additional bounded work, not
included in that terrain-query cell count. No query may emerge unloaded blocks.
An integration without this search API reports no_surface, not a guessed Y.
Candidates lie 12-24 horizontal nodes from the selected observer; any observer within eight nodes vetoes admission. Ground/plant surfaces set the body base half a node above actual support, not at the player's Y. Water surfaces retain their own water-cell Y and use the stand above water for succession observations. The fixed vertical search band is player Y minus four through plus three; distant cliffs outside this band wait for a closer observer.
One plant-food observation and one succession habitat observation are shared
across cheap rotating catalogue matches. Only currently active, habitat/food-fit,
uncapped species receive body-safety/admission checks. There are no 23 separate
terrain scans or a forced 11.5-minute wait for the next eligible species.
Daylight flowering yarrow can admit a bee, mixed understory a bank vole; nocturnal species
remain nocturnal and predators still require represented fruit or actual prey.
Qualitative herb seeding seasons are not an implemented food budget: only
oak/hazel nuts are recognized as seeds, matching succession's granivore debit.
Founder admission does not call can_breed, require a completed reproductive profile,
or fabricate an age/maturity threshold for unknown biology.
Unadopted, unmarked, supported worldgen understory is collision-passable without
pretending it was already adopted. At a recruitment candidate, at most nine
ground-level cells use guarded diversity.bootstrap (when available). The three
legacy meadow-grass/fern/wildflower sprites receive only succ_natural metadata
under the same loaded, natural-support and provenance checks. This closes the
gap between succession's 12-node adoption ring and the wildlife search ring.
No botanical birthday/profile, forage ration, inventory item or plant node is
created. Unknown placement metadata, named planter markers, claims, ambiguous
claims and external protection deny adoption. Botany's presence does not hide
legacy grass/fern browse. Every subsequent meal still requires the existing
finite succession transaction; merely discovering or adopting a plant grants no
nutrition. Existing saved animals activate before the first observer joins,
without bootstrap, safe/room rejection or a current-food requirement; unsafe
terrain freezes subsequent movement/transactions rather than destroying them.
Founders are initialized only as loaded habitat is explored near an observer; unexplored regions have not yet been instantiated. This unavoidable lazy initialization is not recurring immigration when walking around a seeded region. There is no startup world-wide spawn, force-loading or offline execution. Per-frame safety/velocity checks are bounded per loaded entity and do not count as AI decisions. Restoration may exceed 64 loaded objects; the shared AI action ceiling remains 24/second, but per-frame callbacks/list sorting are not a measured constant CPU bound for an arbitrarily large restored population.
Absent-animal diagnosis and focused regression
Before this correction, a single hardcoded candidate at player Y was tried for
one species every 30 seconds. All 23 species therefore took 690 seconds (11.5
minutes) to revisit. Slopes failed body support, and unadopted sprites both
blocked clearance and failed food recognition outside succession's adoption
ring. With botany loaded, legacy meadow grass/fern also lost the fallback browse
path. These were admission/resource blockers, not a missing adult-age privilege:
this runtime never gated immigration on known maturity or can_breed. The old
danger comparison used squared distance 16 (four nodes); it now uses 64 (eight).
The focused wildlife suite now has 57 named checks. It adds repeated physics steps across AI intervals, approach to reachable food, fine-grained collision sweep, solar activity and dormancy, danger/hunger while resting, winter browse-mode negotiation, and sourced hare/fox reproductive timing.
Movement and art
Every fixed ID uses hearth_fauna_<id>.b3d and hearth_fauna_<id>.png.
Five actual ObjectRef animation calls select idle 0-19, locomotion 20-39,
feed 40-59, flight/swim 60-79, rest 80-99, at 24 fps with 0.15-second blend.
The authored asset has 100 frames. Bounds were obtained from faunaBounds() in
the existing art generator (10 model units per node), including long fox tails,
squirrel tail height, bird wings and antlers. Eye heights have a 0.15 minimum.
Collision is based on those measured bind bounds; safety uses a yaw-independent
envelope and animation margin, checking bottom, middle and top, source,
destination and a swept path sampled at no more than 0.2 nodes (at most 20
intervals for a four-node segment). No set_pos teleport movement.
Velocity ramps at at most 2 nodes/second squared up to a 1.3 nodes/second ceiling; each command has a 2.5-second lease, exceeding the two-second AI interval. Safety stops may be abrupt. Land, low flight, submerged swimming and moist-land invertebrate corridors differ; amphibians/otters/mallards may inhabit either land or water but shore transitions are deliberately refused until swept bank-ramp traversal is implemented. Flight can move vertically within a three-node natural-ground corridor. Unloaded, claimed, ambiguous, protected, building, unsupported and wrong-medium samples stop movement. This is conservative local movement, not full navigation, arboreal climbing, digging, seasonal migration or fluid dynamics. Gravity is held at zero inside these validated corridors to avoid uncontrolled cliff falls. The earthworm surface speed is the reported 20 metres/hour, not a mammal sprint.
Species activity differs: local solar day/night schedules, twilight activity,
winddown/wakeup transitions, short rest windows for flexible activity profiles,
and winter dormancy for hedgehogs, frogs and newts. Danger is processed before
rest and loaded hunger continues during sleep; dormancy never removes an animal.
Resource search checks a fixed 5x5 horizontal area and follows a reachable food
candidate rather than requiring it beside the next AI tick. Winter browse accepts
only a non-toxic tagged tree/shrub and never implies human edibility. Wildlife
passes winter_browse to the shared forage hook, but the current succession
implementation does not accept that mode; winter twig/stem debiting is therefore
not active until a separately scoped succession change. Ordinary shared browse
continues to use its existing seven-day plant cooldown. Also represented are
danger flight and hedgehog stillness, alert pauses, nectar visits,
fruit feeding, nuts/caching, litter consumption and actual finite prey pursuit.
The source accounts describe many additional behaviors; descriptions are not
claims that burrows, dreys, antler shedding, caste systems or parenting are coded.
Art quality requires separate native-engine animation/visual acceptance.
Research register and implemented nutritional web
Fetched Wikipedia identity/diet accounts (first eight plus earthworm/deer), and Wildlife Trust/RSPB accounts for the remaining rows, on 2026-11-03. All Wikipedia URLs are explicit identity links; generic deer is Cervidae, not a silently chosen Latin binomial. Bank vole retains the lifecycle identity Myodes glareolus (synonym Clethrionomys glareolus on the retrieved Wikipedia page). Prose below is original summary; no source media or article text is bundled.
| ID | Identity / Wikipedia URL | Reviewed nutrition and represented behavior |
|---|---|---|
| hare | Lepus europaeus | Grass/herbs, surface forms, nocturnal escape; represented browse and fox prey. |
| deer | Cervidae, unidentified legacy deer | Family-level foliage browsing only; no species timing asserted. |
| fox | Vulpes vulpes | Hare/rabbit/vole/mouse/squirrel/worm/frog prey, seasonal berries; mostly nocturnal. |
| rabbit | Oryctolagus cuniculus | Grass/leaves; fox and stoat prey; no fictitious warren reproduction. |
| red_squirrel | Sciurus vulgaris | Seeds/nuts/fruit; diurnal, canopy-dependent establishment; separately funded oak/hazel cache. |
| bank_vole | Myodes glareolus | Leaves/seeds/fruit, needs cover; fox/stoat/weasel/owl prey. |
| wood_mouse | Apodemus sylvaticus | Seeds/fruit and nocturnal covered movement; fox/stoat/weasel/owl prey. |
| hedgehog | Erinaceus europaeus | Finite earthworm prey, nocturnal/winter rest; badger prey. |
| badger | Meles meles | Worms, rodents, hedgehogs, fruit; nocturnal. No adult rabbit edge: account emphasizes kittens. |
| roe_deer | Capreolus capreolus | Wildlife Trust: buds/leaves/herbs/grass; delayed implantation not fabricated. |
| stoat | Mustela erminea | Wildlife Trust: rabbit and small rodents; day/night hunting. |
| weasel | Mustela nivalis | Wildlife Trust: vole/mouse/small birds, low running. |
| otter | Lutra lutra | Wildlife Trust: salmonids/frogs/newts; aquatic pursuit. |
| robin | Erithacus rubecula | RSPB: earthworms, seeds, fruit; hopping/flight. |
| blackbird | Turdus merula | RSPB: earthworms and seasonal fruit; ground feeding. |
| blue_tit | Cyanistes caeruleus | RSPB: seeds/nuts/berries; caterpillars are described but absent from simulated food supply. |
| barn_owl | Tyto alba | RSPB: finite voles/mice, low hunting flight; no adult-rabbit edge. |
| mallard | Anas platyrhynchos | RSPB: seeds/berries/plants; water-associated. |
| common_frog | Rana temporaria | Wildlife Trust: invertebrates; only registered earthworms modeled; moist habitat/winter shelter. |
| smooth_newt | Lissotriton vulgaris | Wildlife Trust: land worms, nocturnal moist habitat; aquatic prey stages unimplemented. |
| brown_trout | Salmo trutta | Wildlife Trust: larvae/small fish/flying insects; no phantom biomass, saved trout are finite otter prey. |
| bumblebee | Bombus terrestris | Wildlife Trust: legitimate nectar/pollen at active flowers; shared pollination/nectar transaction, not seed dispersal. |
| earthworm | Lumbricus terrestris | Natural dead leaves/mineral soil; moist nocturnal surface motion, finite litter debit. Wild lifespan unknown; captive six-year record is not a death deadline. |
Lifecycle's separately attributed numerical references also include ADW rabbit, ADW squirrel, ADW wood mouse and Woodland Trust bank vole. Those evidence values retain field-level confidence; unsupported fields stay unknown.
Focused acceptance
Standalone catalogue and wildlife tests use injected clocks and strict expected named-test totals; no native engine, background game instance or offline event replay is involved. They cover catalogue identity/evidence/copies, real-day age, unknown breeding denial, seasons, JSON hostile payloads and roundtrip, all caps, startup restore before players, all modeled trophic classes, single-use prey, feeding cooldowns, protected source/destination stencils, shared floral/fruit budgets, finite litter/nut authority, velocity bounds/no teleport, runtime animation calls, cliff/water/unloaded refusal, and scheduler work caps.
The wildlife suite now defines 57 named checks, including the movement, activity, dormancy, browse-mode and sourced breeding regressions. These changes were not executed in this pass. No native engine, full-repository test run, real-world save or art files are changed. These tests validate mocked runtime contracts, not native mapblock persistence, rendered young animals, engine crash recovery or biological completeness; native integration remains the main agent's responsibility.