Test one claim at a time. A test that changes the room, save, enabled mods, and code build together can show a failure, but it cannot say which change caused it. Write the intended result before launching: “the plugin loads once”, “this action creates one effect”, or “the feature disables itself when its optional dependency is absent.”

Start with a disposable test setup. Back up any save data you plan to use through your own normal file-management method before a mod can write to it. This article does not name save locations because they vary by platform and installation. Keep the backup outside the active test copy and label it with the date, game build, and purpose. Do not edit a save file to simulate a game event unless the feature specifically requires save-format research.

Build the DLL before changing the test setup. Use the SDK-style command from Project file and copy only the intended DLL from the build output into the test package. Do not use the PowerShell helper as a required test step. Record the RainWorldPath source of the reference assemblies and the operating system used for compilation. A build on Linux or macOS checks the project and references. It does not test the Windows game process under Proton or Wine.

Use a small matrix

Begin with the smallest case that can exercise the feature. Add one dimension only after it passes. A useful early matrix looks like this:

RunVariables held constantVariable changedExpected evidence
1Recorded game build, one room, one input sequenceMod disabledNo plugin marker or feature behavior
2Same as run 1Mod enabledOne load marker and one intended behavior
3Same as run 2Restart or reload the relevant processNo duplicate subscription or repeated registration
4Same core scenarioOne likely compatibility mod enabledFeature result and first log exception, if any

For a feature that writes persistent state, add separate runs for a new save, an existing backed-up test save, a normal quit, and the event that should reload the state. Campaign save data explains the game-owned save scopes. Do not infer persistence from a value visible during the same room visit.

Capture enough evidence

For each run, record the mod DLL version or hash, Rain World build, enabled mod list, chosen character or mode where relevant, room, input sequence, operating system, compatibility layer when used, and observed result. Keep the BepInEx log from a failed run. Reading error logs explains how to isolate the first exception from BepInEx/LogOutput.log or the applicable Windows Player log.

Choose observable results. A one-time log marker can show hook registration. A controlled action can show that the handler reached its target. A save and reload can show persistence. A counter can show that an update handler ran a known number of times. Do not call a test passed because the game reached the menu if the feature runs only in a room.

Add compatibility cases deliberately

Test the base game path before adding other mods. Then select compatibility candidates that touch the same method, object type, assets, menus, or saved state. Add one candidate at a time. If the feature uses player state, include a local co-op case only after the single-player path works. Optional integrations covers module and provider boundaries, while Hook lifecycle covers repeatable registration.

When a failure appears, return to the last passing row and reproduce with the one changed variable. Preserve the failing log and test notes before trying a new build. This turns a vague report into a comparison another modder can repeat.

The test matrix is a procedure, not evidence that any particular mod has been run. The inspected code baseline is Rain World v1.11.8, Steam build 22785462. Runtime reference records its assembly identities.

Sources