Commit Graph
18 Commits
Author SHA1 Message Date
selimaj-devandclaude 46c7bacd04 Build for Minecraft 26.3
Check / compile (pull_request) Successful in 16m19s
Adds 26.3 as a Stonecutter version, the last step of #39.

Input: 26.3 replaces GLFW with SDL, which numbers keys (scancodes),
modifiers and mouse buttons differently. Saturn keeps GLFW's numbers,
which common uses and the config's keybinds store, so saved keybinds
stay valid. The new Keys class converts at the boundary: key events,
modifiers and mouse buttons coming into Saturn's screens, and key codes
going to InputConstants. Its table pairs GLFW's codes with 26.3's
InputConstants of the same name. Key names come from the game on 26.3,
and version-specific code uses InputConstants' key constants rather
than GLFW's.

Rendering: Blaze3D's API moved to renderpearl, which Stonecutter
replacements cover. PoseStack's quaternion mulPose became rotate, and
TextureTarget takes a depth format instead of a flag. 26.3 compiles
shaders through SPIR-V and reorders the transforms block, so glass.fsh
takes explicit locations and the new order behind defines that
GlassRenderer sets, and the unlit cosmetics pipeline declares its
color target, which 26.3 requires.

OptionsScreen no longer takes whether a world is open.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 22:12:50 +02:00
selimaj-devandclaude 6b1b79062c Note in the version guide that version blocks can nest
Stonecutter 0.9 writes an inactive block inside another as /^ ... ^/,
so nesting works (GlassRenderer relies on it since 26.1). else if is
still clearer for several ranges of the same code.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 21:31:32 +02:00
selimaj-devandclaude a4ed30111c Build for Minecraft 26.2
Adds 26.2 as a Stonecutter version (#39).

26.2 splits the HUD out of Gui into Hud and moves the open screen, the
overlay and the toasts from Minecraft to Gui. A new Screens helper gets
and sets the screen and clears the overlay on every version, and
MinecraftClientMixin opens screens through it instead of shadowing
Minecraft.setScreen. SetScreenMixin targets Gui.setScreen and the HUD
hook Hud.extractChat on 26.2.

26.2's rendering API declares samplers through bind group layouts and
gives render targets a GpuFormat, so the glass pipeline adds SAMPLER1's
layout and its backdrops are RGBA8_UNORM like vanilla's targets. The
main render target is the game renderer's, the panorama no longer takes
a fade flag, and toasts are added with SystemToast.add.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 21:31:32 +02:00
selimaj-devandclaude 4fb48cc647 Build for Minecraft 26.1
Adds 26.1 as a Stonecutter version (step 3 of #39). Its jar also
loads on the 26.1.1 and 26.1.2 hotfixes.

Most of 26.1's changes are renames: the GUI's render methods became
extract methods and GuiGraphics became GuiGraphicsExtractor, which
Stonecutter replacements cover along with the moved render state
package and GuiRenderState's add methods. The rest are version
comments:

- The menu panorama is drawn by GuiRenderer from vanilla's cube map;
  the new GuiRendererMixin swaps in Saturn's while a Saturn screen is
  open (empty on older versions).
- The camera works out the FOV and aligns with its entity in
  alignWithEntity, so the zoom and freelook hooks move to CameraMixin.
- Gamma and the menu blur are read while extracting render state.
- The glass blur's post chain takes a Projection and its buffer.
- The dragon's alpha render type is gone; capes use entityCutout.
- Fabric API renamed KeyBindingHelper to KeyMappingHelper.

The docs describe the 26.x build and Java 25.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 19:15:10 +02:00
selimaj-devandclaude 09bc223b8b Implement the Ref interfaces explicitly in their mixins
Several mixins implemented a Ref method only through a vanilla method
of the same name. Released jars rename vanilla methods to intermediary
names, so those Ref methods had no implementation there and threw
AbstractMethodError: the armour display's durability, the status
effects' icon and infinite checks, the SVG texture size and the
pre-1.21.6 matrix stack's push and pop. With Mojang's names the same
happens in development (1.21.4 crashed on the title screen).

Each mixin now shadows the vanilla method and implements the Ref
method by calling it. Points common at the Ref renames this needs.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 17:42:48 +02:00
selimaj-devandclaude af27907356 Build every version with Mojang mappings instead of Yarn
Minecraft ships unobfuscated from 26.1, and 1.21.11 has the last Yarn
release, so the shared src/ has to use Mojang's names before newer
versions can be added (#39).

Each version's sources were migrated with Loom's migrateMappings and
merged back into src/, so code that is only active on other versions
is migrated too. Where Mojang's names differ between 1.21.x versions,
src/ uses the newest ones: Stonecutter replacements swap in the older
Identifier/ResourceLocation and Avatar/Player renderer names, and
version comments cover the few package moves and renamed methods.

The fog mixin now targets setupFog on every version. Yarn's applyFog
named two methods from 1.21.6 on, so it also applied to updateBuffer.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 17:39:14 +02:00
selimaj-devandclaude 22a7152f0d Replace nametags while the render state is built, on every version
Check / compile (pull_request) Successful in 2m49s
NametagsMixin hooked EntityRenderer.renderLabelIfPresent with a
VertexConsumerProvider, which 1.21.9 moved to the render command queue, so
custom nametags only worked before 1.21.9 (#30).

LivingEntityRendererMixin already captures health and entity type at the
end of LivingEntityRenderer.updateRenderState. It now also applies
NametagsMod's replacement to state.displayName there, the label the
renderer draws later. This works the same on every version, so
NametagsMixin and its features.mixins.json entry are gone.

As before, only entities that already show a label get a replacement. For
players, the role icon is added after this (PlayerEntityRendererMixin), so
it now comes before the replaced name and keeps its colour, instead of
being folded into the replacement text.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 07:13:54 +02:00
selimaj-devandclaude 48118f6a84 Fill five version gaps from #30
Check / compile (pull_request) Successful in 2m31s
- World age on 1.21.11: World.getTime() was a shortcut for
  getLevelProperties().getTime(), which every version has, so
  getWorldAge uses that everywhere (the TPS feature and day counter got 0
  on 1.21.11).
- Screen resize on 1.21.11: override resize(int, int), the new signature.
- Splash loading-bar border on 1.21.9+: drawBorder was renamed
  drawStrokedRectangle.
- Drag deltas on 1.21.9+: mouseDragged(Click, offsetX, offsetY) gets the
  deltas as offsetX/offsetY; Saturn's screens got 0.0 before.
- Role icon in player names on 1.21.4-1.21.7: only storing the player in
  the render state needs Fabric API's render state data (1.21.8+). The
  updateRenderState hook now runs on every version and only the setData
  call is limited to 1.21.8+.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 06:59:18 +02:00
selimaj-devandclaude 25a19d7951 Build 1.21.4 with Stonecutter; every version now shares src/
Check / compile (pull_request) Successful in 7m44s
Step 6 of #8. versions/1.21.4/src is gone, so all eight versions (1.21.4 to
1.21.11) build from src/.

1.21.4's differences from 1.21.5 are behind version comments:
- The end gateway render layer has no render pipeline before 1.21.5
  (ShaderUtils: the pipeline field only exists from 1.21.5, and the layer
  is a four-way chain).
- Hat head rotation, the NativeImageBackedTexture constructor, armor slots
  (inventory.armor vs getEquippedStack), MatrixStackMixin's Quaternionf,
  and inside the pre-1.21.6 implementations: prevHeadYaw, GUI lighting,
  ModelTransformationMode, item depth, setShaderTexture and the blur
  uniform call. Those are one-line version comments, since the pre-1.21.6
  blocks are already inside /* */ on newer versions.

1.21.5's drawItem wrapped its body in a second isEmpty check after already
returning early for empty stacks; the redundant check is gone, so 1.21.4
and 1.21.5 share the body.

Freelook's zoom-out (FreelookMod.shouldZoomOut in GameRendererMixin) only
existed on 1.21.4. It doesn't depend on the Minecraft version, so it's
back on every version.

With no old copies left, the mc-<v> fallback in settings.gradle.kts and
scripts/port.sh are removed, and README and VERSION_GUIDE describe the
single layout.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 06:34:32 +02:00
selimaj-devandclaude a949c18ec1 Build 1.21.6 with Stonecutter from the shared src/
Check / compile (pull_request) Successful in 8m3s
1.21.6's copy only differed from 1.21.7's in RenderScopeImpl: item
rendering uses ItemRenderState, which 1.21.7 renamed to
KeyedItemRenderState. That's behind a version comment; 1.21.6 keeps its
older loader_version (0.18.5) in its gradle.properties.

Moving a version over leaves the old mc-<v> project's compiled classes in
the shared build/ folder, so a removed class (1.21.6's dead NameTagMixin)
still got packaged until a clean. VERSION_GUIDE now says to run
:<v>:clean once after moving a version.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 06:10:31 +02:00
selimaj-devandclaude 6f122b5237 Build 1.21.7 with Stonecutter from the shared src/
Step 5 of #8. versions/1.21.7/src is gone; 1.21.7 builds from src/ as
:1.21.7.

1.21.7's copy differed from 1.21.8's in the player render state: Fabric
API's RenderStateDataKey only exists from 1.21.8 (fabric-rendering-v1
12.6.0), so 1.21.7 had no updateRenderState hook, no SaturnRenderState,
and looked players up by name for the cloak and hat. That stays the case:
- The cloak and hat use getData on >=1.21.8 and SaturnPlayer.get(name)
  before that.
- PlayerEntityRendererMixin's updateRenderState exists only on >=1.21.8,
  as flat ranges (>=1.21.9, else if >=1.21.8) calling a shared
  saturn$applyPlayer helper, instead of nested version blocks.
- SaturnRenderState's key only exists on >=1.21.8; the class is empty
  before.
- TODO: 1.21.6 and 1.21.7 still don't show the role icon in names.

1.21.7's NameTagMixin isn't carried over: it wasn't registered in any
mixin config, so it never ran.

The 1.21.7 jar differs from the old one only as 1.21.8's did in step 4
(entityAlpha and drawGroup helpers, getIconId, and the cloak getting its
buffer at the draw call), plus the empty SaturnRenderState and the
missing dead NameTagMixin. 1.21.8-1.21.11 only differ in
PlayerEntityRendererMixin (the helper).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 05:46:41 +02:00
selimaj-devandclaude 0bf4fc6808 Build 1.21.8 with Stonecutter from the shared src/
Check / compile (pull_request) Successful in 10m37s
Step 4 of #8, the first version before the 1.21.9 render queue.
versions/1.21.8/src is gone; 1.21.8 builds from src/ as :1.21.8.

API differences behind version comments (<1.21.9 / >=1.21.9):
- Player cosmetics: FeatureRenderer.render takes a VertexConsumerProvider
  instead of the render queue. The cloak, hat and OBJ renderers name the
  render target "output" in both, so only the parameter type and the final
  draw call differ; the OBJ face loop moved into drawGroup.
- PlayerEntityRenderer.updateRenderState's entity type, the cape texture
  accessor, GameProfile getName()/getId() vs name()/id(), fonts in
  TextMixin, EntityRenderDispatcher vs EntityRenderManager, Screen input
  events (Click/KeyInput), and KeyBinding categories and isKeyPressed.

Features 1.21.9+ lacks stay on 1.21.8, with a TODO for 1.21.9+:
- NametagsMixin moves into src/. It hooks renderLabelIfPresent with a
  VertexConsumerProvider, which 1.21.9 changed, so on 1.21.9+ its body is
  empty; it stays registered, so features.mixins.json is the same for
  every version.
- The splash screen's loading-bar border, and the real drag deltas in
  SaturnScreenFabric.mouseDragged.
- Status effect icons keep 1.21.8's GUI atlas sprite; 1.21.9+ draws the
  texture instead (getIconId), as before.

Behaviour changes on 1.21.8: the cloak and hat read the Saturn player from
the render state (set by PlayerEntityRendererMixin, by UUID) instead of
looking it up by name, and the display-name null check applies.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 05:24:24 +02:00
selimaj-devandclaude f2d30e6611 Build 1.21.9 with Stonecutter from the shared src/
Check / compile (pull_request) Successful in 7m8s
Step 3 of #8. 1.21.9's copy was identical to the old 1.21.10 one, so the
existing version comments already cover it and no code changes: 1.21.9 is
added to stonecutterVersions and versions/1.21.9/src is removed.

Like 1.21.10 in step 2, 1.21.9 now renders hats (1.21.11's render-queue
implementation) and gets the display-name null check. The jar has the same
entries, fabric.mod.json and mixin configs as before; only those classes
and ShaderUtils's entityAlpha helper differ in bytecode.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 05:10:15 +02:00
selimaj-devandclaude 95e4dff448 Build 1.21.10 with Stonecutter from the shared src/
Check / compile (pull_request) Successful in 7m13s
Step 2 of #8. versions/1.21.10/src is gone; 1.21.10 builds from src/ as
:1.21.10, with versions/1.21.10 keeping only gradle.properties and run/.

API differences go behind version comments: render layers (ShaderUtils),
Camera.update's World vs BlockView (CameraMixin), the text and textured-quad
render states (RenderScopeImpl), Screen.init (SplashOverlayMixin) and
jspecify's @NonNull (SaturnRenderState).

Features 1.21.11 leaves out stay on 1.21.10, with a TODO for 1.21.11:
WorldFeatureImpl.getWorldAge, SaturnScreenFabric.resize and
EntityDrawerImpl clearing the hitbox.

Hats now render on 1.21.10: its HatFeatureRenderer overrode the
render-queue method with an empty body, and the working code sat in an old
VertexConsumerProvider method nothing called. 1.21.10 now uses 1.21.11's
render-queue implementation (HatFeatureRenderer, ObjModel, ObjRenderer),
and also gets 1.21.11's null check on the player's display name.

The 1.21.10 jar has the same entries, fabric.mod.json and mixin configs as
before; only those four classes and ShaderUtils (a helper method for
entityAlpha) have different bytecode. The 1.21.11 jar only differs in
ShaderUtils.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 05:05:03 +02:00
selimaj-devandclaude eebfe8fa4d Switch the root build scripts to Kotlin and limit parallel remaps
Check / compile (pull_request) Successful in 7m47s
- settings.gradle, stonecutter.gradle and the root build.gradle become
  .kts. Loom's version for the Stonecutter versions moves to the root
  gradle.properties (loom_version), read by pluginManagement, since the
  Kotlin plugins block can't read properties. The old mc-<v> projects keep
  their Groovy scripts until they're folded in.
- buildAll ran all eight remapJar tasks at once. Each loads a Minecraft
  classpath and remaps a ~50 MB jar, which doesn't fit in the 3 GB daemon
  heap: a cold build stalled in garbage collection for 40+ minutes, and
  earlier runs failed. A shared build service now lets two remaps run
  together; a cold buildAll takes about 2 minutes.
- port.sh and VERSION_GUIDE follow the .kts file names.

The 1.21.11 jar is the same as with the Groovy scripts.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 04:51:28 +02:00
selimaj-devandclaude 019e5cfb43 Build 1.21.11 with Stonecutter from a shared src/
Step 1 of #8. 1.21.11's version-specific code moves from versions/1.21.11/src
to the top-level src/, built by Stonecutter as the project :1.21.11. The other
versions still build from their own copies as :mc-<v> until they're folded in.

- settings.gradle: applies Stonecutter (Groovy controller) with
  stonecutterVersions = ["1.21.11"] and skips those folders when including
  the old mc-<v> projects.
- The old root build.gradle becomes stonecutter.gradle (the root project's
  script, with the shared repositories, common wiring and buildAll), and
  1.21.11's build.gradle becomes the root build.gradle that Stonecutter runs
  for each version. versions/1.21.11 keeps its gradle.properties and run/.
- The jar has the same 415 entries, fabric.mod.json and mixin configs as
  before; the only class differences also appear when rebuilding an
  untouched version today.
- scripts/port.sh treats src/ as the active Stonecutter version, so changes
  port between it and the old copies both ways.
- README and VERSION_GUIDE describe the layout, version comments and how to
  add a version.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 04:18:42 +02:00
selimaj-devandclaude f73f7e733c Add a version port script and a compile check for pull requests
Check / compile (pull_request) Successful in 18m7s
- scripts/port.sh ports a change made under versions/<from>/src to the
  other versions with `git apply --3way`: clean where files match,
  normal conflicts only where a version really differs. Supports
  uncommitted changes or --commit, --to, --dry-run, and detects changes
  already applied.
- .gitea/workflows/check.yml compiles every version on pull requests and
  pushes to master (--continue reports all failing versions).
- VERSION_GUIDE.md documents the layout, porting, and adding a version.

Closes #17, closes #18

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-26 02:41:22 +02:00
selimaj-dev b98fe211f0 Starting fresh 2026-03-05 15:24:28 +01:00