[{"data":1,"prerenderedAt":404},["ShallowReactive",2],{"docs-\u002Fbuild-logic\u002Ftargets":3},{"id":4,"title":5,"body":6,"description":394,"extension":395,"meta":396,"navTitle":397,"navigation":398,"path":399,"rawbody":400,"seo":401,"stem":402,"__hash__":403},"docs\u002Fbuild-logic\u002Ftargets.md","Target Matrix",{"type":7,"value":8,"toc":383},"minimark",[9,13,22,27,43,53,64,69,107,111,122,128,132,142,150,168,171,272,276,279,287,306,310,313,377],[10,11,5],"h1",{"id":12},"target-matrix",[14,15,16,17,21],"p",{},"The matrix is what lets one source tree build and publish against many Minecraft\nversions. A ",[18,19,20],"strong",{},"target"," is a named coordinate (Minecraft version + Java level +\nplatform dependency versions); adding one is a single edit to a properties file,\nnever a change to build scripts or CI.",[23,24,26],"h2",{"id":25},"targetsproperties","targets.properties",[14,28,29,30,34,35,38,39,42],{},"Each target is a prefix in ",[31,32,33],"code",{},"gradle\u002Ftargets.properties",". The ",[31,36,37],{},"target="," line at the\ntop is the default target used when no ",[31,40,41],{},"-Ptarget="," is passed:",[44,45,51],"pre",{"className":46,"code":48,"language":49,"meta":50},[47],"language-properties","target=mc12110\n\nmc12110.minecraft=1.21.10\nmc12110.java=21\nmc12110.yarn=1.21.10+build.3\nmc12110.loader=0.18.3\nmc12110.fabric_api=0.138.4+1.21.10\nmc12110.paper=1.21.11-R0.1-SNAPSHOT\nmc12110.neoforge=21.10.64\nmc12110.pb4_placeholder_api=2.8.1+1.21.10\nmc12110.miniplaceholders_api=3.1.0\n","properties","",[31,52,48],{"__ignoreMap":50},[14,54,55,56,59,60,63],{},"Every module compiles against the target's ",[31,57,58],{},"java"," level (via ",[31,61,62],{},"options.release","),\nwhile a single modern toolchain (JDK 25) compiles all targets. So you never\nprovision a separate JDK per Minecraft version.",[65,66,68],"h3",{"id":67},"per-target-fabric-java-requirement","Per-target Fabric Java requirement",[14,70,71,72,75,76,79,80,83,84,87,88,91,92,95,96,99,100,103,104,106],{},"A module that ships a ",[31,73,74],{},"fabric.mod.json"," declares its Java requirement as the\nliteral token ",[31,77,78],{},"\"java\": \"@MC_JAVA@\""," rather than a hardcoded ",[31,81,82],{},">=21",". During the\nbuild the shared ",[31,85,86],{},"java-library"," plugin substitutes it with ",[31,89,90],{},">=\u003Ctarget.java>",", so\na mod built for a 1.20.1 (Java 17) branch requires Java 17 and a 1.21.10 (Java\n21) branch requires Java 21 — from one manifest, resolved per target. This\nprevents a lower-Java branch from being wrongly rejected by the Fabric loader.\nThe token is a plain string, not a ",[31,93,94],{},"${...}"," placeholder, because Loom expands\n",[31,97,98],{},"${version}"," and would fail on an unknown ",[31,101,102],{},"${}"," key. All modules that carry a\n",[31,105,74],{}," — including the common ones (commands, logger, config, lang,\nplaceholders) — get the substitution.",[65,108,110],{"id":109},"library-vs-runtime-minecraft","Library vs runtime Minecraft",[14,112,113,114,117,118,121],{},"The published coordinate branch normally follows ",[31,115,116],{},"minecraft",". When the version\nyou publish against differs from the runtime one (for example a Paper build that\ntargets Java 21 on 1.20.5+), set ",[31,119,120],{},"\u003Ctarget>.library_minecraft"," and consumers\nresolve against that branch:",[44,123,126],{"className":124,"code":125,"language":49,"meta":50},[47],"mc12110.library_minecraft=1.21.10\n",[31,127,125],{"__ignoreMap":50},[23,129,131],{"id":130},"the-magicmatrix-dsl","The magicMatrix DSL",[14,133,134,137,138,141],{},[31,135,136],{},"magicMatrix { }"," in ",[31,139,140],{},"settings.gradle.kts"," declares the module layout and how\ntargets map to platforms. This is the single source of truth for the whole\nbuild:",[44,143,148],{"className":144,"code":146,"language":147,"meta":50},[145],"language-kotlin","magicMatrix {\n    targetsFile = \"gradle\u002Ftargets.properties\"\n    publishingFile = \"gradle\u002Fpublishing.properties\"\n    defaultTarget = \"mc12110\"\n\n    \u002F\u002F Your own platform-neutral module(s). Most consumers keep their own module\n    \u002F\u002F names, so no name remapping is needed here.\n    commonProjects(\"common\")\n\n    \u002F\u002F Platform module groups. The third argument disables a platform on\n    \u002F\u002F specific target prefixes (here NeoForge only on the 1.20.1 target).\n    platform(\"bukkit\", listOf(\"bukkit\"))\n    platform(\"fabric\", listOf(\"fabric\"))\n    platform(\"neoforge\", listOf(\"neoforge\"), listOf(\"mc1201\"))\n\n    \u002F\u002F Named build selections for CI and local work.\n    scenario(\"workspace\", listOf(\"bukkit\", \"fabric\", \"neoforge\"), \"Everything\")\n    scenario(\"fabric\", listOf(\"fabric\"), \"Fabric only\")\n}\n","kotlin",[31,149,146],{"__ignoreMap":50},[14,151,152,155,156,159,160,163,164,167],{},[31,153,154],{},"moduleNamePrefix(...)"," \u002F ",[31,157,158],{},"moduleName(project, artifact)"," remap a subproject name\nto a published artifact id (for example ",[31,161,162],{},"platform-bukkit"," -> ",[31,165,166],{},"magicutils-bukkit",").\nMagicUtils itself uses them; most consumers keep their own module names and can\nskip both.",[14,169,170],{},"Key methods:",[172,173,174,187],"table",{},[175,176,177],"thead",{},[178,179,180,184],"tr",{},[181,182,183],"th",{},"Method",[181,185,186],{},"Purpose",[188,189,190,204,218,229,239,249,259],"tbody",{},[178,191,192,201],{},[193,194,195,155,198],"td",{},[31,196,197],{},"targetsFile",[31,199,200],{},"publishingFile",[193,202,203],{},"Paths to the properties files.",[178,205,206,211],{},[193,207,208],{},[31,209,210],{},"defaultTarget",[193,212,213,214,217],{},"Target used when ",[31,215,216],{},"-Ptarget"," is absent.",[178,219,220,226],{},[193,221,222,155,224],{},[31,223,154],{},[31,225,158],{},[193,227,228],{},"Artifact id naming.",[178,230,231,236],{},[193,232,233],{},[31,234,235],{},"commonProjects(...)",[193,237,238],{},"Platform-neutral modules (built once).",[178,240,241,246],{},[193,242,243],{},[31,244,245],{},"platform(name, projects [, disabledTargetPrefixes])",[193,247,248],{},"A platform's module group, optionally disabled on some targets.",[178,250,251,256],{},[193,252,253],{},[31,254,255],{},"scenario(name, platforms [, description])",[193,257,258],{},"A named subset of platforms.",[178,260,261,269],{},[193,262,263,155,266],{},[31,264,265],{},"smoke { }",[31,267,268],{},"modrinth { }",[193,270,271],{},"Compatibility smoke and Modrinth release config (see the other pages).",[23,273,275],{"id":274},"selecting-a-target-or-scenario","Selecting A Target Or Scenario",[14,277,278],{},"At invocation time you pick a target and a scenario with Gradle properties:",[44,280,285],{"className":281,"code":283,"language":284,"meta":50},[282],"language-bash","# Build everything for the default target\n.\u002Fgradlew buildWorkspace\n\n# Build just the Fabric scenario on a specific target\n.\u002Fgradlew buildFabric -Ptarget=mc262\n\n# Publish the common modules on one target to Maven Local\n.\u002Fgradlew publishCommonMatrix -Ptarget=mc2611\n","bash",[31,286,283],{"__ignoreMap":50},[14,288,289,290,293,294,297,298,301,302,305],{},"Scenario aggregate tasks (",[31,291,292],{},"build\u003CScenario>",", ",[31,295,296],{},"check\u003CScenario>",",\n",[31,299,300],{},"publishToMavenLocal\u003CScenario>",") are generated from your ",[31,303,304],{},"scenario(...)","\ndeclarations.",[23,307,309],{"id":308},"inspecting-the-matrix","Inspecting The Matrix",[14,311,312],{},"These tasks print what the matrix resolves to, and feed CI:",[172,314,315,325],{},[175,316,317],{},[178,318,319,322],{},[181,320,321],{},"Task",[181,323,324],{},"Output",[188,326,327,337,347,357,367],{},[178,328,329,334],{},[193,330,331],{},[31,332,333],{},"magicutilsHelp",[193,335,336],{},"Human-readable summary of targets, scenarios, and usage.",[178,338,339,344],{},[193,340,341],{},[31,342,343],{},"listBuildMatrix",[193,345,346],{},"The resolved target, platforms, scenario, and included projects.",[178,348,349,354],{},[193,350,351],{},[31,352,353],{},"printBuildMatrix",[193,355,356],{},"JSON array of every target (for a CI build fan-out).",[178,358,359,364],{},[193,360,361],{},[31,362,363],{},"printPublishMatrix",[193,365,366],{},"JSON of every target with its publish tasks (publish fan-out).",[178,368,369,374],{},[193,370,371],{},[31,372,373],{},"printReleaseMatrix",[193,375,376],{},"JSON rows of (platform × smoke entry) for a release fan-out.",[14,378,379,380,382],{},"Because the target list comes from ",[31,381,26],{},", adding a Minecraft\nversion never touches a workflow file: CI reads the matrix from these tasks.",{"title":50,"searchDepth":384,"depth":384,"links":385},3,[386,391,392,393],{"id":25,"depth":387,"text":26,"children":388},2,[389,390],{"id":67,"depth":384,"text":68},{"id":109,"depth":384,"text":110},{"id":130,"depth":387,"text":131},{"id":274,"depth":387,"text":275},{"id":308,"depth":387,"text":309},"Build one MagicUtils-based source tree against many Minecraft versions with build-logic: targets.properties, the magicMatrix DSL, scenarios, and per-target selection.","md",{},null,true,"\u002Fbuild-logic\u002Ftargets","---\ntitle: Target Matrix\ndescription: 'Build one MagicUtils-based source tree against many Minecraft versions with build-logic: targets.properties, the magicMatrix DSL, scenarios, and per-target selection.'\n---\n\n# Target Matrix\n\nThe matrix is what lets one source tree build and publish against many Minecraft\nversions. A **target** is a named coordinate (Minecraft version + Java level +\nplatform dependency versions); adding one is a single edit to a properties file,\nnever a change to build scripts or CI.\n\n## targets.properties\n\nEach target is a prefix in `gradle\u002Ftargets.properties`. The `target=` line at the\ntop is the default target used when no `-Ptarget=` is passed:\n\n```properties\ntarget=mc12110\n\nmc12110.minecraft=1.21.10\nmc12110.java=21\nmc12110.yarn=1.21.10+build.3\nmc12110.loader=0.18.3\nmc12110.fabric_api=0.138.4+1.21.10\nmc12110.paper=1.21.11-R0.1-SNAPSHOT\nmc12110.neoforge=21.10.64\nmc12110.pb4_placeholder_api=2.8.1+1.21.10\nmc12110.miniplaceholders_api=3.1.0\n```\n\nEvery module compiles against the target's `java` level (via `options.release`),\nwhile a single modern toolchain (JDK 25) compiles all targets. So you never\nprovision a separate JDK per Minecraft version.\n\n### Per-target Fabric Java requirement\n\nA module that ships a `fabric.mod.json` declares its Java requirement as the\nliteral token `\"java\": \"@MC_JAVA@\"` rather than a hardcoded `>=21`. During the\nbuild the shared `java-library` plugin substitutes it with `>=\u003Ctarget.java>`, so\na mod built for a 1.20.1 (Java 17) branch requires Java 17 and a 1.21.10 (Java\n21) branch requires Java 21 — from one manifest, resolved per target. This\nprevents a lower-Java branch from being wrongly rejected by the Fabric loader.\nThe token is a plain string, not a `${...}` placeholder, because Loom expands\n`${version}` and would fail on an unknown `${}` key. All modules that carry a\n`fabric.mod.json` — including the common ones (commands, logger, config, lang,\nplaceholders) — get the substitution.\n\n### Library vs runtime Minecraft\n\nThe published coordinate branch normally follows `minecraft`. When the version\nyou publish against differs from the runtime one (for example a Paper build that\ntargets Java 21 on 1.20.5+), set `\u003Ctarget>.library_minecraft` and consumers\nresolve against that branch:\n\n```properties\nmc12110.library_minecraft=1.21.10\n```\n\n## The magicMatrix DSL\n\n`magicMatrix { }` in `settings.gradle.kts` declares the module layout and how\ntargets map to platforms. This is the single source of truth for the whole\nbuild:\n\n```kotlin\nmagicMatrix {\n    targetsFile = \"gradle\u002Ftargets.properties\"\n    publishingFile = \"gradle\u002Fpublishing.properties\"\n    defaultTarget = \"mc12110\"\n\n    \u002F\u002F Your own platform-neutral module(s). Most consumers keep their own module\n    \u002F\u002F names, so no name remapping is needed here.\n    commonProjects(\"common\")\n\n    \u002F\u002F Platform module groups. The third argument disables a platform on\n    \u002F\u002F specific target prefixes (here NeoForge only on the 1.20.1 target).\n    platform(\"bukkit\", listOf(\"bukkit\"))\n    platform(\"fabric\", listOf(\"fabric\"))\n    platform(\"neoforge\", listOf(\"neoforge\"), listOf(\"mc1201\"))\n\n    \u002F\u002F Named build selections for CI and local work.\n    scenario(\"workspace\", listOf(\"bukkit\", \"fabric\", \"neoforge\"), \"Everything\")\n    scenario(\"fabric\", listOf(\"fabric\"), \"Fabric only\")\n}\n```\n\n`moduleNamePrefix(...)` \u002F `moduleName(project, artifact)` remap a subproject name\nto a published artifact id (for example `platform-bukkit` -> `magicutils-bukkit`).\nMagicUtils itself uses them; most consumers keep their own module names and can\nskip both.\n\nKey methods:\n\n| Method | Purpose |\n| --- | --- |\n| `targetsFile` \u002F `publishingFile` | Paths to the properties files. |\n| `defaultTarget` | Target used when `-Ptarget` is absent. |\n| `moduleNamePrefix(...)` \u002F `moduleName(project, artifact)` | Artifact id naming. |\n| `commonProjects(...)` | Platform-neutral modules (built once). |\n| `platform(name, projects [, disabledTargetPrefixes])` | A platform's module group, optionally disabled on some targets. |\n| `scenario(name, platforms [, description])` | A named subset of platforms. |\n| `smoke { }` \u002F `modrinth { }` | Compatibility smoke and Modrinth release config (see the other pages). |\n\n## Selecting A Target Or Scenario\n\nAt invocation time you pick a target and a scenario with Gradle properties:\n\n```bash\n# Build everything for the default target\n.\u002Fgradlew buildWorkspace\n\n# Build just the Fabric scenario on a specific target\n.\u002Fgradlew buildFabric -Ptarget=mc262\n\n# Publish the common modules on one target to Maven Local\n.\u002Fgradlew publishCommonMatrix -Ptarget=mc2611\n```\n\nScenario aggregate tasks (`build\u003CScenario>`, `check\u003CScenario>`,\n`publishToMavenLocal\u003CScenario>`) are generated from your `scenario(...)`\ndeclarations.\n\n## Inspecting The Matrix\n\nThese tasks print what the matrix resolves to, and feed CI:\n\n| Task | Output |\n| --- | --- |\n| `magicutilsHelp` | Human-readable summary of targets, scenarios, and usage. |\n| `listBuildMatrix` | The resolved target, platforms, scenario, and included projects. |\n| `printBuildMatrix` | JSON array of every target (for a CI build fan-out). |\n| `printPublishMatrix` | JSON of every target with its publish tasks (publish fan-out). |\n| `printReleaseMatrix` | JSON rows of (platform × smoke entry) for a release fan-out. |\n\nBecause the target list comes from `targets.properties`, adding a Minecraft\nversion never touches a workflow file: CI reads the matrix from these tasks.\n",{"title":5,"description":394},"build-logic\u002Ftargets","v0V2wr9cGQoJBqD98poN3Lid1-Fm2iH86svAqy7f1OM",1783944486788]