Skip to content

v3.3.0 — load order follows the engine

Choose a tag to compare

@WingedGuardian WingedGuardian released this 29 Sep 02:05
· 1204 commits to master since this release

Load order now follows the engine — and that can change which mod wins a collision. Every tool that decides a winner (x4compat, x4effective, the effective store, BaseX x4eff, Tier B) used the community rule "alphabetical, dependencies forced earlier". Measured against the engine's own debug.txt it was wrong: it inverted 685 of 5,134 engine-logged pairs. The rule it now implements inverts 0, and an in-game probe (throwaway mods launched to the main menu, three rounds) confirmed the parts the log could not show.

⚠ A zzz_ folder name does not make a mod load last

The engine walks extension folders in case-insensitive UPPERCASE order (_ sorts after letters) in repeated passes: a mod whose dependencies have not loaded yet waits for a later pass. So an overlay named zzz_… loads last only within its own pass — every mod that waits on a dependency loads after it. To make an overlay win against a mod, give it an optional="true" <dependency> on that mod: measured to order exactly like a required one, and to never block loading, even when the mod it names is uninstalled or disabled.

Also measured and now modelled: a missing REQUIRED dependency, a dependency cycle, or a required dependency on a disabled mod means the mod does not load (and every tool now says so, naming the reason); the profile entry decides whether a mod is enabled, the manifest is only the default; DLC load before mods; mods in the profile's extensions\ folder load after every game-root mod, and a dependency never resolves between the game root and the profile root. The Steam Workshop root is unmeasured and disclosed as such whenever it is in play.

The PowerShell tool is guarded — and a release review closed its gaps

Before this release the safety hooks had no matcher for PowerShell or NotebookEdit, so every guard could be bypassed by choosing PowerShell. PowerShell commands are now parsed with PowerShell's own parser and judged by the same rule set as Bash. The pre-release review then found real bypasses in that new front-end (a delete reached through a pipeline or a variable, pwsh -cwa / stdin hosts, cmd /R, ^-escaped verbs, cd /d, an unquoted path with spaces, .NET writers, scriptblocks) — all closed, test-first, and measured against 50,061 historical commands before shipping so they add no friction. Bare system python on toolkit code is now a deny with the uv run form to use instead. Hook timeouts went from 5 s to 30 s (a guard that times out does not block).

A zero from BaseX is certified only over what the query addressed

ask.py used to print "NEGATIVE CONFIRMED over 10970 of 10970 documents" for a query that filtered itself down to 9 of them. A query that can narrow the documents it addresses (by document identity, position, node order, or an unreadable route) still runs and reports its hits, but its zero is withheld (rc 4, naming why). An unreadable mod catalog no longer lets coverage read "complete".

Every tool says what it left out

A mod the engine will not load is excluded from the model and named, with the reason, by every tool that models the running game — previously 16 of 20 call sites dropped it silently. x4compat, x4stats and x4similar now scan every configured extensions root, not just the game root.

Also

  • Freshness: an artifact goes STALE for every change that moves its answer (mods moving between roots, the reference tree, the engine code); a machine with no X4 installed no longer crashes x4xref.
  • x4diff sees element text; x4modlist detects updates from the Nexus file date with a 3-day grace window and never lets a network outage overwrite what it knew; x4validate, x4effective, x4debug, x4save, x4live and ~30 gates got correctness fixes — a finding now always outranks a refusal.
  • Installing from a git checkout copies only tracked files (one checkout carried 2.3 GB of local BaseX databases).
  • A Windows TMP longer than 260 characters hung the hook test suite for hours; fixed and banned by a test.

How this release was checked

A full release review: 9 fresh reviewers read all 116 changed production files in full; every finding (1 critical, 9 important, and every minor and pre-existing item they raised) fixed test-first, then re-verified. Full suite 2,961 passed, 0 failed (3 skipped: symlink tests that need a privilege this machine lacks); a cold clone with no X4 installed 2,878 passed, 0 failed, every CLI refusing cleanly; the release zip is the tagged commit, member for member.

Known, and stated rather than hidden

  • The instrument_hygiene gate is red: it measures the maintainer's own command habits across session transcripts, not the toolkit.
  • mutation_probe rewrites source in place and is never part of a gate run; it was not re-run for this release.
  • Issue #3 (one unexplained, non-reproducing cross_tool failure) is still open.
  • Still unmeasured, and disclosed at run time where it applies: the Workshop root; case-sensitivity of dependency ids; where a game-root mod that waits a pass lands relative to profile-root mods; non-NTFS filesystems.

Full detail: CHANGELOG · defect register: BLIND-SPOTS F128–F145 · audit record: tools/x4validate/AUDIT-2026-09-24.md.