Skip to content

Commit 649eefd

Browse files
Zangesclaude
andcommitted
Add README and MIT LICENSE
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 14501fd commit 649eefd

2 files changed

Lines changed: 97 additions & 0 deletions

File tree

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Zanges
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Early Input Guard
2+
3+
A small client-side NeoForge mod that stops a class of startup crash in large modpacks: a mouse
4+
click or key press (or an automatic per-tick event) being dispatched to another mod's input/tick
5+
listener **before that mod has registered its keybinds** — so the listener dereferences a `null`
6+
`KeyMapping` and the game hard-crashes.
7+
8+
- **Minecraft:** 1.21.1
9+
- **Loader:** NeoForge (21.1.x)
10+
- **Side:** client only
11+
12+
## The problem
13+
14+
In heavily-modded packs the client renders frames and polls input while the loading screen is still
15+
up, and FML may finish loading in a degraded state. Two things can leave a mod's keybind fields
16+
`null` when its listeners run:
17+
18+
1. **During the loading screen** — input is polled before every mod's `RegisterKeyMappingsEvent`
19+
handler has run.
20+
2. **In a broken mod state** — if any mod fails to construct, FML "cowardly refuses" to fire the
21+
client registration events (including `RegisterKeyMappingsEvent`) for the rest of the session, so
22+
keybinds are *never* assigned, yet NeoForge keeps dispatching input and per-tick events.
23+
24+
A single click in either situation reaches a listener like Quark's `HotbarChangerModule` or Arknights
25+
Endfield's `KeyInputHandler` and crashes with:
26+
27+
```
28+
java.lang.NullPointerException: Cannot invoke "net.minecraft.client.KeyMapping.isDown()"
29+
because "...changeHotbarKey" is null
30+
```
31+
32+
## What it does
33+
34+
It mixes into NeoForge's `ClientHooks` and short-circuits the relevant dispatch hooks while it is
35+
unsafe to deliver events to mod listeners:
36+
37+
| Hook | Guarded |
38+
| --- | --- |
39+
| `onMouseButtonPre` / `onMouseButtonPost` | mouse clicks |
40+
| `onMouseScroll` | scroll |
41+
| `onKeyInput` | key presses |
42+
| `fireClientTickPre` / `fireClientTickPost` | per-tick mod events |
43+
44+
**Suppression conditions:**
45+
46+
- **Input** is dropped when mod loading has errored (`ModLoader.hasErrors()`) **or** a `LoadingOverlay`
47+
is active.
48+
- **Ticks** are dropped when mod loading has errored. Suppressing ticks during a *healthy* loading
49+
screen is opt-in via config (see below), since some mods legitimately tick during loading.
50+
51+
This does **not** hide problems: NeoForge's loading-error screen still renders and its buttons still
52+
work (they dispatch through `Screen.mouseClicked`, a different path), so you can read the errors and
53+
quit cleanly instead of being thrown into a crash report. It also has no effect on a healthy,
54+
fully-loaded game — by then nothing is suppressed.
55+
56+
## Config
57+
58+
`config/earlyinputguard-client.toml`:
59+
60+
| Option | Default | Effect |
61+
| --- | --- | --- |
62+
| `suppress_ticks_during_loading_screen` | `false` | Also suppress client tick dispatch while a loading screen is active, not just in a broken mod state. |
63+
64+
## Building
65+
66+
Requires JDK 21.
67+
68+
```bash
69+
./gradlew build
70+
```
71+
72+
The mod jar is written to `build/libs/`.
73+
74+
## License
75+
76+
MIT

0 commit comments

Comments
 (0)