Repository navigation
Kiln 0.2.0-dev.21
Pre-release
Pre-release
Kiln 0.2.0-dev.21
This build fixes the problems found in the dev.20 review, stops the launcher from removing mods while Enshrouded runs, makes EML mods start much faster, moves the hooks Kiln places on the game into one registry, and helps closed-source DLL mods (XHL, trainers) work next to Kiln.
Players and server owners
- The launcher no longer removes a Library version while Enshrouded runs. Remove and Clean up say "Close Enshrouded first: the game may be reading this mod". Clean up never lists a version the game's active profile uses. This is Kiln's side of GitHub issue #4 (PR #5, "Refs #4"): it closes a way to lose a mod folder mid-start, but the reporter's root cause is not proven.
- EML mods: a mod whose
src/mod.luacannot be read is switched off before the long game-data step, with the reason instate/eml.jsonand kiln.log. The other mods still run, and a file that vanishes during the run drops only its own mod. - EML starts read far less game data: each file at most once per start, and not at all while the OS shows it unchanged (bisdat/kiln-mods#17 found the cost; this follows their analysis). On a lab server under Wine with 7.5 GiB of real server data, a start that changed nothing went from 7.6 GiB read in 5.4 s to 562 B in 64 ms, and a start after a mod change from 30.2 GiB in 13.4 s to 141.5 MiB in 1.0 s. On synthetic 55 GiB data a cache hit went from 55 GiB read to 0 B. Not measured on a real client.
- The first start after this update still reads all game files once (about 48 GiB on a full client install, as in dev.20), because the old cache has no change stamps; later starts do not.
KILN_EML_FULL_HASH=1turns the reuse off. - Closed-source DLL mods (XHL-Core, Auto Loot Plus, trainers) can clash with Kiln over the same game function. The profile's native page now has a "Load after Kiln and ShroudForge" switch per chain entry, shows last session's hook overlaps with a one-click "Load late", and lists the compat rules that apply.
- Chat: Kiln's chat commands no longer depend on the game's return address, so kiln-emf's chat hook or an EMF mod's hook in front of Kiln's can't hide players' lines from them (a dev.20 bug). Tested with stand-in hooks under Wine; the real-client check is open.
- ShroudForge and SET placement and modpack installs no longer refuse a folder just because
/homeis a link to/var/home(Fedora Atomic, Bazzite). Links inside the managed folders are still refused. Tested with symlinks on Linux, not on a Fedora Atomic host. - Leftovers from dev.19 are cleaned up. A launcher build with Nexus off gives
nxm://links back to the handler you had before (Vortex, for example); a stray link is forwarded to it, or you get a message on how to reset the handler. A personal Nexus API key stored by dev.19 is removed, in every build, without being shown. - Smoother play: mod status lines never make the menu, tick or frame wait. EMF portraits are drawn off the boot thread, and current pictures skip the renderer. SET no longer re-reads a catalog without texts every 60 s, and handles non-ASCII Windows paths.
- File names that Windows would change (trailing dots or spaces) are refused in mod zips, runtime bundles and modpacks.
Mod authors
- kiln.hooks v2. One registry owns one detour per game function. Every handler is a link in an ordered chain. Order:
before/afterconstraints, then priority (higher first), then registration order. New C calls:raw_detour(any signature, floats too),detour2(up to 12 integer arguments),mid2,caller(),call_original2,map_json. Seedocs/kiln/services/hooks.md. - C++ header
native/core/abi/kiln_hook.hpp:kiln::RawHookandkiln::MidHook2. Useg.install(...)on a global. Readg.caller()before calling the original, instead of_ReturnAddress(). - Every Kiln service and the core tick now hook through the registry. Only system DLL exports (
LoadLibraryExW, Vulkan, XInput) and mod hooks outside the game exe still use plain safetyhook. kiln/state/hooks.jsonlists every hooked function, its links in order, and other modules' hooks found before or over Kiln. kiln.log sayshooks: <label> chained over <module>+0x...andhooks: <module> hooked over Kiln's <label>.- EMF mods'
hook,hook_patternandhook_address, and Shroudtopia'sCreateDetour, are links owned byemf:<id>andshroudtopia:<mod>. They run newest first, before Kiln's own links. - ShroudForge's six engine hooks go through kiln.hooks when Kiln hosts it, so another DLL's jump on one of them no longer switches its native runtime off. Dormant on the current game build (see Known limits); tested with a stand-in and a synthetic legacy profile.
KILN_SF_ENGINE_HOOKS=selfkeeps the old behaviour. chain.inigains[late]: entries named there are loaded by kiln-core after Kiln's services, plugins and ShroudForge.state/native.jsonreports them underchain.late.compat-rules.json(Kiln's, then yours in<configDir>) canwarn, load a chain DLLlate, ordisablea chain DLL or a profile-listed mod. The launcher applieslateanddisableof chain entries when it writes chain.ini; kiln-core logswarnrules, skips a disabled profile-listed mod and reports anything else as not applied. Schemas:schema/compat-rules.schema.json,schema/hooks-state.schema.json.- Managed hooks cost less (lab, Wine,
GetComponent): about 6 ns per call through an empty chain and 59 ns through a managed handler. dev.20 measured about 65 ns and 100 ns. - Item transfer handlers see
KILN_TRANSFER_DRY_RUNon a mod's dry-run move. Roll nothing forward there: don't count, log or change anything outside the transfer. component_changechecks an add's payload against the component's size from kiln.types and refuses a mismatch.Overridesfrom a background thread belong to the mod that got the handle. Without one they throwInvalidOperationException.Texts.Getreturnsnullwhile another thread is loading the catalog (Texts.Preload, or a first call), instead of waiting.Assets.Reflectreturnsnullon builds without kiln.types.- World program
TryRead/TryWriteno longer allocate or lock per entity. Without kiln.types they log once per program. - KILN111: items registered with
ItemDefinitioncount. A game-style name missing from your local catalog is now info, not a warning. - Launcher commands:
chain_view,chain_set_late,library_unused,library_users,library_remove_many.library_removetakesshown(the users its dialog named) and refuses when anything else uses the version. - Mid hooks keep safetyhook's stack rules:
trampoline_rspstarts atrsp - 8, and a handler at a function entry returns early by settingtrampoline_rsp = rsp. - Installing the same raw handler on a function again replaces the earlier link in one step. An install that matches a revoked link (same function, handler, owner and label) takes that link's slot again.
hooks.jsonlinkSlotsandKilnHooksStats.links_used/links_cap/targets_capshow the use; kiln.log warns at 75% and when full. KilnHookOrder.flagswithKILN_HOOK_NEWEST_FIRST: at one priority, flagged links run newest first. EMF and Shroudtopia detours use it, so the newest mod detour runs first across both engines.- A DLL loaded late (or a native mod) may patch the game's entry point: the proxy puts the entry's own bytes back before the core starts, and the patch runs before the game's own entry.
[late]limits: EMF's own loader is never deferred; a DLL another loader already started is reported asalready-loaded; a late DLL of a disabled or policy-refused native mod is skipped; an early or boot native mod cannot require a late one. Seedocs/kiln/engines.md.- Play-once:
chain/once.inicarries the play-once profile's[chain]and[late], so that start follows its own compat rules. - EMF
image_load("portrait:<key>")from a tick or render thread returns a handle at once while the picture is still being drawn. It shows nothing until the drawing finishes, then the picture.
Breaking and behaviour changes
- A v1
detour(and managedHooks.Detour) now passes every argument to the original, not only the first four. - Hook order between Kiln's own services follows the registry (priority, then registration). The core tick links stay innermost.
- EMF and Shroudtopia mod hooks now run before Kiln's own links on the same function.
- Library removal is refused while the game runs, even with force. A running server blocks it only when its profile points into the Library.
- Item transfer handlers are now also called on dry-run moves (not on silent ones), with the dry-run flag set.
- Managed: background-thread override claims without a mod throw.
Texts.Getcan returnnullwhile another thread loads the catalog. Status lines show the last snapshot and refresh a moment later. - npcai faction hooks and creatures rules keep their links after 64 on/off rounds, answering nothing.
- kiln-eml's
files.jsongains change stamps. Older Kiln reads it fine. Use kiln-emf and kiln-eml from the same release: portrait cache codes 5 (busy), 6 (full) and 7 (cache I/O error, tried again next start) are new. - A hook function installed twice on the same game function is one link now: the second install replaces the first.
- A compat
disablerule on a native mod whose DLL the proxy already loaded is reported as not applied (it used to say applied). Re-activate the profile in the launcher to apply it. - An older proxy ignores
[late]and loads those DLLs early. - Every launcher build deletes the personal Nexus API key dev.19 stored, on start. A build with Nexus off also gives back the
nxm://registration dev.19 made.
Client checklist
Only a real client or a joined player can confirm these.
- Hooks on the client: Kiln's menu opens and draws, the camera and render hooks work, the in-game UI hooks behave as in dev.20 (ui, render, game; input and Vulkan stay on safetyhook).
- Chat: with kiln-emf's client chat bridge on, Kiln chat commands and EMF mods' chat both work, in both directions.
- Services a-m with a player: item moves and quick stack, combat (fall damage, regen), abilities, audio on the client (voice-over, narration, mod sounds).
- Services n-z with a player: players and quests, flight and creative rules, saves, settings, skills, time, spawns, NPC factions (npcai), VFX, world programs. Their server side ran in labs; the client side did not.
- XHL or another DLL that hooks first: ShroudForge still starts. The host path itself cannot be exercised on the current game build (no shipped profile names engine hooks); this only confirms nothing regressed.
- Closed DLL mods: switch "Load after Kiln and ShroudForge" on for XHL-Core. Next start, XHL works, kiln.log shows it loaded late, and the overlaps panel updates. Also click through the profile's native page (chain card, late switch, overlaps, rules) by hand; see Known limits.
- Library guard: while Enshrouded starts with an EML mod active, Remove or Clean up of that version is refused. After the game closes, removal works. Clean up never lists a version the active profile points at.
- On a
/home -> /var/homehost, the profile's EML mod loads. - EML start cost on the real install: the first start reads about 48 GiB once. After that kiln.log shows
hashedin KiB andnothing changedwithin a second or two. If it saysChange stamps are not trusted here, note the reason. - EMF portraits: the game enters the world without waiting when every picture is current, and pictures still show. On the first start after a portrait change, a window opened early shows empty slots that fill in when the drawing finishes.
- The game starts with the new proxy on the real client (the gate now restores the entry point before Kiln boots; labs covered the dedicated server only).
- Library: the Remove dialog names what uses the version, its Remove button waits for that list, and removing works.
- Play-once with a profile whose compat rules differ from the active profile's: that start follows the play-once profile's rules, and the next normal start is back to the active profile's.
- Mods tab status lines refresh without stalls.
- Windows, launcher build with Nexus off: a PC that had dev.19's Nexus links on over Vortex gets them back (the registry key points at Vortex again). A junction inside the game folder is still refused; one above it works.
Known limits
- Reordering links that are already installed is not atomic for calls in flight. A call at that moment can skip a link or run one twice. It is built not to crash, and Wine stress tests cover it, but no real game session has.
- Hook links are never freed; a process has 65,536 slots. Native handlers installed again reuse their slot. Managed
Hooks.DetourandHooks.Midtake a new slot on every install, so a mod that installs and disposes one per command still uses them up. - A
MidHook2installed again while live can run its handler twice for one call at that moment. - Many new paths were verified only under Wine: unit tests, Wine host tests and dedicated-server labs. Not on Windows, and not in the real client.
- ShroudForge's host hooks are dormant on the current build: no shipped game profile names engine hooks.
- A stray
nxm://link that a build with Nexus off cannot hand on opens a launcher window with a message. If a launcher already runs, that is a second window. - The new launcher pages and messages (chain card, Library guard) are covered by Rust tests, type checks and mock data, not by a hand-run against a real install.
- exFAT and FAT game folders refuse CRC reuse, so EML reads every file in full there, as before.
- After a power loss or a hard crash of the machine, a game file can come back changed with its old size and times, and EML would reuse its old CRC. Start once with
KILN_EML_FULL_HASH=1after such a crash. - A compat rule's
disablecannot stop a native mod whose DLLs the proxy already loaded (dllmainphase, not in[late]). The rule is reported as not applied; only the launcher's chain.ini keeps such a DLL out.