- Multi-module Architectury mod:
common(shared API/logic),fabric,neoforge(settings.gradle.kts). commonis the source of truth; loader modules mostly provide bootstrapping, loader deps, andactualimplementations.- Main entrypoint flow is
Archie.init()-> register events/network/config/datagen/gametest gates (common/src/main/kotlin/net/kernelpanicsoft/archie/Archie.kt).
- Cross-loader abstractions use Kotlin
expect/actualfiles named*.common.kt,*.fabric.kt,*.neoforge.kt(example:APlatform,ADataGeneratorPlatform,AGameTestPlatform). - Loader entrypoints must only delegate into common init methods:
- Fabric:
ArchieFabric.onInitialize*(fabric/src/main/kotlin/net/kernelpanicsoft/archie/ArchieFabric.kt) - NeoForge: bus listeners in
ArchieNeoForge(neoforge/src/main/kotlin/net/kernelpanicsoft/archie/ArchieNeoForge.kt)
- Fabric:
- Networking is centralized via
NetworkChannel; packets must be@Serializable data classand registered beforeregister()(common/src/main/kotlin/net/kernelpanicsoft/archie/networking/NetworkChannel.kt). ArchieNetworkChannel.init()is the canonical registration order example (register packet producers/consumers, then callregister()).
- Build all modules + merged artifact:
./gradlew build(rootbuild/assemblefinalize withfusejarsinbuild.gradle.kts). - Loader-specific dev runs:
./gradlew fabric:runClient,./gradlew neoforge:runClient. - Datagen runs are explicit tasks:
./gradlew fabric:runDatagen/./gradlew neoforge:runDatagen. - GameTest runs:
./gradlew fabric:runGametest/./gradlew neoforge:runGametest. - Docs pipeline:
embedDokkaIntoMkDocsthenpublishDocs(callsmike deploy ...);mkdocs.ymlcontains# !!! EMBEDDED DOKKA ... DO NOT COMMIT !!!markers.
- Keep resource/manifests tokenized using Gradle properties (
${mod_id},${versions.*}) infabric.mod.jsonandneoforge.mods.toml. - Shared assets are merged from
commoninto loader modules viaprocessResources; do not duplicateassets/archie/**directly in loader modules unless loader-specific. common/build.gradle.ktsintentionally usesmodImplementation(libs.fabric.loader)only for annotations/mixin deps; avoid importing random Fabric-only classes in common code.- Utility operators are used pervasively for IDs (
Archie % "main","namespace" % "path") fromcommon/src/main/kotlin/net/kernelpanicsoft/archie/util/ResourceLocation.kt.
- Versions and plugin IDs are centralized in
gradle/libs.versions.toml; update there first. - Packaging/publishing is configured at root via
modfusioner(fusejars) andmodpublisher(CurseForge/Modrinth IDs and required deps) inbuild.gradle.kts. - Mixins are split by scope: loader mixins in
fabric/src/main/resources/archie.mixins.jsonandneoforge/src/main/resources/archie.mixins.json, common mixin config incommon/src/main/resources/archie-common.mixins.json.
- For new gameplay/library logic: start in
common/src/main/kotlin/..., then add loaderactual/bootstrap only when APIs differ. - When adding packets/events/config sections, mirror existing object-singleton style (
Archie,AEvents,ArchieNetworkChannel) rather than introducing DI/service containers. - If adding new runtime libraries to shipped jars, use
bundleRuntimeLibrary(...)/bundleMod(...)in loaderbuild.gradle.ktsfiles (not plainimplementationonly).