- Shock on Death
- Shock on Damage
- Multiple on damage modes
- Threshold of damage
- Cooldown between damage shocks
- Adjustible intensity and duration
Config GUI by YetAnotherConfigLib
You can support the openshock dev team here: Sponsor OpenShock
The mod is built from a single source tree for every supported Minecraft version and both mod loaders, using Stonecutter for the version matrix and Stonecraft (which wraps Architectury Loom) for the loader wiring.
| Minecraft | 1.20.4, 1.21, 1.21.1, 1.21.4, 1.21.5, 1.21.11, 26.1, 26.2 |
| Loaders | Fabric, NeoForge |
| Targets | 16 (every version × every loader) |
| Java | 17 for 1.20.x, 21 for 1.21.x, 25 for 26.x (Gradle downloads any it is missing) |
./gradlew chiseledBuildAndCollect # build every target; jars land in build/libs/
./gradlew build # build only the currently active targetThe active target is the one your IDE and runClient use. Switch it with:
./gradlew "Set active project to 1.21.1-neoforge"Stonecutter rewrites the files under src/ in place when you switch, commenting out the branches
that do not apply to the new target. That is expected — do not revert it.
There are two sets of IntelliJ run configurations:
Client <version>-<loader>- generated by./gradlew generateRunConfigs. These invoke:<target>:runClientthrough Gradle and work without a successful Gradle sync. Re-run that task after adding or removing a Minecraft version, and it will rewrite the whole set.Minecraft Client (:<version>-<loader>)- generated by Architectury Loom during Gradle sync. These launch the game directly (faster, easier to debug) but need the IDE to have created the per-target modules first.
.idea/ is gitignored, so both sets are local to your machine.
From the command line:
./gradlew :26.2-fabric:runClient
./gradlew :1.21.1-neoforge:runClientYou do not need to switch the active target to run a different one - every target is a real Gradle subproject and can be launched directly. Switching only changes which one your IDE indexes and edits.
Each target runs in its own directory, run/<version>-<loader>/, because Minecraft 1.21.1 and 26.2
cannot share a world or an options file and the two loaders cannot share a mods folder.
Pushing a version tag runs .github/workflows/release.yml, which builds all targets, creates a
GitHub release with the jars attached, and publishes every one of them to Modrinth and CurseForge.
git tag 1.4.0 && git push origin 1.4.0The tag is the source of truth for the version (tag 1.4.0 publishes 1.4.0), so mod.version in
gradle.properties does not need bumping first. The changelog on Modrinth and CurseForge is a link
back to the GitHub release, so the notes only ever live in one place.
The tag also decides the release type, consistently across all three destinations:
| Tag contains | Modrinth / CurseForge | GitHub release |
|---|---|---|
alpha |
Alpha | pre-release |
beta, next, rc |
Beta | pre-release |
| anything else | Stable | normal |
rc needs an explicit mapping because Stonecraft's own inference recognises only alpha, beta
and next; left to it, an rc tag would reach both platforms marked stable.
Configure these under Settings -> Secrets and variables -> Actions:
| Secret | |
|---|---|
MODRINTH_TOKEN |
Modrinth PAT with the "Create versions" scope |
CURSEFORGE_TOKEN |
CurseForge API token |
| Variable | Current value |
|---|---|
MODRINTH_ID |
DwMSqx5B |
CURSEFORGE_ID |
980833 |
CURSEFORGE_SLUG |
openshock-shockcraft |
The workflow checks all five are set before building, so a missing one fails in seconds with a clear message rather than part-way through publishing.
Nothing is ever uploaded unless PUBLISH_RELEASE=true, which only the release workflow sets, so
running ./gradlew chiseledPublishMods locally is always a dry run. Use it to preview exactly what
would be sent:
./gradlew chiseledPublishModssettings.gradle.kts— the list of targets. Adding a Minecraft version is one line here plus a matchingversions/dependencies/<version>.propertiesfile.versions/dependencies/<version>.properties— every dependency version for that Minecraft version, shared by its Fabric and NeoForge targets. This is the only file to touch when bumping Fabric API, NeoForge, YACL, Mod Menu or Kotlin for Forge.build.gradle.kts— applied to every target.src/main/kotlin/.../platform/— the only loader- and version-specific code:Entrypoint.kt— the Fabric and NeoForge entrypoints.Platform.kt— the handful of loader APIs with no common equivalent.McCompat.kt— the few vanilla APIs that changed across the version range.
Everything outside platform/ compiles unchanged on all sixteen targets. Sources use Mojang
mappings, which both loaders share.
The version-conditional code is deliberately confined to those files. McCompat.kt covers the
vanilla renames (ResourceLocation/Identifier, the fromNamespaceAndPath factory,
displayClientMessage/sendOverlayMessage, Minecraft.screen moving onto Gui), and the
NeoForge half of Entrypoint.kt covers the 1.21 API break (TickEvent.ClientTickEvent became
ClientTickEvent.Post, ConfigScreenHandler.ConfigScreenFactory became IConfigScreenFactory,
and @Mod gained its dist element).
