Table of Contents

Namespace Valheim.Testing.Adapter

Classes

FixtureGate

The opt-in gate for commands that build fixtures in the world (spawn terrain, write saved objects): they run only in a process whose runner turned them on. A test adapter can be installed in a runtime that somebody else uses; its read-only observations are harmless there, but a fixture command must refuse unless the owned test session asked for it. Check at the start of the command:

if (FixtureGate.Refusal("MYMOD_TEST_FIXTURES", "MYMOD_TEST_SESSION_TOKEN") is string refused)
{ context.Fail("fixture_disabled", refused); yield break; }
GlobalKeyCommands

A fixture command that sets or removes a global key on the server. ValheimCLI's default ValheimCLI plugin owns the read-only key list. In Valheim 1.0.16 a change goes to the server, which applies it and sends its whole list to every client; each client replaces its own list with it. Keys are stored lower case, as name or name value. The runner's GlobalKeyFixture in Valheim.Testing.Game issues a change once and waits until a joined client lists the server's set. The game's own setkey console command is not used: in 1.0.16 it refuses a key that is not a world-modifier setting (a boss key, for example) unless the game already counts as cheated, and that check reads the world modifiers menu. A world-modifier key (one the world-modifiers menu sets, such as nomap) set or removed here is also written into, or removed from, the world's saved settings (its starting global keys), as the game does for any change of such a key; other keys (boss keys, for example) are saved only in the world's own key list. Written against the Valheim 1.0.16 decompile and run on a 1.0.16 server and client.

Members

Exact reflected access to game members that the shipped game keeps private, even where publicized build references show them as public. Every lookup names one member (a method by its exact parameter types) and throws when it is missing or has another type, so a game update fails the test loudly instead of reading a default.

QuitLogFlush

Makes the lines plugins log while the game quits reach BepInEx's disk log (LogOutput.log), so the runner's teardown log scan can read them. BepInEx 5.4's DiskLogListener writes through a buffered writer that a 2-second timer flushes, and nothing flushes it when the game quits: on the Valheim 1.0.16 Windows dedicated server a boot that quit cleanly sometimes kept its plugins' last lines and sometimes lost them.

Enable() adds one log listener after BepInEx's own, and does nothing else until the game starts quitting. The first quit signal arms it: Application.quitting, the adapter's own OnApplicationQuit (call Quitting(string) there), or AppDomain.ProcessExit/DomainUnload. Arming flushes every disk log once, which saves the lines logged so far; from then on the listener flushes after each line any plugin logs, which saves the rest. A line is lost only if the process stops running managed code before any of those signals, or if it is logged after the last managed code runs. Arming logs one info line naming the signal that armed it.

Enable it in the test adapter's Awake and call Disable() from its OnDestroy; production mods never need it. It changes no BepInEx configuration, removes no listener but its own, changes no log level and never touches Harmony. Before the game quits, logging is buffered exactly as without it.

The state is process-wide, not per load: a ScriptEngine reload loads the adapter again with fresh statics, and two mods' adapters each compile this source, while BepInEx's listener list lives on. So the process keeps one listener whichever load added it, a quit signal seen by any load arms the flush for all, and the listener is removed only when the last enabled load calls Disable() (a load reloaded without it counts as still enabled, so the flush stays: the safe direction).

SavedObjects

A capped census of a zone's saved objects (ZDOs), loaded or not. Throws instead of returning a truncated list or the objects of another zone. Run in game by the native acceptance suite's marker observation.

TestExtension

Registers a mod's test extension with ValheimCLI once ValheimCLI's extension API is ready, together with the session capability that OwnedServerSession uses to prove it started this very server: the token from the runner's environment variable, this process's ID, the save root, whether it is dedicated, the raw devcommands flag, whether it accepts game connections yet, and whether the world and the mod are ready. Run it as a coroutine from the adapter plugin's Start:

private IEnumerator Start() => TestExtension.Register("mymod.testing", "0.1.0", "MYMOD_TEST_SESSION_TOKEN",
    () => MyMod.Ready, registration => _registration = registration, Logger.LogError, extraCommands);

and dispose the registration in OnDestroy.