This file is for Claude Code (and similar agents) working in this repository.
FPSMaster Edge is a free Minecraft PvP client implemented as a Minecraft Forge 1.8.9 mod. Java sources live under src/main/java/top/fpsmaster/. Chinese docs under docs/ are the human-facing reference; see AGENTS.md for the full agent conventions doc.
Do not add multi-version / modern-MC framework work here — that belongs in FPSMaster-Nova.
- JDK 17 or 21 runs Gradle / IDE import; JDK 8 runs the Minecraft client (Apple Silicon: x86_64 JDK 8 via Rosetta). Do not use JDK 25 with the current wrapper.
- Build uses
gg.essential.loom(Forge) + Shadow. Pipeline:shadowJar(all-dev) →remapJar(final jar) →assembledepends onremapJar. - Version:
FPSMaster.CLIENT_VERSION(1.0.0),EDITION(Edge); keepmcmod.infoaligned.
./gradlew build # full build → remapped output
./gradlew remapJar # final remapped jar
./gradlew shadowJar # shaded dev jar (all-dev)
./gradlew genIntelliJRuns # generate IntelliJ run configs (see docs/development_environment.md)
./gradlew test # JUnit 5; test tree is sparse
./gradlew test --tests "com.example.MyTest.method"No Spotless/Checkstyle/PMD task — do not invent one. Style: docs/code_standards.md (4-space indent, K&R braces, camelCase members, PascalCase types, UPPER_SNAKE constants). After genIntelliJRuns, run configs may need copying into .idea/ and absolute path fixes (docs/development_environment.md).
Entry: forge/Mod.java (@Mod modid fpsmaster) → FMLInitializationEvent → FPSMaster.INSTANCE.initialize(). FPSMaster holds static singletons (moduleManager, configManager, componentsManager, commandManager, fontManager, i18n, async, telemetry) and wires init (auth → fonts → modules → components → config → commands → i18n, etc.).
Three layers:
- Mixins (
forge/mixin/,mixins.fpsmaster.json) patch vanilla at load time and dispatch into the client viaEventDispatcher. Accessors live inforge/api/; AT infpsmaster_at.cfg. - Event bus (
event/): self-hostedEventDispatcher+@Subscribe(cached reflection). Cancelable events extendCancelableEvent. - Modules (
features/): extendModuleorInterfaceModule(HUD). Enable/disable registers listeners on the bus. Settings underfeatures/settings/impl/. Categories:OPTIMIZE,RENDER,Utility,Interface.
- Module: subclass
Module,addSettings(...)in ctor, register inModuleManager.init(). - HUD: subclass
InterfaceModulewith appropriateTraits (common appearance settings are registered viaregisterCommonSettings()— do not duplicate). Pair withui/custom/impl/*(TextComponentfor single-line HUDs, elseComponent). Register module + component. - Mixin: add under
forge/mixin/, append name inmixins.fpsmaster.json. - Command: subclass
Command, register inCommandManager.init(). Chat prefix.by default.
GlobalListener is always-on (chat copy, config autosave on value change, etc.).
modules/: config (ConfigManager, profiles viaConfigProfileUtils), i18n, auth/telemetry/async, music,ClientLogger.font/: TTF renderer;FontManagerparses the face once, pins base sizes, LRU-caches derived sizes and disposes atlases on eviction/reload.ui/: ClickGUI, screens, notifications, minimap.utils/: render/math/io/… (Utilitylives inutils.core).
- Log with
ClientLogger; no empty catches in new code. - Defensive null checks around
mc/ player / world, file I/O, reflection. Utility.mc(static import fromutils.core) is the usualMinecraftshortcut.- HUD colors need real alpha in ARGB.
- License GPL-3.0. Shaded (
shadowImpl) deps include mixin, jlayer, Java-WebSocket, jtransforms, slf4j.