This is an up-to-date, minimal, opinionated template for starting a multiloader Hex Casting addon on 1.20.1 with Architectury. Includes all necessary dependencies on both Forge and Fabric loaders, plus some demo bits.
Caution
Do not fork or clone this repository to set up a new mod! See the usage steps and FAQ for more details.
- Install the prerequisites:
- Git
- uv
- Any IDE with Java and Kotlin support (recommended: IntelliJ IDEA Community Edition)
- Create, clone, and enter a new GitHub repo.
Caution
Do not fork/clone/copy this repo directly.
- From the repo root, run this command to copy the template, then follow the prompts to set it up:
uvx copier copy gh:FallingColors/hexdummy . - Set up your Python environment and lockfile:
uv sync .\.venv\Scripts\activate # Windows . .venv/bin/activate.fish # fish source .venv/bin/activate # everything else
- Look through the generated project to make sure everything looks good, then add, commit, and push the generated files (including
uv.lock):git add . git update-index --chmod=+x gradlew git commit -m "Set up mod template" git push - Follow the hexdoc setup instructions for GitHub Pages.
- Set up the release workflow:
- In your GitHub repository settings, create two new environments called
pypiandcurseforge-modrinth. - Add the following environment secrets (not environment variables) to the
curseforge-modrinthenvironment:CURSEFORGE_TOKEN: Generate a new CurseForge API token.MODRINTH_TOKEN: Generate a new Modrinth PAT with theCreate versionsscope.
- Create a PyPI pending publisher with the following settings:
- PyPI Project Name: The
project.namevalue in yourpyproject.toml(eg.hexdoc-hexcasting) - Owner: Your GitHub username
- Repository name: Your GitHub repository name
- Workflow name:
release.yml - Environment name:
pypi
- PyPI Project Name: The
- If you'd like to publish your mod to https://maven.hexxy.media, follow these instructions to set it up.
- When your mod is ready, manually trigger a release through the Actions tab on GitHub.
- In your GitHub repository settings, create two new environments called
Further instructions TODO - look at HexDebug or IoticBlocks for examples, since this template is based heavily on those mods.
See the following branches for up-to-date example projects generated using HexDummy:
The following repository contains an example of a project generated using HexDummy, including GitHub Actions workflow runs and a hexdoc web book:
HexDummy uses Copier, a Python app for generating projects from parameterized templates. When you run uvx copier copy, Copier clones this repository, prompts you for some values, then fills those values into many placeholders in the template, making a customized project with no placeholder values for you to have to replace by hand.
As a consequence, this repository by itself is not a working Minecraft mod - if you look in the template directory, you'll see a lot of .jinja files with placeholders that still need to be filled in.
Minecraft mod releases tend to be brittle. HexDummy's release workflow includes separate inputs for each platform your mod is released to, so if some of them fail but others succeed, you can manually fix and re-release just the failing parts, rather than having to push a new tag or commit and release everything again.
Architectury's DeferredRegister does not work with modded registries. It's also somewhat unergonomic to use in Kotlin (in my opinion). So, HexDummy generates a Registrar base class that you can use to register things in all registries, vanilla or modded.
To add a registrar for a registry, create an object subclassing the registrar, and pass the ResourceKey of the registry and a callback that returns the actual registry to the superclass. (A callback is used to avoid initializing the registry too early on Forge.) Add the subclass to the initRegistries call in your common mod initializer.
Registering things with a HexDummy Registrar generally looks like this:
val REGISTERED_THING = register("registered_thing") { ThingConstructor("parameters") }register takes a callback for the same reason as the registry object: to avoid constructing the instance too early on Forge. The string is used as the path for a ResourceLocation, with your mod id as the namespace.
The value returned by register is an Entry<V>. You can use this to access the registered thing's id (.id) or ResourceKey (.key), and when you're sure registration has finished, the actual registered instance (.value).
For a more concrete example, the template comes with an example for registering patterns, and HexDebug has several more examples for various types of registries.
- Finish adding Yarn support.
- See if there's a better way to download dependencies for CI tests than just manually listing Modrinth URLs.
- Improve documentation.
- Investigate https://github.com/headlesshq/mc-server-test more. From the logs, it seems like the Fabric server test might not actually be loading any mods?
- Fix the CI tests in this repository.
- Figure out how to publish to CurseForge/Modrinth/GitHub without having to build the mod again.