Skip to content

Commit 6c04112

Browse files
committed
Improve AGENTS.md to better fit the current code
1 parent b9a502f commit 6c04112

1 file changed

Lines changed: 93 additions & 127 deletions

File tree

AGENTS.md

Lines changed: 93 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1,168 +1,134 @@
11
# AGENTS.md - NeteaseMusicDisplay
22

3-
A Minecraft Fabric mod that displays the current playing song from Netease Music on Windows.
3+
This file is the execution guide for coding agents working in this repository.
44

5-
## Tech Stack
5+
## Project Intent
66

7-
- **Build System**: Gradle with Fabric Loom
8-
- **Primary Language**: Kotlin (2.3.0)
9-
- **Secondary Language**: Java (for Mixin classes)
10-
- **Java Version**: 21
11-
- **Minecraft Version**: 1.21.10
12-
- **Mod Loader**: Fabric
7+
NeteaseMusicDisplay is a Fabric client-side mod that renders the currently playing Netease Cloud Music track inside Minecraft.
138

14-
## Build Commands
9+
- Primary runtime target: Minecraft `1.21.10`, Java `21`, Fabric Loader.
10+
- Platform behavior: track detection is Windows-specific (`cloudmusic.exe` via JNA), but the mod must stay safe on non-Windows systems.
11+
- User-facing contract: `/nmd` commands configure overlay state, position, color, width, and scale.
1512

16-
```bash
17-
# Build the mod JAR
18-
./gradlew build
13+
## Source Map (Current Code)
1914

20-
# Run all tests
21-
./gradlew test
15+
- `src/main/kotlin/com/as9929/display/netease/NeteaseMusicDisplay.kt`
16+
- Mod entrypoint. Loads config and registers client commands.
17+
- `src/main/java/com/as9929/display/netease/mixin/InGameHudMixin.java`
18+
- Injects into HUD render to call `TextRender.onRender(...)`.
19+
- `src/main/kotlin/com/as9929/display/netease/TextRender.kt`
20+
- Render pipeline + background polling thread (1s cadence) for song title cache.
21+
- `src/main/kotlin/com/as9929/display/netease/CloudMusicHelper.kt`
22+
- Windows API access through JNA (`user32` / `kernel32`) to read title from `cloudmusic.exe` windows.
23+
- `src/main/kotlin/com/as9929/display/netease/RenderUtils.kt`
24+
- Text drawing and scrolling logic with scissor clipping.
25+
- `src/main/kotlin/com/as9929/display/netease/config/ModConfig.kt`
26+
- Config model + `ConfigManager` load/save/update behavior.
27+
- `src/main/kotlin/com/as9929/display/netease/command/ConfigCommand.kt`
28+
- `/nmd` command tree and validation logic.
2229

23-
# Run a specific test class
24-
./gradlew test --tests "com.as9929.display.netease.YourTestClass"
30+
## Agent Priorities
2531

26-
# Run a specific test method
27-
./gradlew test --tests "com.as9929.display.netease.YourTestClass.testMethod"
32+
1. Keep runtime behavior stable for players.
33+
2. Preserve render-thread safety.
34+
3. Preserve non-Windows safety.
35+
4. Keep config compatibility and command UX intact.
36+
5. Prefer small, reviewable diffs over broad refactors.
2837

29-
# Run all checks (includes tests, ABI checks)
30-
./gradlew check
38+
## Non-Negotiable Invariants
3139

32-
# Clean build directory
33-
./gradlew clean
40+
### Windows/JNA Safety
3441

35-
# Full clean build
36-
./gradlew clean build
42+
- Always gate Windows-only behavior with an OS check before any JNA call path.
43+
- Keep native libraries lazily loaded (`by lazy`) so non-Windows startup does not fail.
44+
- Close native handles in `finally` blocks.
45+
- Expected failure path is `null` / no render, not a crash.
3746

38-
# Generate sources JAR
39-
./gradlew sourcesJar
40-
```
47+
### Threading and Render Safety
4148

