mcNows
Nows Loader 0.6.2 / Minecraft 26.2

Metadata

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

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.

side accepts client, server, both or common. The current launcher runtime is client-side and rejects server-only mods before loading mod classes.

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.

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 and range-style constraints 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.