510 lines
41 KiB
Markdown
Executable File
510 lines
41 KiB
Markdown
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](https://github.com/ElCeejo/animalia/blob/main/mobs/song_bird.lua),
|
|
[AI](https://github.com/ElCeejo/animalia/blob/main/api/mob_ai.lua), and
|
|
[Libri](https://github.com/ElCeejo/animalia/blob/main/api/libri.lua) 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](../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](https://animaldiversity.org/accounts/Myodes_glareolus/) gives 17-24 d, 20-25 d weaning, late April-September; [Woodland Trust](https://www.woodlandtrust.org.uk/trees-woods-and-wildlife/animals/mammals/bank-vole/) supplies conservative 6/8-week maturity; [Wildlife Trusts](https://www.wildlifetrusts.org/wildlife-explorer/mammals/bank-vole) 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](https://animaldiversity.org/accounts/Apodemus_sylvaticus/) gives maturity, gestation and 21 d weaning, but 4-7 young; retained 4-8 is from [Wildlife Trusts](https://www.wildlifetrusts.org/wildlife-explorer/mammals/wood-mouse). [Wikipedia](https://en.wikipedia.org/wiki/Wood_mouse) 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](https://animaldiversity.org/accounts/Turdus_merula/) gives first breeding at one year, 13-day prose/14-day summary and 13-14 d leaving nest. [RSPB](https://www.rspb.org.uk/birds-and-wildlife/blackbird) 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](https://animaldiversity.org/accounts/Anas_platyrhynchos/) gives these values; [Wikipedia](https://en.wikipedia.org/wiki/Mallard) 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](https://animaldiversity.org/accounts/Lepus_europaeus/) 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](https://animaldiversity.org/accounts/Vulpes_vulpes/) 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](https://www.bto.org/understanding-birds/articles/blue-tit-diary)
|
|
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](https://en.wikipedia.org/wiki/Common_frog) adds about 3-year maturity
|
|
and 14-21 d incubation, but aquatic eggs/tadpoles and their food remain absent.
|
|
[Brown trout](https://en.wikipedia.org/wiki/Brown_trout) needs female mass for its
|
|
approximately 2000 eggs/kg, a gravel redd and temperature-dependent development.
|
|
[Bumblebee](https://en.wikipedia.org/wiki/Bombus_terrestris) 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](https://en.wikipedia.org/wiki/Lepus_europaeus) | Grass/herbs, surface forms, nocturnal escape; represented browse and fox prey. |
|
|
| deer | [Cervidae, unidentified legacy deer](https://en.wikipedia.org/wiki/Deer) | Family-level foliage browsing only; no species timing asserted. |
|
|
| fox | [Vulpes vulpes](https://en.wikipedia.org/wiki/Vulpes_vulpes) | Hare/rabbit/vole/mouse/squirrel/worm/frog prey, seasonal berries; mostly nocturnal. |
|
|
| rabbit | [Oryctolagus cuniculus](https://en.wikipedia.org/wiki/Oryctolagus_cuniculus) | Grass/leaves; fox and stoat prey; no fictitious warren reproduction. |
|
|
| red_squirrel | [Sciurus vulgaris](https://en.wikipedia.org/wiki/Sciurus_vulgaris) | Seeds/nuts/fruit; diurnal, canopy-dependent establishment; separately funded oak/hazel cache. |
|
|
| bank_vole | [Myodes glareolus](https://en.wikipedia.org/wiki/Myodes_glareolus) | Leaves/seeds/fruit, needs cover; fox/stoat/weasel/owl prey. |
|
|
| wood_mouse | [Apodemus sylvaticus](https://en.wikipedia.org/wiki/Apodemus_sylvaticus) | Seeds/fruit and nocturnal covered movement; fox/stoat/weasel/owl prey. |
|
|
| hedgehog | [Erinaceus europaeus](https://en.wikipedia.org/wiki/Erinaceus_europaeus) | Finite earthworm prey, nocturnal/winter rest; badger prey. |
|
|
| badger | [Meles meles](https://en.wikipedia.org/wiki/Meles_meles) | Worms, rodents, hedgehogs, fruit; nocturnal. No adult rabbit edge: account emphasizes kittens. |
|
|
| roe_deer | [Capreolus capreolus](https://en.wikipedia.org/wiki/Capreolus_capreolus) | [Wildlife Trust](https://www.wildlifetrusts.org/wildlife-explorer/mammals/roe-deer): buds/leaves/herbs/grass; delayed implantation not fabricated. |
|
|
| stoat | [Mustela erminea](https://en.wikipedia.org/wiki/Mustela_erminea) | [Wildlife Trust](https://www.wildlifetrusts.org/wildlife-explorer/mammals/stoat): rabbit and small rodents; day/night hunting. |
|
|
| weasel | [Mustela nivalis](https://en.wikipedia.org/wiki/Mustela_nivalis) | [Wildlife Trust](https://www.wildlifetrusts.org/wildlife-explorer/mammals/weasel): vole/mouse/small birds, low running. |
|
|
| otter | [Lutra lutra](https://en.wikipedia.org/wiki/Lutra_lutra) | [Wildlife Trust](https://www.wildlifetrusts.org/wildlife-explorer/mammals/european-otter): salmonids/frogs/newts; aquatic pursuit. |
|
|
| robin | [Erithacus rubecula](https://en.wikipedia.org/wiki/Erithacus_rubecula) | [RSPB](https://www.rspb.org.uk/birds-and-wildlife/robin): earthworms, seeds, fruit; hopping/flight. |
|
|
| blackbird | [Turdus merula](https://en.wikipedia.org/wiki/Turdus_merula) | [RSPB](https://www.rspb.org.uk/birds-and-wildlife/blackbird): earthworms and seasonal fruit; ground feeding. |
|
|
| blue_tit | [Cyanistes caeruleus](https://en.wikipedia.org/wiki/Cyanistes_caeruleus) | [RSPB](https://www.rspb.org.uk/birds-and-wildlife/blue-tit): seeds/nuts/berries; caterpillars are described but absent from simulated food supply. |
|
|
| barn_owl | [Tyto alba](https://en.wikipedia.org/wiki/Tyto_alba) | [RSPB](https://www.rspb.org.uk/birds-and-wildlife/barn-owl): finite voles/mice, low hunting flight; no adult-rabbit edge. |
|
|
| mallard | [Anas platyrhynchos](https://en.wikipedia.org/wiki/Anas_platyrhynchos) | [RSPB](https://www.rspb.org.uk/birds-and-wildlife/mallard): seeds/berries/plants; water-associated. |
|
|
| common_frog | [Rana temporaria](https://en.wikipedia.org/wiki/Rana_temporaria) | [Wildlife Trust](https://www.wildlifetrusts.org/wildlife-explorer/amphibians/common-frog): invertebrates; only registered earthworms modeled; moist habitat/winter shelter. |
|
|
| smooth_newt | [Lissotriton vulgaris](https://en.wikipedia.org/wiki/Lissotriton_vulgaris) | [Wildlife Trust](https://www.wildlifetrusts.org/wildlife-explorer/amphibians/smooth-newt): land worms, nocturnal moist habitat; aquatic prey stages unimplemented. |
|
|
| brown_trout | [Salmo trutta](https://en.wikipedia.org/wiki/Salmo_trutta) | [Wildlife Trust](https://www.wildlifetrusts.org/wildlife-explorer/freshwater-fish/brown-trout): larvae/small fish/flying insects; no phantom biomass, saved trout are finite otter prey. |
|
|
| bumblebee | [Bombus terrestris](https://en.wikipedia.org/wiki/Bombus_terrestris) | [Wildlife Trust](https://www.wildlifetrusts.org/wildlife-explorer/invertebrates/bees-and-wasps/buff-tailed-bumblebee): legitimate nectar/pollen at active flowers; shared pollination/nectar transaction, not seed dispersal. |
|
|
| earthworm | [Lumbricus terrestris](https://en.wikipedia.org/wiki/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](https://animaldiversity.org/accounts/Oryctolagus_cuniculus/),
|
|
[ADW squirrel](https://animaldiversity.org/accounts/Sciurus_vulgaris/),
|
|
[ADW wood mouse](https://animaldiversity.org/accounts/Apodemus_sylvaticus/) and
|
|
[Woodland Trust bank vole](https://www.woodlandtrust.org.uk/trees-woods-and-wildlife/animals/mammals/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.
|