modinfo.json identifies a package to Rain World’s mod manager. Put it at the package root. For a small code mod, this is enough metadata to give the Remix entry a stable ID and readable description:
{
"id": "example.weatherlamp",
"name": "Weather Lamp",
"version": "1.0.0",
"authors": "Example Author",
"description": "Adds a room weather indicator.",
"requirements": [],
"requirements_names": []
}The example declares no Remix dependency. Add a requirement only when the package needs another Rain World mod to work.
Fields read by this build
In Steam build 22785462, global::ModManager.LoadModFromJson(RainWorld,String,String) reads these keys:
| Key | Value read by the loader |
|---|---|
id, name, version | Text |
hide_version, checksum_override_version | Boolean |
target_game_version | Text |
authors, description, youtube_trailer_id | Text |
requirements, requirements_names, tags, priorities | Lists |
Omitted fields receive defaults. Include fields that identify and describe the package, plus dependency fields the package uses. The selected source shows target_game_version being stored, but does not show that value being compared during activation.
requirements contains Rain World mod IDs. During global::ModManager.RefreshModsLists(RainWorld), each string is checked against InstalledMods. Missing IDs are recorded in FailedRequirementIds. requirements_names supplies corresponding readable names. The bundled More Slugcats manifest demonstrates the shape with "requirements": ["rwremix"] and a matching name.
The manifest format shown here has no dependency version field. Do not encode versions into a requirement string or claim that requirements pins a version.
Mod ID and plugin GUID
Rain World and BepInEx read separate identifiers:
modinfo.jsonusesidfor package discovery, enabled mod selection, and Remix requirements.BepInPluginuses a plugin GUID for BepInEx discovery.BepInDependencynames another BepInEx plugin throughDependencyGUID.
For a package with one plugin, using the same text for the mod ID and plugin GUID makes logs, folders, and dependency declarations easier to compare. First plugin follows that convention. The inspected Rain World manifest parser does not compare id with a plugin GUID, so equality is not a general engine requirement.
When code needs another mod’s plugin, the two dependency layers may both matter. Put the provider’s Rain World mod ID in requirements, then use its BepInEx plugin GUID in BepInDependency. Confirm both identifiers from that provider’s maintained manifest and plugin source. BepInEx 5.4.17 treats the ordinary BepInDependency form as a hard plugin dependency. This does not make BepInEx, HOOKS-Assembly-CSharp.dll, or game assemblies valid entries in requirements.
Choose the package content path
Build 22785462 recognizes code under plugins or patchers at the package root, under newest, or under v1.11.8. A plain code package can use the layout documented in First plugin:
example.weatherlamp/
modinfo.json
plugins/
WeatherLamp.dllUse v1.11.8 for content intended for this game version. newest is the fallback consulted when targeted content is not selected. Keep complete path precedence in Asset resolution. A versioned folder records a packaging choice. It does not prove compatibility with later builds.
Before release, parse the JSON, compare every requirement ID with the provider’s manifest, and inspect the final folder. Ship your own DLLs, assets, metadata, and documentation. Check each owner’s license and distribution terms before including files from another project.
Sources
global::ModManager.LoadModFromJson(RainWorld,String,String),global::ModManager.RefreshModsLists(RainWorld), andglobal::ModManager.ModFolderHasDLLContent(String)in the baselineAssembly-CSharp.dll. See Runtime reference.- BepInEx 5.4.17 plugin and dependency attributes
- BepInEx 5.4.17 chainloader dependency handling