All notable changes to this project will be documented in this file.
- Expanded the Byte Buddy integration from a thin helper wrapper into a reusable patching framework designed for Mixin-style runtime transformations.
- Added
ByteBuddyPatchas a declarative patch definition API for targeting classes and applying multiple transformations without manually recreatingAgentBuilderor transformer boilerplate. - Added
ByteBuddyPatchRegistryfor managing multiple patches with deterministic ordering and configurable priorities. - Added JVM descriptor-based method matching for more reliable targeting across mapped, obfuscated, and legacy Minecraft environments.
- Added patch validation through
require(...), allowing transformations to fail immediately when an expected method or target is missing instead of silently continuing with an unapplied patch. - Added reusable Advice-based injection support for method entry, method exit, constructors, argument modification, return-value modification, and exception handling.
- Added support for replacing complete method implementations through direct Byte Buddy interception.
- Added low-level transformation access through
mutate(...), allowing patches to use raw Byte Buddy features such asMemberSubstitution, ASM visitors, field/method definitions, implemented interfaces, and custom builder mutations. - Kept the underlying Byte Buddy API exposed so advanced transformations are not restricted by the higher-level NilKit abstraction.
- Added a NilLoader transformation bridge so registered Byte Buddy patches can participate directly in NilLoader class transformation without requiring Byte Buddy self-attachment.
- Added optional
Instrumentation-based installation with retransformation support for environments where already-loaded classes must be patched. - Preserved explicit Byte Buddy Agent attachment behavior; NilKit still does not automatically invoke
ByteBuddyAgent.install()during SDK startup. - Added composition support so multiple independent patches can safely target the same class through a single transformation pipeline.
- Improved transformation diagnostics and failure behavior for incompatible targets, incorrect mappings, and changed method descriptors.
- Added documentation and examples for using the Byte Buddy patch API as a Mixin-style transformation layer.
- Documented patch registration, priorities, required targets, Advice injection, full method interception, and advanced raw Byte Buddy mutations.
- Added examples showing integration through the NilLoader transformer bridge without requiring a Java agent.
- Added the optional
Legacy-3.0.2-all.jardeveloper toolbox with Byte Buddy1.17.6, Byte Buddy Agent1.17.6, GEB core0.5.4, ClassGraph4.8.184, and SnakeYAML2.6, keeping upstream package names unrelocated for direct imports. - Added
DeveloperToolboxcapability checks plusByteBuddyHelper,ClassGraphHelper,YamlHelper, andGebHelperconvenience APIs. - Byte Buddy self-attachment remains explicit; SDK startup never calls
ByteBuddyAgent.install()automatically. - YAML helpers use
SafeConstructor, reject duplicate mapping keys, and cap aliases for safer configuration loading. - Moved GEB's
processorto the GradleannotationProcessorconfiguration. It is build-time tooling and is not bundled in the runtime shadow JAR. - Optional toolbox dependencies are available to SDK compilation/tests but are not published as transitive dependencies of the normal Maven artifact.
- Ensured
assemble/buildcreates the-all.jarand standalone-mapping-tool.jaralongside the normal JAR. - Attached both classified JARs to the Maven publication so project-local GPG publishing signs them together with sources/Javadocs.
- Moved signing configuration after classified artifact attachment and added project license/implementation metadata to the standalone mapping-tool JAR.
- Simplified the Windows Gradle launcher to respect the active
JAVA_HOMEselected byactions/setup-javabefore scanning other installed JDKs, while still rejecting unsupported Java 25 for Gradle 8.8. - Preserved service-provider metadata in the shadow JAR and added third-party notices/license files to the distribution.
- Restored GitHub Actions
build.ymlfor Ubuntu/Windows on JDK 17/21 andrelease.ymlforv*tags, including tag/version validation, changelog extraction, SHA-256 checksums, and GitHub Release creation. - Restored release helper scripts and a submodule guard that detects a missing
160000Git link fortools/MinecraftRemapping.
- Replaced the accidental Gradle snippet previously stored in
THIRD_PARTY_LICENSES.mdwith an actual third-party license inventory. - Updated stale
3.0.1metadata and documentation references to the in-development3.0.2release. - Kept complete mapping data outside release artifacts; mapping input continues to come directly from
tools/MinecraftRemapping.
- Removed the SDK's hard bytecode link to
net.minecraft.client.Minecraft;McHelpernow resolves the mapped Minecraft class lazily through reflection only when Minecraft-specific helpers are called. - Removed the compile-time
game/jarmodMinecraft 1.4.7 dependencies from the SDK build. The core artifact no longer needs a Minecraft JAR to compile. - Removed unused external ASM 9.5 runtime dependencies; transformer helpers already use NilLoader's shaded ASM API, avoiding unnecessary ASM classpath conflicts in
-all.jar. MinecraftAutoNetworkBridgeno longer assumes Minecraft 1.4.7. When explicitly enabled it reads-Dnilkit.minecraft.version=<version>and disables itself safely if the version or mappings are unavailable.- Added regression coverage that rejects hard
net.minecraft.*type references in the Minecraft-facing SDK classes.
- Removed the
.remappingstaging workflow.tools/MinecraftRemappingis now the single source path for mapping data. - Gradle mapping generation reads
tools/MinecraftRemapping/<version>/mcp2obf.srgdirectly from the pinned submodule. - Fixed
SimpleRemapso release JARs actually consume the generated mapping subset; 3.0.0 generatedGeneratedSrgMappingsbut never called it. - Replaced
prepareRemapping/import-submodulewith directinspectMinecraftRemapping,inspect-submodule, andsubmodule-pathworkflows. - Updated
gen_srg_mappings.pyto use project-relative paths instead of a machine-specific absolute Windows path.
- Removed duplicate declarations accidentally left in
build.gradle3.0.0 mapping-generation code.
- Added
agaricusb/MinecraftRemappingas an external Git submodule configuration attools/MinecraftRemapping, pinned by the bootstrap scripts to8ca7ba25dfd67eae43b3c73d02603ff6c085a6d7. - Added a Java 8-compatible SRG/CSRG mapping API:
SrgMappingSetandSrgMappings. - Added
MappingToolMainwithinspect,reverse,chain,lookup,list-submodule, andimport-submodulecommands, plus a standalonemapping-toolJAR that contains no mapping data. - Added Gradle
mappingToolandprepareRemappingtasks for local mapping workflows. - Added
MAPPINGS.mddocumenting mapping-source policy and local-only import behavior. - Added cross-platform Gradle launcher JVM discovery for Linux/macOS and Windows. JDK 21 and 17 are preferred automatically so a system-wide Java 25 does not break Gradle 8.8.
- Added GitHub Actions
build.ymlfor push/pull-request builds and tests on Ubuntu/Windows with JDK 17/21. - Added GitHub Actions
release.ymlforv*tags. Releases are created only after build/tests succeed, include JARs plus SHA-256 checksums, and use the matchingCHANGE.mdsection as the release body. - Added release helper scripts that verify tag/project version consistency and extract one changelog section.
- Bumped the SDK and metadata version to
3.0.0. - Java compilation now targets Java 8 with
--release 8while Gradle itself runs on a supported modern launcher JDK; a dedicated local JDK 8 installation is no longer required for normal builds. - Complete mapping collections are not duplicated into the project ZIP/release tree. Mapping-aware builds read directly from the pinned
tools/MinecraftRemappingsubmodule. - GitHub release responsibilities were separated from normal commit CI:
build.ymlonly validates commits/PRs, whilerelease.ymlowns tagged releases.
- Fixed Gradle 8.8 startup failing under Java 25 with
Unsupported class file major version 69by selecting a compatible installed launcher JDK before Gradle starts. - Fixed old mapping workflows relying on copied 100+ MB mapping trees by replacing them with explicit local import tooling and an external submodule reference.
- Mapping parsing now reports conflicting entries instead of silently replacing them, mapping composition keeps method descriptors namespace-correct, and CSRG member resolution no longer depends on class-entry order.
- Added project-local Maven publishing to
./mavenviapublishProjectLocal; publications are OpenPGP-signed with the user's normal GnuPG /gpg-agentsetup. - Added inherited event-listener discovery, typed-listener unregistration, and event-bus clearing APIs.
- Added cooldown remaining-time queries and expired-player cleanup.
- Added NIO client/server state inspection (
isRunning,isConnected, connection snapshots/counts) and server bound-port lookup. - Added default listener hooks for unknown packet IDs and exhausted client reconnect attempts without breaking existing listener implementations.
- Added packet-registry inspection helpers (
isRegistered,size,clear). - Added lifecycle controls/state for the automatic Minecraft network bridge, including explicit
stop()and automatic recovery after reconnect exhaustion. - Added regression tests for KDL, cooldown concurrency, and packet codec/registry behavior.
- Normal
buildno longer forces NilLoader decompilation;decompileNilloaderremains an explicit developer task. - KDL scalar output now uses KDL 2 forms (
#true,#false,#null,#inf,#-inf,#nan). - KDL parsing now accepts common KDL 2 numeric forms, raw strings, quoted property keys, dotted identifiers, nested block comments, and slash-dash node/entry suppression while retaining legacy boolean/null compatibility.
- Event registration is de-duplicated, scans inherited subscriber methods, and preserves deterministic registration order for equal-priority handlers.
- Network listener callback failures are isolated from the selector loop; packet serialization failures no longer disconnect healthy peers.
- Network constructor and packet-registry inputs are validated early with clearer errors.
- Fixed
TargetFinderreturning a nearby player that failed the requestedminDotaim threshold and fixed target ranking to prefer alignment with distance as the tie-breaker. - Fixed
CooldownTracker.tryUseGlobal/tryUsePlayerrace conditions so a cooldown window cannot be consumed concurrently by multiple callers. - Fixed entrypoint phase re-entrancy during the pre-dispatch event by installing the active-phase guard before posting the event.
- Fixed NIO server duplicate disconnect callbacks and stale connection entries.
- Fixed NIO client reconnect attempts terminating permanently when opening a replacement channel throws immediately or when a non-blocking connect completes immediately.
- Fixed KDL writer/parser round-trip failures for quoted property keys and KDL 2 scalar values.
- Fixed zero/invalid look-vector and negative-range edge cases in
TargetFinder. - Fixed
ReflectHelper.invokecontradicting its documented null-to-primitive-default behavior. - Fixed automatic network bridge getting stuck with a dead client after reconnect exhaustion.
- Fixed local SRG mapping reads using platform-default encoding and added clearer version validation.
- Added SDK runtime bootstrap for KDL-only mods (archives with
.nilsdkmod.kdlbut no root*.nilmod.css). - Added
KdlOnlyModBootstrapperto discover/inject such mods frommods/andnilmods/during SDK premain. - Added verbose bootstrap diagnostics for KDL-only loading flow (candidate scan, KDL entry detection, metadata parse status, classpath injection, premain invocation).
- Added formatted loaded-mod summary table log:
ID | Name | Version | Authors | License
- Bumped SDK version to
2.0.1in build and metadata resources. DefaultSdkEntrypointModulenow runs KDL-only bootstrap before dependency enforcement.
- Fixed KDL parser newline/block handling in nested sections, resolving
KdlParseExceptionduring valid.nilsdkmod.kdlparsing. - Improved metadata text decoding for runtime reads (UTF-8/UTF-16 BOM and UTF-16 heuristic fallback) in bridge and SDK metadata IO.
- Fixed KDL-only metadata resolution so injected mods now correctly expose
name,version, andentrypointsinstead of fallback?values.
- Introduced KDL support as a first-class metadata layer in
2.0.0.- Prior to
2.0.0, mods relied on NilLoader CSS metadata only (*.nilmod.css). 2.0.0adds SDK KDL metadata (*.nilsdkmod.kdl) and runtime bridge integration.
- Prior to
- Introduced a general-purpose KDL toolkit for broad SDK usage (not metadata-only):
KdlParser,KdlWriterKdlDocument,KdlNode,KdlValue,KdlParseException- Can be used by any system/module that needs KDL parsing/serialization.
NilLoaderHelperconvenience APIs for easier multi-mod integration and diagnostics:isAllModsLoaded(String...)getFirstLoadedMod(String...)getEntrypoints(String)hasEntrypoint(String, String)getModsWithEntrypoint(String)hasMissingRequiredMods(String)getMissingRequiredModsForLoadedMods()getModsRequiring(String)
- Forge/Fabric-like event architecture for easier mod development:
- Global SDK access point:
NilKit - Event primitives:
Event,CancellableEvent,EventPriority,SubscribeEvent - Central
EventBuswith:- annotation listener registration (
@SubscribeEvent) - typed callback registration (
listenstyle) - cancellation-aware dispatch flow
- annotation listener registration (
- Lifecycle events:
PreEntrypointDispatchEvent(cancellable)PhaseEventPostEntrypointDispatchEvent
- Entrypoint dispatcher now emits lifecycle events around phase execution.
NilModBasenow includes convenience methods to register/post/listen events.
- Global SDK access point:
- SDK KDL metadata schema expanded with richer mod info fields:
modurlsourceurllicensecredits(multi-value)
- Bumped SDK version to
2.0.0in build and metadata resources. NilMetadataBridgenow parses.nilsdkmod.kdlvia shared KDL parser (KdlParser) instead of manual string parsing for better compatibility.- KDL metadata merge now supports both section blocks (
nilmod {},entrypoints {}) and top-level fallback keys (name,description,authors,version,entrypoints.<phase>).
- Removed inconsistent changelog carry-over for
1.0.4under2.0.0.
- New helper methods are Java 8 compatible and return immutable collections where applicable.
- Focus of this update is DX (developer experience): reduce repetitive NilLoader metadata and dependency-check boilerplate in mods.
- Backward compatibility remains intact: CSS metadata stays primary, and KDL is additive for SDK-aware features.
- Bumped SDK version to
1.0.3in build and metadata resources. - KDL metadata parser remains custom/in-project (Java 8 compatible), without external KDL dependency.
- SDK-only metadata model and IO:
SdkModMetadataSdkMetadataKdlSdkMetadataIO
- Runtime metadata bridge in SDK:
NilMetadataBridgeNilMetadataPatchInstaller- Patches
NilMetadata.fromduring premain to merge CSS + KDL automatically.
- New SDK metadata resource source-of-truth:
src/main/resources/nilkit.nilsdkmod.kdl. NilLoaderHelperSDK metadata APIs:getSdkMetadata(String)/getSdkMetadata(NilMetadata)getMissingRequiredMods(String)areRequiredModsLoaded(String)getLoadBefore(String)getLoadAfter(String)getIconPath(String)getLoadedModIcons()getRequiredMods(String)isSafeLoad(String)
- SDK-only metadata is separated from NilLoader base metadata for compatibility.
- SDK metadata default file is now
.nilsdkmod.kdl(legacy.kdlnames are still readable). - Merge policy: CSS is primary; KDL only fills missing metadata fields.
- No per-mod custom Gradle metadata-generation step required.
- Dependency enforcement:
- Missing required mods +
safeload=true-> warn log - Missing required mods +
safeload=false-> error and stop startup
- Missing required mods +
- If SDK is not installed, NilLoader still reads only original
*.nilmod.cssand continues to work normally.
- New helper:
NilLoaderHelperinme.tamkungz.nilkit.helper. - Convenience APIs for NilLoader metadata and loaded-mod checks:
isModLoaded,isAnyModLoadedgetModMetadata,getModMetadataOrNull,getAllLoadedModsgetLoadedModIds,getLoadedModNames,getLoadedModsByIdgetSourceFile,getEntrypointNames,getEntrypointClass,describeMod
- New helper:
TransformerHelperinme.tamkungz.nilkit.helper. - Java-agent style class patch registration via NilLoader transformer pipeline (no Mixin required):
registerBytecodePatchfor raw byte[] transformsregisterAsmPatchfor ASMClassNodetransforms- class-name normalization utilities for internal slash format
SimpleRemap.forVersion("1.4.7")preserves manual mappings frombuild147()as higher priority.- External SRG (
tools/MinecraftRemapping/1.4.7/mcp2obf.srg) is used only to fill missing entries, not overwrite existingbuild147()mappings. SimpleRemap.forVersion(version)can load remap for versions that providetools/MinecraftRemapping/<version>/mcp2obf.srg.
- SRG files are not bundled into the built JAR.
- Build now auto-generates
GeneratedSrgMappingsfromtools/MinecraftRemapping/*/mcp2obf.srgand embeds only the extracted mappings used by SDK remap calls. - Runtime loads generated mappings first via
SimpleRemap, then keeps fallback behavior for local development.
- Mapping files are not duplicated into the main repository; the pinned
tools/MinecraftRemappingsubmodule is the only source path. - Initialize the submodule before mapping-aware builds:
git submodule update --init --recursive.
- README helper section now includes
NilLoaderHelperand summarizes key API groups. - README now documents class patching usage through
TransformerHelperand phase timing notes (premain/hijack).
- Configurable logging root namespace in
Loggers. - New APIs:
setRoot(String),getRoot(), andresetRoot(). - Per-mod/per-class explicit APIs:
sdk(String),forMod(String),forClass(String, Class<?>), andforModClass(String, Class<?>).
sdk()andforClass(Class<?>)continue to work with global fallback root.- Multi-mod usage is now supported via explicit-root APIs so roots like
A/...andB/...can coexist. - Logging root defaults to
DEFAULT_ROOTand safely falls back when blank/null is provided.
- Initial public release of NilKit.
- Core SDK base for NilLoader mods via
NilModBase. - Entrypoint framework with phase dispatching (
premain,hijack) and recursion safeguards. - Helper utilities for reflection, Minecraft internals, packet handling, and proxy behaviors.
- Utility classes including target resolution and cooldown tracking.
- Java NIO networking stack with client/server, codec, packet registry, and bridge utilities.
- Remapping support through
SimpleRemap. - Standardized logging API through
Loggers. - Example modules and NilLoader metadata resources.
- Maven publishing configuration and source/javadoc artifacts.
- Gradle-based build with Java toolchain (Java 8).
- NilGradle integration for NilLoader workflows.
- Shadow plugin configured for packaging.
- Optional decompilation task for NilLoader dependency inspection.
- This is the first changelog entry for the project.