global::Player.input[0] is the player’s current global::Player.InputPackage, while input[1] is the preceding package used by the inspected game code. Compare those two samples to distinguish a press or release from a held button.
bool jumpPressed = self.input[0].jmp && !self.input[1].jmp;
bool jumpReleased = !self.input[0].jmp && self.input[1].jmp;
bool jumpHeld = self.input[0].jmp;The same comparison works for the Boolean thrw, pckp, mp, and spec fields when that action is relevant. The game itself compares current and previous values for mp and spec. The samples establish an ordering within Player.input. They do not establish that an arbitrary hook runs once per rendered frame or once per intended gameplay update.
InputPackage fields
global::Player.InputPackage is a struct, so copying a package copies its field values. Its public input fields include:
| Field | Meaning available from the source |
|---|---|
x, y | Integer directional axes |
analogueDir | Unity Vector2 analog direction |
jmp | Jump state |
thrw | Throw state |
pckp | Pickup state |
mp | Map state |
spec | Special action state |
crouchToggle | Crouch toggle state |
gamePad | Input source metadata |
controllerType | Options.ControlSetup.Preset metadata |
Treat gamePad and controllerType as metadata recorded by the package. Their values do not identify a particular physical device layout or prove which hardware is connected.
InputPackage.AnyInput covers directional input, jump, throw, pickup, and special. It does not include mp. Code that uses AnyInput to dismiss a prompt will therefore not dismiss it for map input alone. AnyDirectionalInput checks both nonzero integer axes and a nonzero analogueDir, so it covers more cases than x != 0 || y != 0.
For zero-gravity conversion, InputPackage.ZeroGGamePadIntVec applies a magnitude threshold of 0.2f, then an axis threshold of 0.1f, before falling back to the integer direction. Apply those thresholds only when using that helper.
Read input at a chosen update point
An On.Player.Update hook can inspect the package before or after orig(self, eu). Reading after orig is appropriate when the mod needs the state left by the player’s normal update. Reading before it is appropriate only when the mod needs the incoming state before that method changes game state. Hook lifecycle explains the call-chain consequences.
Whichever side you choose, check that the global::Player is the intended player and is in the state required by the action. A hook can run for players outside the one camera or room a visual feature targets. If a press starts an overlay, pass a small state change to a HUD part rather than creating a new part every update while the button remains held.
Do not retain input[0] as a substitute for the game’s previous sample unless the selected hook and update frequency have been tested. The built-in input[1] comparison is the source-verified convention. A separate history buffer can be useful for a sequence or hold duration, but its time unit comes from the hook that fills it.
Custom bindings are separate
Menu.Remix.MixedUI.OpKeyBinder accepts a Configurable<UnityEngine.KeyCode>. It provides a Remix configuration control for keyboard, mouse, and joystick KeyCode values, and it can check for conflicts within the namespace it builds from the mod ID and setting key.
Binding a KeyCode does not add a field to Player.InputPackage and does not join Rain World’s control rebinding system. A mod must read and apply that configured key through a separately chosen input path. Remix settings covers how to bind and save the configurable itself. Use Localized text for the visible action label while keeping the setting key stable.
Runtime checks
This behavior was inspected in the baseline assembly and has not been logged in a running game. Test keyboard and controller input at the selected hook. Record current and previous packages for press, hold, release, analog direction, map, and special actions. In cooperative play, verify which Player receives each package and whether the feature should react separately for each player. Test pause and process transitions if the chosen state survives beyond a room.
Sources
global::Menu.Remix.MixedUI.OpKeyBinderin the same baseline assembly, including its constructor and configurable key binding.global::Player.Update(System.Boolean),global::Player.InputPackage,global::Player.InputPackage.AnyInput,global::Player.InputPackage.AnyDirectionalInput,global::Player.InputPackage.ZeroGGamePadIntVec, andglobal::Player.inputinAssembly-CSharp.dll, SHA-256B6BE1D4E18CE219D21091B51564CB6A11C1E4106B41DE903EB8E58849CB16FDB. See Runtime reference.