mcNows
Nows Loader 0.10.0 / Minecraft 26.2

Metadata

Define nows.mod.kdl metadata, dependencies, side declarations and runtime entrypoints.

Some APIs may still change or behave unevenly because they do not have enough real-world use cases and test coverage yet.

Metadata

KDL is the recommended human-facing metadata format today, but it is replaceable. integrations/kdl turns nows.mod.kdl into the generic ModDescriptor model owned by core.

Nows looks for this file at the root of the mod jar:

nows.mod.kdl

The KDL reader requires a root mod node. id and version are required. name falls back to the id, minecraft falls back to *, and side falls back to both.

mod id="my_mod" name="My Mod" version="1.0.0" minecraft="26.2" side="client" {
    info {
        description "Short description shown to tools and companion UI."
        author "YourName"
        license "Apache-2.0"
        icon "assets/my_mod/icon.png"
    }

    links {
        homepage "https://example.com"
        sources "https://github.com/example/my-mod"
    }

    compatibility {
        requires "minecraft" version="26.2"
        depends "cloth-config" version=">=11.0.0"
        recommends "modmenu" version=">=1.0.0"
        incompatible-with "bad_mod" reason="Breaks the same screen"
    }

    load-order {
        after "cloth-config"
        before "late_mod"
    }

    properties {
        channel "stable"
    }

    runtime {
        network-channel "my_mod:main"
        listener "com.example.MyLifecycleListener"
        entrypoint "com.example.MyMod"
        transformer "com.example.MyTransformer"
        mixin "my_mod.mixins.json"
    }
}

Grouped KDL is the recommended style, but equivalent flat nodes remain supported. Runtime-provided ids such as minecraft, nows and nows-loader can be used in dependency declarations. Core normalizes mod ids, dependency ids and declaration keys for stable lookup, so tools should preserve valid lowercase ids in generated metadata.

side accepts client, server, both or common. Runtime validates discovered mods against the selected launch side before loading mod classes, so client-only mods are rejected on dedicated servers and server-only mods are rejected in client launches.

Parsed Descriptor Fields

The KDL reader normalizes metadata into ModDescriptor, so code that consumes metadata does not depend on KDL directly.

Descriptor field Source
id required mod id="..."; must match [a-z][a-z0-9_-]{1,63}
name mod name, defaulting to id
version required mod version
minecraft mod minecraft, defaulting to *
side side or environment, defaulting to both
description, icon root properties or info/metadata children
authors, contributors, licenses singular or plural metadata nodes/properties
contacts links, contact, homepage, sources, issues, wiki, discord, email
properties custom root properties, properties, custom, or declaration properties
dependencies dependency, compatibility and load-order nodes
declarations unknown nodes plus runtime declarations such as entrypoint, listener, mixin, network-channel

Dependency Semantics

Dependency nodes are validated by ModDependencyResolver before mods load. Required dependencies must be present and match the declared version range. Optional dependencies can influence order when the target mod is present. Conflict/incompatible declarations fail loading when the target version matches. Duplicate mod ids are rejected instead of letting one descriptor hide another.

Load order declarations are edges in the same resolver:

  • requires, depends, dependency and require make the target load before the current mod.
  • recommends and suggests are optional by default.
  • breaks, conflicts, conflict, incompatible and incompatible-with describe incompatible targets.
  • before and load-before make the current mod load before the target when the target is loaded.
  • after and load-after make the target load before the current mod when the target is loaded.

Version constraints support exact versions, wildcard equality such as 1.2.x, range-style constraints and common non-SemVer version labels through Nows’ core version constraint matcher. Use * when the relationship is not version-specific.

Runtime Declarations

Declarations are intentionally generic. Integrations decide which keys they care about:

Declaration Used for
entrypoint classes instantiated as mod entrypoints
listener GEB/Nows lifecycle listener classes
mixin mod-owned Mixin configuration json files
network-channel or network bidirectional network channels
clientbound-channel channel that receives clientbound packets
serverbound-channel channel that receives serverbound packets
transformer custom class transformer declarations

Mods can query loaded metadata through NowsContext:

if (context.isModLoaded("other_mod")) {
    String name = context.requireModDescriptor("other_mod").name();
}

boolean clientRuntime = context.side() == NowsSide.CLIENT;

Use context.modDescriptors() for a snapshot of every loaded descriptor, context.mod(id) for the loaded container, and context.modsById() when a manager needs stable map lookup by mod id.