42-
## Project Structure
49+
- Do not run heavy process/window scans on the render thread.
50+
- Shared mutable state between background polling and render code must remain thread-safe (`@Volatile` or stronger).
51+
- Minecraft client access and drawing logic must stay on the render thread.
4352

44-
```
45-
src/
46-
├── main/
47-
│ ├── java/com/as9929/display/netease/mixin/ # Java Mixin classes
48-
│ ├── kotlin/com/as9929/display/netease/ # Kotlin source
49-
│ └── resources/ # Mod metadata, assets
50-
│ ├── fabric.mod.json
51-
│ └── netease-music-display.mixins.json
52-
├── test/ # Test sources (if any)
53-
build.gradle # Build configuration
54-
gradle.properties # Version constants
55-
settings.gradle # Project settings
56-
```
53+
### Rendering Behavior
5754

58-
## Code Style Guidelines
55+
- `x == -1` means auto right-aligned placement.
56+
- Maintain matrix push/pop balance and scissor enable/disable balance.
57+
- Scrolling text should remain smooth and clipped to `maxBoxWidth`.
5958

60-
### Kotlin
59+
### Config and Command Contract
6160

62-
- **Indentation**: 4 spaces (no tabs)
63-
- **Line endings**: LF
64-
- **Package**: `com.as9929.display.netease`
65-
- Use `object` for singletons (e.g., `object TextRender`)
66-
- Use `by lazy` for expensive initialization
67-
- Prefer `val` over `var`
68-
- Use nullable types (`String?`) over exceptions for optional returns
69-
- Comments: Use `// --- Description ---` for section headers
70-
71-
Example:
72-
```kotlin
73-
package com.as9929.display.netease
74-
75-
import net.fabricmc.api.ModInitializer
76-
77-
object NeteaseMusicDisplay : ModInitializer {
78-
const val MOD_ID = "netease-music-display"
79-
80-
override fun onInitialize() {
81-
// Initialization code
82-
}
83-
}
84-
```
61+
- Config file path/name is `config/netease-music-display.json`.
62+
- Keep `ModConfig` defaults, `/nmd` argument bounds, and status output coherent after changes.
63+
- If adding/changing config fields, keep backward compatibility (`ignoreUnknownKeys` is already enabled).
8564

86-
### Java
65+
## Build and Validation
8766

88-
- **Indentation**: 4 spaces
89-
- **Package**: `com.as9929.display.netease.mixin` for Mixin classes
90-
- Use Mixin pattern for Minecraft injection points
91-
- Annotations on separate lines for complex injections
67+
Use Gradle wrapper from repo root:
9268

93-
Example:
94-
```java
95-
package com.as9929.display.netease.mixin;
69+
```bash
70+
./gradlew build
71+
./gradlew test
72+
./gradlew check
73+
```
9674

97-
import org.spongepowered.asm.mixin.Mixin;
75+
Notes:
76+
- Tests are currently absent; add them under `src/test/kotlin/...` when introducing non-trivial logic.
77+
- For documentation-only edits, full build is optional.
9878

99-
@Mixin(InGameHud.class)
100-
public class InGameHudMixin {
101-
@Inject(
102-
method = "render",
103-
at = @At(value = "INVOKE", target = "...")
104-
)
105-
private void onRender(...) { }
106-
}
107-
```
79+
## Coding Conventions
80+
81+
### Kotlin
10882

109-
### Naming Conventions
83+
- 4-space indentation, LF endings.
84+
- Package: `com.as9929.display.netease`.
85+
- Prefer immutable data and `copy(...)` updates for config.
86+
- Prefer nullable return paths for expected runtime misses.
87+
- Use SLF4J logging instead of stack trace prints in new code.
11088

111-
- **Classes**: PascalCase (e.g., `CloudMusicHelper`, `TextRender`)
112-
- **Objects**: PascalCase (e.g., `TextRender.INSTANCE`)
113-
- **Methods/Functions**: camelCase (e.g., `getCloudMusicTitle()`)
114-
- **Constants**: UPPER_SNAKE_CASE (e.g., `MOD_ID`, `PROCESS_QUERY_INFORMATION`)
115-
- **Packages**: lowercase (e.g., `com.as9929.display.netease`)
89+
### Java/Mixin
11690

