Initial commit: claude derived solution

This commit is contained in:
2026-05-09 14:30:58 -04:00
commit 29d37f48eb
15 changed files with 824 additions and 0 deletions

99
README.md Normal file
View File

@@ -0,0 +1,99 @@
# Gravestone × Sable Compatibility Patch
A minimal patch mod for Minecraft **1.21.1 / NeoForge** that fixes gravestone
placement when a player dies on a Sable sub-level (e.g. a **Create Aeronautics**
airship). Without this mod, dying mid-flight makes gravestone place its block
(and a dirt support block) in the parent world at the player's visible position.
The blocks then clip into the airship's collision shape and stall its physics.
With this mod installed, the grave is placed inside the airship's plot area, so
it lands on the deck and travels with the airship like any other block on it.
## How it works (one paragraph)
Sable stores each sub-level's blocks in a far-away "plot" region of the same
`Level`. The visible airship position is a logical pose that's applied at render
and collision time only. Gravestone's `DeathEvents.playerDeath` calls
`GraveUtils.getGraveStoneLocation(level, deathPos)` with the player's world
position — but that position is empty space, so the search either fails or
places the grave clipping into the airship. This mod uses Mixin Extras'
`@WrapOperation` to intercept that single call and substitute the player's
position transformed into the sub-level's plot-local frame
(`subLevel.logicalPose().transformPositionInverse(playerPos)`). Gravestone's
existing search routine then finds the deck above the player's feet and places
the grave correctly inside the contraption. If the player isn't on a sub-level
when they die, the mod is a no-op.
The mod uses **Sable Companion** rather than depending on Sable directly, so
it's safe to ship in packs without Sable (the companion's default
implementation just returns null for all sub-level queries → graves behave
exactly like vanilla gravestone).
## Build
Requires **JDK 21**.
If you don't already have a Gradle wrapper jar in `gradle/wrapper/`, bootstrap
one first (one-time, needs any system Gradle ≥ 8.10 — `sdk install gradle 8.10`,
`brew install gradle`, `apt install gradle`, etc.):
```bash
gradle wrapper --gradle-version 8.10
```
Alternatively, copy `gradlew`, `gradlew.bat`, and `gradle/wrapper/` from any
recent NeoForge 1.21.1 mod template (e.g. the official
[NeoForge MDK](https://github.com/neoforged/MDK)).
Then build the mod:
```bash
./gradlew build
```
The output jar is at `build/libs/gravestone_sable_compat-1.0.0.jar`.
If the Modrinth maven can't resolve `gravestone-mod` for your machine, drop
`gravestone-1.21.1-1.0.19.jar` (or any 1.21.1 build of gravestone) into a
`libs/` folder at the project root, comment out the `compileOnly
"maven.modrinth:gravestone-mod:..."` line in `build.gradle`, and uncomment the
`compileOnly fileTree(dir: 'libs', ...)` line.
## Runtime requirements
Drop the built jar into your modpack alongside:
| Mod | Version |
|---|---|
| NeoForge | 21.1.x (1.21.1) |
| [Gravestone (henkelmax)](https://modrinth.com/mod/gravestone-mod) | 1.21.1-1.0.19 or later |
| [Sable](https://modrinth.com/mod/sable) | 1.0+ |
| [Sable Companion](https://github.com/ryanhcode/sable-companion) | 1.6+ (bundled inside this jar via JarInJar; no separate install needed) |
| Create Aeronautics | any version that uses Sable |
The mixin only attaches to `de.maxhenkel.gravestone.events.DeathEvents.playerDeath`'s
single call to `GraveUtils.getGraveStoneLocation(Level, BlockPos)`. The signature
of that call has been stable across gravestone 1.21.1-1.0.19 → 1.0.37, so the
mod should work with any of them. If a future build refactors that method, the
mixin will fail loudly at load time (`defaultRequire: 1`) rather than silently
no-op.
## File layout
```
gravestone-sable-compat/
├─ build.gradle
├─ gradle.properties
├─ settings.gradle
├─ src/main/java/com/example/gravestonesablecompat/
│ ├─ GravestoneSableCompat.java # tiny @Mod entry point
│ └─ mixin/DeathEventsMixin.java # the actual fix (one @WrapOperation)
└─ src/main/resources/
├─ META-INF/neoforge.mods.toml
├─ gravestone_sable_compat.mixins.json
└─ pack.mcmeta
```
## License
MIT — go wild.