global::ProcessManager owns Rain World’s current primary activity in currentMainLoop. Gameplay is a global::RainWorldGame. Title screens and other menus are other global::MainLoopProcess instances. Obtain an existing process from the manager instead of constructing a game or menu from a plugin.

flowchart TD
    A[ProcessManager] --> B[currentMainLoop]
    B --> C[RainWorldGame]
    C --> D[GameSession]
    D --> E[StoryGameSession]
    D --> F[ArenaGameSession]

The manager also owns upcomingProcess and a collection of side processes. ProcessManager.Update(float) sends RawUpdate(deltaTime) to the current primary process and each side process. This ownership determines when references are valid. A field on a BaseUnityPlugin can outlive several game and menu processes.

Read the active game

Check both the process and session type at the point of use:

RainWorldGame game = manager.currentMainLoop as RainWorldGame;
if (game == null)
    return;
 
StoryGameSession story = game.session as StoryGameSession;
ArenaGameSession arena = game.session as ArenaGameSession;

Use story only after a non-null check for a campaign feature, and use arena only after the corresponding arena check. This fragment shows type selection only. The hook that supplies manager, the chosen data, and any mutations need their own evidence.

global::GameSession is an abstract base containing the game, abstract players, creature communities, difficulty, and character statistics. It has no universal save state, arena sitting, room, HUD owner, or session update method. global::StoryGameSession adds campaign save state, records, statistics, and transfer data. global::ArenaGameSession adds its arena sitting, mode behavior, initialization state, and HUD ownership.

RainWorldGame.Update() calls the arena session’s Update() when IsArenaSession is true. Story time instead advances from RainWorldGame.RawUpdate(float) through StoryGameSession.TimeTick(float) while gameplay is unpaused. These are separate paths. A plugin should not call either method to make a session advance.

Arena construction also comes before every usable arena condition. ArenaGameSession.Initiate() starts its behaviors and multiplayer HUD. Players may not be spawned yet. Its room property reads game.cameras[0].room, which can be absent during a transition.

Release state at a process switch

RequestMainProcessSwitch records the requested process after dialog handling. Once the fade finishes, PreSwitchMainProcess pauses or shuts down the old process, marks it inactive, and clears currentMainLoop. PostSwitchMainProcess restores a retained process or creates the requested one, assigns it as current, and lets the old process communicate with the replacement.

A process switch is the cleanup boundary for state that belongs to that process. Clear collections containing Room, RoomCamera, HUD, menu page, realized object, and Futile node references when their owner shuts down. Reacquire them from the new process if the feature remains applicable. Drawable lifetime covers camera resources, and HUD parts covers HUD cleanup.

Cooperative play can provide several players and cameras. Choose whether a feature has one controller per session, one effect per realized Player, or one overlay per RoomCamera. Access through Players[0] or cameras[0] encodes a policy and needs checks for empty collections and transitions.

No game process was launched for this page. Process changes, pause and resume behavior, story and arena transitions, cooperative play, save mutations, and interaction with other hooks still need runtime tests.

Sources

  • Rain World v1.11.8, Steam app 312520, build 22785462. Assembly-CSharp.dll SHA-256 B6BE1D4E18CE219D21091B51564CB6A11C1E4106B41DE903EB8E58849CB16FDB.
  • Assembly-CSharp.dll: global::ProcessManager.Update(System.Single), global::ProcessManager.RequestMainProcessSwitch(global::ProcessManager.ProcessID), global::ProcessManager.PreSwitchMainProcess(global::ProcessManager.ProcessID), and global::ProcessManager.PostSwitchMainProcess(global::ProcessManager.ProcessID).
  • Assembly-CSharp.dll: global::MainLoopProcess.RawUpdate(System.Single), global::MainLoopProcess.ShutDownProcess(), and global::MainLoopProcess.CommunicateWithUpcomingProcess(global::MainLoopProcess).
  • Assembly-CSharp.dll: global::RainWorldGame, global::GameSession, global::StoryGameSession, and global::ArenaGameSession.
  • Runtime reference records the same installed assembly baseline.