117-
### Imports
91+
- Keep mixins in `com.as9929.display.netease.mixin`.
92+
- Use explicit `@Inject` targets and stable injection points.
93+
- Avoid broad injections when a precise target is available.
11894

119-
- Group imports by source:
120-
1. Kotlin/Java standard library
121-
2. Minecraft/Fabric libraries
122-
3. Project imports
123-
4. Third-party libraries (JNA, etc.)
124-
- Use wildcard imports sparingly
95+
### Imports and Naming
12596

126-
### Error Handling
97+
- Use explicit imports; avoid wildcard imports.
98+
- Class/Object: PascalCase, method/property: camelCase, constants: UPPER_SNAKE_CASE.
12799

128-
- Use nullable return types instead of throwing exceptions for expected failures
129-
- Wrap platform-specific code (Windows API) with OS checks first
130-
- Use try-finally for resource cleanup (handles, processes)
131-
- Log errors using SLF4J: `LoggerFactory.getLogger(MOD_ID)`
100+
## When Changing Specific Areas
132101

133-
### Threading
102+
### If you touch `CloudMusicHelper`
134103

135-
- Offload heavy work to background threads using `Executors`
136-
- Mark shared mutable state with `@Volatile`
137-
- Use daemon threads: `t.isDaemon = true`
138-
- Always access Minecraft client on main render thread only
104+
- Re-verify OS guard, lazy native loading, and handle cleanup.
105+
- Keep noisy/error-prone native failures non-fatal.
139106

140-
### Mixin Guidelines
107+
### If you touch rendering (`TextRender` / `RenderUtils` / mixin)
141108

142-
- Place all Mixin classes in `mixin` package
143-
- Use `@Inject` for adding behavior
144-
- Use proper `@At` targets (e.g., `INVOKE`, `HEAD`, `TAIL`)
145-
- Include shift when needed: `shift = At.Shift.BEFORE`
109+
- Re-verify no heavy work moved onto render path.
110+
- Re-verify clipping, scale, and right-alignment behavior.
146111

147-
## Key Dependencies
112+
### If you touch config or commands
148113

149-
- Fabric Loader: `0.18.4`
150-
- Fabric API: `0.138.4+1.21.10`
151-
- Fabric Language Kotlin: `1.13.8+kotlin.2.3.0`
152-
- JNA: For Windows API access (cloudmusic.exe integration)
114+
- Re-verify all `/nmd` subcommands:
115+
- `color`, `pos`, `width`, `scale`, `toggle`, `reset`, `status`
116+
- Keep command validation messages clear and user-safe (clamping where needed).
153117

154-
## Testing
118+
### If you update versions/dependencies
155119

156-
Currently no tests exist. When adding tests:
157-
1. Place in `src/test/kotlin/` mirroring main package structure
158-
2. Use JUnit 5 (included via Gradle)
159-
3. Run with `./gradlew test`
120+
- Update `gradle.properties` and ensure `build.gradle` remains consistent.
121+
- Confirm `fabric.mod.json` dependency bounds are still accurate.
160122

161-
## CI/CD
123+
## PR/Change Checklist for Agents
162124

163-
GitHub Actions workflow at `.github/workflows/build.yml`
125+
- Change is scoped to the requested outcome.
126+
- No regressions to non-Windows startup/runtime behavior.
127+
- No render-thread blocking added.
128+
- Command/config behavior remains coherent.
129+
- Build/test status reported honestly (including if not run).
164130

165-
## Resources
131+
## Reference Links
166132

167-
- Fabric Wiki: https://fabricmc.net/wiki
168-
- Mixin Wiki: https://github.com/SpongePowered/Mixin/wiki
133+
- Fabric docs: https://fabricmc.net/wiki
134+
- Mixin docs: https://github.com/SpongePowered/Mixin/wiki

0 commit comments

Comments
 (0)