The Last Hearth
An original, standalone Luanti survival prototype: gather flint and sticks, make tools, build a supported shelter, fuel a hearth, cook forage and boil water. It does not depend on Minetest Game (MTG). This is an environment simulation prototype, not a full physics simulator or a launch-ready public service. Original game code and procedural assets are MIT-licensed; the separately distributed engine retains its own licenses.
Status and planning
M0 technical gates are complete. M1 implementation/preflight and M2 gameplay / verification are complete; their human acceptance gates remain open. M3 implementation and automated verification are complete; its two-player acceptance gate remains open. M4 ecology, preservation, pottery, metalworking and bounded offline process work has passed automated technical verification; its week-long group acceptance remains open. M5 is now beginning with an offline-tested private staging deployment contract, not a live deployment. See M0 evidence, M1 playtest gate, M2 evidence, M3 implementation and verification, and M4 verification.
The newer living-ecosystem and botanical field-journal/art integration is an additional implementation pass, pending main integrated validation and native visual review. Historical M4 results do not certify this new pass. No version or save-schema bump is part of the journal work.
Woodland traveler appearance
Use /character, or Character appearance in the inventory, to choose muted
woodland clothing, skin, face, hair and details with three equal-mechanics body
profiles. Four tabs and a rotatable 3D model preview keep changes in a private
draft: Save / Apply persists them; Cancel keeps the original. Joining
restores saved appearance without prompting. Corrupt appearance data is retained
with a safe-default warning, never a kick. Existing location forms retain priority.
See character creator and recovery contract.
Focused offline tests do not certify native visuals or client interaction.
Offline species reader
Use /inspect while pointing at a known plant/tree within six blocks, or
/inspect oak / /inspect Quercus robur for an exact catalogue ID or Latin name.
Field notes include Inspect target; /botany offers a Species article
selector for each ten-row page. Harvesting and building controls are unchanged.
The Article tab contains 78 cached plaintext Wikipedia introductions, labelled Wikipedia excerpt (offline), with copyable canonical/revision/history URLs, contributor attribution and CC BY-SA 4.0 licensing. The other two species have explicit original CC0 availability notes, not counterfeit articles. Current effects distinguishes simulated game policy from descriptive natural history. This is not a full wiki, embedded browser, or real-world identification/foraging guide. Nothing is fetched or automatically opened; inspection writes no world or player data. Text is escaped and bounded to 8,000 characters, 4,000 per page. See source coverage, licenses and reader contract. Focused isolated tests cover the reader; native visual/client integration remains pending. Full-engine tests were not run for this change.
The landscape/content expansion now wires ten communities, ten tree species, an 80-species botanical catalogue (eight categories of ten) and ordered geology into the seasonal ecosystem. The trees are oak, birch, pine, willow, alder, beech, aspen, rowan, hazel and spruce. All ten logs fuel hearths for 180 seconds and craft four matching planks; buildings/planks are not direct fuel. Copper charges/ingots/picks, copper smelting, coal fuel and a three-quartz alternate window recipe are integrated; native validation of the latest botanical pass remains pending. New launcher worlds use a broad-relief v7 preset with a ±4096 bound; existing saved mapgen/seed/bounds are not retuned. Old chunks are never regenerated; future unexplored chunks can change and leave seams. Focused registration/tooling tests do not certify new-seed safety or engine visuals.
Human acceptance remains open across M1–M4. The actual M1 course has not been evidenced as traversed/repeated by several testers, and there are no measured FPS, frame-time, multiplayer, latency or hardware-envelope results. M2 implementation is proceeding under the user's explicit direction; this does not waive those gates or claim the M2 unfamiliar-tester, M3 two-player cabin, or M4 week-long group gate has passed.
- Roadmap: M0–M6 and M1 acceptance
- Launch feature checklist: F01–F19
- M0 decisions, provisional budgets, risks and evidence
- Architecture and save/module contracts
The exact development contract is Luanti 5.18.0, game 0.5.0-m4, save schema 1. See release.json and package.json. Native-first: Windows is natively verified on the existing development host. Linux/macOS path selection has unit coverage only; native execution is unverified on both. No clean machine was tested. A browser client is not promised launch-ready. There is no committed public launch date.
Run and test locally
Requires Node.js 22+ (built-in modules only), a separately installed stock Luanti
5.18.0, and a trusted writable runtime directory. The launcher checks the
engine's reported version; it does not download the engine or authenticate it.
On non-Windows systems set HEARTH_ENGINE to the absolute executable path. On
Windows it defaults to the existing Luanti 5.18.0 win64 runtime's bin directory;
setting HEARTH_ENGINE explicitly also works there. A headless-only server binary
can run checks but cannot provide graphical play.
From this repository, using Node on PATH:
node scripts/run.mjs check
node scripts/run.mjs smoke
node scripts/run.mjs test
node scripts/run.mjs test:seeds
npm test
node scripts/run.mjs play
node scripts/run.mjs test:course
node scripts/run.mjs course
- check: disposable headless world, game startup and compilation of the Lua sources/specs. Compilation alone does not execute the unit assertions.
- smoke: real-engine registry/crafting/terrain/resource/enclosure checks and isolated execution of the discovered Lua unit specs. Mocked globals do not replace globals in the live game.
- test: check plus smoke; with
HEARTH_LUAset to an absolute Lua 5.1+/LuaJIT executable, also runs the standalone Lua harnesses. No separate Lua is otherwise required. Do not rely on historical test counts: record named suites/results. - test:seeds: fresh real-engine worlds for eight fixed map seeds; checks safe arrival surfaces and required starting resources without touching the play world.
- M3: structure removal is refused if it would strand connected construction.
/claim sharemanages household access and/claim showbriefly marks boundaries. See M3 rules and remaining gates. - npm test: Node tooling tests only, not the engine suite. The
test:enginepackage script runs the engine suite;test:recoveryis a separate, private offline recovery exercise described below. - play: persistent local singleplayer world. Uses normal engine controls.
The expanded v7 preset applies only at creation. Use a separate empty
HEARTH_HOMEto try it without migrating/deleting the current world. See new-world settings and existing-world transitions. - course: a fresh disposable summer course; it never opens or changes
worlds/last_hearth. Wait for arrival, then run
/courseto generate the route and receive a temporary kit. The course route covers half-steps, a one-wide doorway, water, two controlled falls, gathering, construction and an arena. Run/course reportfor checkpoint progress and server-step/Lua-callback samples—not client FPS./sparopts into a bounded moving sparring opponent;/practiceuses the stationary reference target. PvP remains disabled. - test:course: native headless enrollment/staging and no-consent preflight. It intentionally does not generate terrain, forge a player, or claim traversal.
Engine checks require zero exit status and a unique per-run success marker. Their outer deadline is 90 seconds; standalone Lua invocations are bounded to 30 seconds. Graphical play has an eight-hour safety bound. Quit normally to save; interrupts/deadlines kill the child and are not graceful-save guarantees. Session configuration and logs are temporary and removed at session cleanup; retain sanitized evidence separately when validating. See scripts/run.mjs.
Data locations and isolation
HEARTH_HOME overrides the runtime root and must be absolute. Without it:
| Platform | Default root (literal environment notation) |
|---|---|
| Windows | %LOCALAPPDATA%/last-hearth-runtime |
| Linux | $XDG_DATA_HOME/last-hearth-runtime, or $HOME/.local/share/last-hearth-runtime |
| macOS (runner unverified) | $HOME/Library/Application Support/last-hearth-runtime |
The old Windows runtime and world location remain unchanged. Within the root,
the persistent world is under worlds/last_hearth and retained snapshots are under
backups. Each invocation packages a generated game into a temporary session's
games directory and sets LUANTI_GAME_PATH; it does not overwrite the engine
installation or its games. See scripts/launcher.mjs.
Use a different absolute HEARTH_HOME for staging, with an explicit
HEARTH_ENGINE when the engine lives outside it. Changing the root does not copy
or migrate the old world. Production must use a separate external deployment,
storage and configuration, outside this checkout, packages and webroots. The
local launcher is not a dedicated-server deployment tool. It binds loopback,
disables announcements, PvP and creative mode, and keeps mod security enabled.
Package, back up and restore
Examples below use absolute Windows destinations; substitute your own trusted paths (POSIX absolute paths on Linux/macOS). Parents must already exist and each destination must be new. No command overwrites an existing destination.
node scripts/run.mjs package C:/HearthArtifacts/game-0.1.0-m0
node scripts/run.mjs verify C:/HearthArtifacts/game-0.1.0-m0
node scripts/run.mjs backup C:/HearthPrivate/worlds/last_hearth C:/HearthPrivate/backups/manual-001 --offline
node scripts/run.mjs restore C:/HearthPrivate/backups/manual-001 C:/HearthPrivate/worlds/restored-001 --offline
Without a destination, package uses the dist/last_hearth directory, still
requiring it not to exist. Packaging generates assets and includes release,
configuration, license, mod and JSON fixture inputs plus an exact SHA-256
inventory. It is an engine-independent game directory, not an engine/client
bundle or installer; it excludes saves, tooling and the full test suite.
verify verifies a game package, not a world backup. Restore verifies a
backup before and after copying; scripts/backup.mjs also
exports verifyBackup() for programmatic verification.
Before backup, restore, recovery, or launching an existing managed world, stop
ALL engines that could access it, including external engines on other machines.
--offline is the operator's confirmation, not a mechanism that stops them.
Launcher/world locks and SQLite sidecar checks cannot prove remote idleness.
Do not delete locks/sidecars merely to bypass a refusal. Clear a stale launcher
lock only after confirming every relevant process has stopped.
The launcher takes a full retained prelaunch snapshot of an existing managed world; it has no automatic retention deletion. Backups include private map, player, authentication, inventory and mod data: use access-controlled, preferably encrypted storage, never a public artifact directory. Permissions remain the operator's responsibility; portable file modes do not provision Windows ACLs. SHA-256 detects corruption, not authenticity; it is not signing or encryption. Preserve the original snapshot and restore to a new directory before considering any operator-controlled cutover. See scripts/package.mjs, scripts/files.mjs and scripts/backup.mjs.
Private old-save recovery evidence
The test:recovery package script runs scripts/recovery.mjs.
Stop all engines and other Hearth tooling first. HEARTH_RECOVERY_SOURCE selects
an absolute existing SQLite world; otherwise it selects the legacy Windows world
under LOCALAPPDATA. HEARTH_HOME changes recovery's working/backup root, not
that default source. Non-Windows operators normally need an explicit source.
Recovery retains an untouched snapshot, verifies byte-exact restores, boots only instrumented disposable copies twice, and checks migration/restart behavior. Temporary copies omit old worldmods and use synthetic staging coordinates. A sanitized report is retained beside, not inside, the immutable snapshot. The original world is never launched. The retained successful report records 79 seed and 81 restart assertions, two byte-exact restores, two engine shutdowns and an unchanged source. It tested an earlier package, not the final export; its source had zero claims, so claim-owner/protection coverage uses regression fixtures and mocks, not preservation of existing source claims. This is not a real-client recovery playtest or public-service disaster recovery certification. See the recovery evidence and qualifications.
First play and current rules
- I opens crafting and field notes;
/guidereopens help. - Ecosystem survey in the field journal, or
/ecosystem, observes one small loaded habitat patch and reports global active hare/deer/fox totals. It does not grow plants, spawn animals, force-load terrain or change world state. - Botanical guide in the journal/survey, or
/botany [search], browses the actual catalogue, ten species per page. Search is literal, escaped and limited to 48 characters; it includes common/scientific names, category, habitat, seasons and ecological roles. Toxicity flags are game labels, not real-world food-safety advice; unflagged does not mean edible. Missing catalogue APIs display an unavailable message. See the category list and role limits. - Gather flint, sticks, berries and reeds. Make an axe to harvest timber; build supported walls/roof and fuel a stone hearth with sticks/logs.
- Fallen logs are ordinary sideways full cubes. An axe yields one canonical log, not two sticks gathered by hand. Existing full-block trees/deadwood are retained; this journal/process pass does not replace their geometry.
- Use a cup on water, then use untreated water on a fueled hearth before drinking.
- Aux1 (normally E) plus forward sprints; release after exhaustion and recover
stamina before sprinting again. FOV is unchanged by default;
/comfort fov 75applies a session-only static preference. /practiceplaces a stationary target. In local play or privileged staging,/sparopts into one moving opponent. Strike to begin a round; step back/aside to evade or face the attacker and hold right-click with a spear to brace.- The controlled route exists only in the disposable launcher-created course
world.
/course retryrestarts its run. A settings flag alone cannot authorize course generation in a survival/production world. /claimprotects one 25 × 25 area, extending ±24 vertically./claim sharegrants resident (build/use) or storekeeper (storage-only) rights;/claim unshare,/claim list,/claim show, and/claim removemanage membership and bounds.
Death preserves inventory, food, water and wetness; respawn only limits stamina and warmth before safe home/fallback arrival. A home must be inside the player's own claim and is revalidated at use. Offline player needs pause; hearth fuel and queued cooking/boiling use real-time deadlines, while completed output waits for collection. Food cooks in six seconds, water boils in four, and fuel cost is reserved when a job starts. A craftable bedroll grants a small warmth recovery after five uninterrupted sheltered seconds; it does not skip world time. M4 adds seasonal crops and preservation; general food spoilage remains disabled. PvP is disabled. See the M2 rules and limits and M4 offline contract.
A living landscape, a botanical field journal
The living ecosystem model is an original implementation inspired by Dynamic Life's ecological ideas, not copied datapack code or assets. Light, shade, moisture and competition shape meadow grass, wildflowers, ferns and slow tree succession. Litter, fungi and dung recycle finite nutrients; grazing opens gaps and wildlife links habitat to the food web. Wild succession is bounded, loaded-only, pauses across unloading/restart and never replays an offline backlog. Claims, placed plants, crops and construction are excluded from autonomous changes; existing crop and planted-sapling clocks keep their separate rules. Survey counts cover a fixed 5×5×5 patch at your feet, not the whole landscape; unloaded cells are explicitly unknown. Wildlife totals describe all currently active animals, not a local census or saved population. There is no compulsory ecological quest.
The moonlit botanical art direction pairs original pixel
materials with the eom.dev Mocha interface: base #1e1e2e, mantle #181825, raised
#292940, border #3c3d56, pale #cdd6f4 text and #a6adc8 annotations. Mauve
#cba6f7, teal #94e2d5 and yellow #f9e2af are restrained navigation, botanical
and warmth accents. The eight-page guide, botanical browser, recipes, satchel/crafting and location
forms share controls, dark fields, list colors, tooltips and pressed-sprig dividers.
HUD needs use labeled percentages and colored tracks on a dark panel rather than
ASCII bars. The ten-slot hotbar repeats the authored single-slot texture and uses
the authored selection outline; standard crosshair asset integration belongs to
the generated-art pass. Client scaling, contrast, long text and artwork still need
native visual acceptance; automated checks are not a claim of polished gameplay.
Location and privacy
Optionally set both HEARTH_LATITUDE and HEARTH_LONGITUDE (−90…90 and
−180…180). Local worlds can instead use the prompt or /location; an unchosen
local world shows a disclosed neutral equatorial preview. There is no IP lookup
or external location service. Configured/stored coordinates are private data.
Dedicated servers require explicit administrator-selected hearth_latitude and
hearth_longitude, even with a stored location. The community location is not
chosen: the user/operator must approve it before M2 climate staging. The M0
45°N, 0°E synthetic fixture is not a production location. The host UTC clock
drives a synthetic seasonal model and an approximate fixed-orbit sky, not live
weather. Labels are UTC and local solar time, not civil timezone/DST.
HEARTH_FIXTURE selects first-session, summer, or winter for isolated local
or staging work. First-session fixes seed 731104, not the date/location; summer
and winter fix UTC/weather/45°N, 0°E. Use a separate staging root/world; never
apply fixtures to valued play data. Production rejects preview/test settings.
See tests/fixtures/scenarios.json and
settingtypes.txt.
Known limits, not fixes
M1 code now implements smoothed stamina/sprint transitions, collision/course test geometry, animated held tools, material feedback and moving sparring. Manual feel/collision evaluation, voluntary repeat testing and performance/network measurements remain open; see M1 verification. This is not a custom engine/client controller; the newer bounded wildlife work is documented separately above. Stock Luanti remains the M1 baseline unless human measurements reveal a specific blocking engine limitation. M2 replaced the old below-world teleport with safe bounded recovery. M3 now provides bounded room/vent-aware comfort, a small building palette, refuse-unsafe-removal, shared resident/storekeeper roles and protected storage. This is not a full structural physics engine or persistent smoke simulation; two-player grief/comfort acceptance is still open. Generated art remains procedural prototype art. Public operations, moderation, identity and disaster-recovery acceptance remain later gates; no account, browser parity or multiplayer-hardening approval is implied.