Table of Contents

Class QuitLogFlush

Namespace
Valheim.Testing.Adapter
Assembly
Valheim.Testing.Adapter.CompileCheck.dll

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).

public static class QuitLogFlush
Inheritance
object
QuitLogFlush

Properties

ArmedBy

The quit signal that armed the flush (seen by any load in this process), or null while the game is not quitting.

public static string? ArmedBy { get; }

Property Value

string

Enabled

Whether this load of the adapter has enabled the flush (and not disabled it).

public static bool Enabled { get; }

Property Value

bool

Methods

Disable()

Unsubscribes this load, for the adapter's OnDestroy before a script reload; the last enabled load also removes the listener. Does nothing once the game is quitting (ArmedBy set): plugins are destroyed at quit too, and the lines they log then are the ones this flush exists to save.

public static void Disable()

Enable()

Subscribes this load to the quit signals and makes sure the process has the one listener. Idempotent, also across script reloads and several adapters.

public static void Enable()

Flush()

Flushes every BepInEx disk log now.

public static void Flush()

Quitting(string)

Arms the flush (once; later calls flush again). Call it from the adapter's OnApplicationQuit, naming the caller. Not from OnDestroy: a script reload destroys the plugin without quitting.

public static void Quitting(string signal)

Parameters

signal string