Dq?;#c!KKy79e
zBtQRO-}mipGyGcYrR5(vvlfO$sQ547Tdsq@dhLj>HG)NE>QCLG$RJat?*iw7e
z5dH=J4GnHBmCzitNI`RmP!TN+Q9@`T6+~F#>wQigx%h?Wy?^JPdwzVs_vox`jd}N_
zcegLv(~2az4Twj(Od#Ae4|kr}>KDVuNA=51ra~?5x%}v1?djX_5!{KXRIhw9>7dvo
zWp!qkM?B3ao`2|t#f|<}vmTJMmB)P(i4B_C^NY#etV&ld8RwP;BzSn#k@kVzG96W_
zKN6g|T98#CRe!jk71={WaanA%wV-l-;@p&P3u4o`Gd7)Y#PXpuNPx3bI94dJDlKPs
zZ``AT2Fa-pXxU=gck~5-1Y{Zq(pq+CyIm2^HafMzPXQN>Do#9{mdaXzs>+|sIwz_T
zK9@s8$wiJ$rCyYafK{skIAil_&|uFeo0Hg)$p<&h^?!Upvf3|#|LpM1y*Pb!HMtFE
zCpYQg#87^8MIby$hBnZnLy7^;p(~jQgtu}88Z3JF!MWPHXhdQ_Ou6*=_X^B74kl6e
z_ApUdHR^=?8wr3PLg`9&ptE5Q8ASlyi<5Q{PesCE4;6rp-4#ftLakrYkre(cUw|P1
P0000}I
zy)vK(d5YlzwD~x1a;_tY2!%i1PwV`>FZq2nIoA=zKrk>}R9$2|Ql(l#L^1GJr_2tJ
zST_^|ZMv%ahu{JN;^8amP!D@+P_+e>>gT5x52dLl(UlK%%FTPcE%
T#an{_0000$4g
delta 494
zcmVpGok>JNR5(vvk}*pIK@f!}OKe3&P;6qlQ}h%eWk4b-Vr3Js7yJb&
zY-}tnQdn78SPH3yaQYJj(P)v*1VI#nrm>NDns1UhHuqp}_J4Ng&Age}OliH8kv_uZ
zFrJ;8k(=n&ZEbJH?{6OxECo`#s=3NhC2qIclAF)rD$#YM7JpaXFUKrB@c_B|`6b->
z%W#Bh=+&}ppo!+K$g06|DX
zL#_0Ys2n0Q7(3H{Uy*^n0Bib4mcsOL?II7bS&F7{D
zrwnzpASMlhWwj>_NYZ#}=u?K1yaOMQed#P~9H0!pk;#P*t8@6PU@G=jxHGkmDE!zc
kEj!kNnDwVJm`2t818JEa&V$%T0000007*qoM6N<$g1q(H*Z=?k
diff --git a/common/src/main/resources/assets/minecraft/textures/block/mangrove_leaves.png b/common/src/main/resources/assets/minecraft/textures/block/mangrove_leaves.png
index 8891092c057c0bab27a8720fcecc770d8b72c657..1fe0289ad99948fab6ceb58e471ded1c29b15810 100644
GIT binary patch
delta 240
zcmV(>9qMn;Sv4CTXdM|=B!K$~=c!axiH
zQPlG;^h!BvnZPSkSwJSr`bU#ZEt>qC6TP*>IHdXWJog+0-2macaRBhKiQ<@gG0Jt?E!AK2YkQFrSl^9ur(d=ER#%MbNcxjPAwQB-^D@VYt4Jtt2
zG8i|2DB##PYBbIb0I?>$fc^8xt+btcT7cKLj;gy%ll}p?0W=f@0NAwCZ_2r$0LdxH
q4pGUP(kjR5(vNGT$UtqH036yyrw6yX$0
z8;N=glp+#Rs8NcDVmZXZK9j#Pqx>R{J>&mvkN4tXKL2@KE`RN5wMy2bD2fhW_}K5Q
zX&Nib(rzXbYulDP_Pk#ExhKiFo6S1x>t^G=NFzuVuE*m)0{%o?jYdQAWuL$~Rxt^H
ze+ne#WPtcfUHgBLaF2L8mw;M?e6@Hxow^Uw=iy*)+if~`NDSrgesEDpbAUMYQ}vQa
z{5l@};C;9A*MFcypbF%J`^CcTpbWTxngAinaq&=sxN>|3r^AkN0MEo=1ytBZmMykN9MWMA2xucU*t)LWvdREOT8T693wgQyx6n~V
zRaG4%d{1M>lpB!9X|L_t(|+G5B^$@mY#P7Y3tJNN7a(=%qy02EFKC=|mW3_x?~
z&yK&3zyk@wfY2_Q8kN0+xj(<>9ZU{R?(ji^2PY^tr*Go9&ly6M2#C1q>X2PQ^{#@0
z-EN4T5{SD!?r=d6dz~W?>-j|Qf~-5g=98;;xV9q4cU0QRI8eOgYqhxs1ucNRr3fw;
zXRo+kWqRVBu-CaAL6B`#!Zl3XoY@slH`SIL_Yn8~kALKBD|@PNZKNOJ=nsgR4#H~c
R(ait=002ovPDHLkV1g>RXHEbB
delta 441
zcmV;q0Y?7w0n-DJB!2;OQb$4nuFf3k00004XF*Lt006O%3;baP00009a7bBm000id
z000id0mpBsWB>pGXh}ptR5(v{@5NGEoqKp#TtJE*3+e)N!==*j(vkMKDJRrkc%CJ$y_rDiJkKO`%j-g^88STIK*V1uS5E|-r
zVkD%J5E(E@eJIt~g;6tA#6DxZ1B*yJQsWIlOs!3s-!eKVx4ad=$o5B4x?pe_kU^5L
jP}zJwr1DtJqUrwtmmW}rrdQN!00000NkvXXu0mjfg!#XD
diff --git a/common/src/main/resources/assets/minecraft/textures/block/pale_oak_leaves.png b/common/src/main/resources/assets/minecraft/textures/block/pale_oak_leaves.png
new file mode 100644
index 0000000000000000000000000000000000000000..7a0f81ba2c77c692168d664001943504a227cd0b
GIT binary patch
literal 266
zcmV+l0rmcgP)84wK^ycf46yBV199hl%y2+A+;)RI0L|X)2iqJGajIp$
Q!2kdN07*qoM6N<$f|37nvj6}9
literal 0
HcmV?d00001
diff --git a/common/src/main/resources/assets/minecraft/textures/block/spruce_leaves.png b/common/src/main/resources/assets/minecraft/textures/block/spruce_leaves.png
index 8bd6cdba419c5009847907f14bedb3a24b91cf8d..d37a65140fd9616671ec078d0d6e7ba17246b42d 100644
GIT binary patch
delta 202
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
Date: Sun, 15 Dec 2024 13:57:26 -0600
Subject: [PATCH 032/215] Clean up BitArray class
---
.../mods/sodium/client/util/MathUtil.java | 14 ++
.../client/util/collections/BitArray.java | 152 +++---------------
2 files changed, 35 insertions(+), 131 deletions(-)
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/util/MathUtil.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/util/MathUtil.java
index 5a11ae1355..01d267e128 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/util/MathUtil.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/util/MathUtil.java
@@ -12,6 +12,20 @@ public static long toMib(long bytes) {
return bytes / (1024L * 1024L); // 1 MiB = 1048576 (2^20) bytes
}
+ /**
+ * Rounds the integer {@param num} up to the next multiple of {@param alignment}. This multiple *MUST* be
+ * a power-of-two, or undefined behavior will occur.
+ *
+ * @param num The number to round up
+ * @param alignment The power-of-two multiple to round to
+ * @return The rounded number
+ */
+ public static int align(int num, int alignment) {
+ int additive = alignment - 1;
+ int mask = ~additive;
+ return (num + additive) & mask;
+ }
+
/**
* Converts a float to a comparable integer value. This is used to compare
* floating point values by their int bits (for example packed in a long).
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/util/collections/BitArray.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/util/collections/BitArray.java
index 2fb9d6252a..f018b18e6c 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/util/collections/BitArray.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/util/collections/BitArray.java
@@ -1,5 +1,7 @@
package net.caffeinemc.mods.sodium.client.util.collections;
+import net.caffeinemc.mods.sodium.client.util.MathUtil;
+
import java.util.Arrays;
/**
@@ -10,30 +12,14 @@ public class BitArray {
private static final int ADDRESS_BITS_PER_WORD = 6;
private static final int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD;
private static final int BIT_INDEX_MASK = BITS_PER_WORD - 1;
- private static final long WORD_MASK = 0xFFFFFFFFFFFFFFFFL;
+ private static final long WORD_MASK = -1L;
private final long[] words;
- private final int count;
-
- /**
- * Returns {@param num} aligned to the next multiple of {@param alignment}.
- *
- * Taken from https://github.com/CaffeineMC/sodium/blob/1.19.x/next/components/gfx-utils/src/main/java/net/caffeinemc/gfx/util/misc/MathUtil.java
- *
- * @param num The number that will be rounded if needed
- * @param alignment The multiple that the output will be rounded to (must be a
- * power-of-two)
- * @return The aligned position, either equal to or greater than {@param num}
- */
- private static int align(int num, int alignment) {
- int additive = alignment - 1;
- int mask = ~additive;
- return (num + additive) & mask;
- }
+ private final int capacity;
- public BitArray(int count) {
- this.words = new long[(align(count, BITS_PER_WORD) >> ADDRESS_BITS_PER_WORD)];
- this.count = count;
+ public BitArray(int capacity) {
+ this.words = new long[(MathUtil.align(capacity, BITS_PER_WORD) >> ADDRESS_BITS_PER_WORD)];
+ this.capacity = capacity;
}
public boolean get(int index) {
@@ -64,13 +50,14 @@ public void set(int startIdx, int endIdx) {
long firstWordMask = WORD_MASK << startIdx;
long lastWordMask = WORD_MASK >>> -endIdx;
+
if (startWordIndex == endWordIndex) {
this.words[startWordIndex] |= (firstWordMask & lastWordMask);
} else {
this.words[startWordIndex] |= firstWordMask;
for (int i = startWordIndex + 1; i < endWordIndex; i++) {
- this.words[i] = 0xFFFFFFFFFFFFFFFFL;
+ this.words[i] = -1L;
}
this.words[endWordIndex] |= lastWordMask;
@@ -86,128 +73,33 @@ public void unset(int startIdx, int endIdx) {
long firstWordMask = ~(WORD_MASK << startIdx);
long lastWordMask = ~(WORD_MASK >>> -endIdx);
+
if (startWordIndex == endWordIndex) {
this.words[startWordIndex] &= (firstWordMask & lastWordMask);
} else {
this.words[startWordIndex] &= firstWordMask;
for (int i = startWordIndex + 1; i < endWordIndex; i++) {
- this.words[i] = 0x0000000000000000L;
+ this.words[i] = 0L;
}
this.words[endWordIndex] &= lastWordMask;
}
}
- // FIXME
- /* public boolean checkUnset(int startIdx, int endIdx) {
- int startWordIndex = wordIndex(startIdx);
- int endWordIndex = wordIndex(endIdx - 1);
-
- long firstWordMask = ~(WORD_MASK << startIdx);
- long lastWordMask = ~(WORD_MASK >>> -endIdx);
- if (startWordIndex == endWordIndex) {
- return (this.words[startWordIndex] & firstWordMask & lastWordMask) == 0x0000000000000000L;
- } else {
- if ((this.words[startWordIndex] & firstWordMask) != 0x0000000000000000L) {
- return false;
- }
-
- for (int i = startWordIndex + 1; i < endWordIndex; i++) {
- if (this.words[i] != 0x0000000000000000L) {
- return false;
- }
- }
-
- return (this.words[endWordIndex] & lastWordMask) == 0x0000000000000000L;
- }
- }*/
-
- public void copy(BitArray src, int startIdx, int endIdx) {
- int startWordIndex = wordIndex(startIdx);
- int endWordIndex = wordIndex(endIdx - 1);
-
- long firstWordMask = WORD_MASK << startIdx;
- long lastWordMask = WORD_MASK >>> -endIdx;
- if (startWordIndex == endWordIndex) {
- long combinedMask = firstWordMask & lastWordMask;
- long invCombinedMask = ~combinedMask;
- this.words[startWordIndex] = (this.words[startWordIndex] & invCombinedMask)
- | (src.words[startWordIndex] & combinedMask);
- } else {
- long invFirstWordMask = ~firstWordMask;
- long invLastWordMask = ~lastWordMask;
-
- this.words[startWordIndex] = (this.words[startWordIndex] & invFirstWordMask)
- | (src.words[startWordIndex] & firstWordMask);
-
- int length = endWordIndex - (startWordIndex + 1);
- if (length > 0) {
- System.arraycopy(
- src.words,
- startWordIndex + 1,
- this.words,
- startWordIndex + 1,
- length);
- }
-
- this.words[endWordIndex] = (this.words[endWordIndex] & invLastWordMask)
- | (src.words[endWordIndex] & lastWordMask);
- }
- }
-
- public void copy(BitArray src, int index) {
- int wordIndex = wordIndex(index);
- long invBitMask = 1L << bitIndex(index);
- long bitMask = ~invBitMask;
- this.words[wordIndex] = (this.words[wordIndex] & bitMask) | (src.words[wordIndex] & invBitMask);
- }
-
- public void and(BitArray src, int startIdx, int endIdx) {
- int startWordIndex = wordIndex(startIdx);
- int endWordIndex = wordIndex(endIdx - 1);
-
- long firstWordMask = WORD_MASK << startIdx;
- long lastWordMask = WORD_MASK >>> -endIdx;
- if (startWordIndex == endWordIndex) {
- long combinedMask = firstWordMask & lastWordMask;
- long invCombinedMask = ~combinedMask;
- this.words[startWordIndex] &= (src.words[startWordIndex] | invCombinedMask);
- } else {
- long invFirstWordMask = ~firstWordMask;
- long invLastWordMask = ~lastWordMask;
-
- this.words[startWordIndex] &= (src.words[startWordIndex] | invFirstWordMask);
-
- for (int i = startWordIndex + 1; i < endWordIndex; i++) {
- this.words[i] &= src.words[i];
- }
-
- this.words[endWordIndex] &= (src.words[endWordIndex] | invLastWordMask);
- }
- }
-
- private static int wordIndex(int index) {
- return index >> ADDRESS_BITS_PER_WORD;
- }
-
- private static int bitIndex(int index) {
- return index & BIT_INDEX_MASK;
- }
-
public void fill(boolean value) {
- Arrays.fill(this.words, value ? 0xFFFFFFFFFFFFFFFFL : 0x0000000000000000L);
+ Arrays.fill(this.words, value ? -1L : 0L);
}
- public void unset() {
+ public void unsetAll() {
this.fill(false);
}
- public void set() {
+ public void setAll() {
this.fill(true);
}
- public int count() {
+ public int countSetBits() {
int sum = 0;
for (long word : this.words) {
@@ -218,7 +110,7 @@ public int count() {
}
public int capacity() {
- return this.count;
+ return this.capacity;
}
public boolean getAndSet(int index) {
@@ -262,13 +154,11 @@ public int nextSetBit(int fromIndex) {
}
}
- public String toBitString() {
- StringBuilder sb = new StringBuilder();
-
- for (int i = 0; i < this.count; i++) {
- sb.append(this.get(i) ? '1' : '0');
- }
+ private static int wordIndex(int index) {
+ return index >> ADDRESS_BITS_PER_WORD;
+ }
- return sb.toString();
+ private static int bitIndex(int index) {
+ return index & BIT_INDEX_MASK;
}
}
From 2d2808402126c16dcf352b938a8d7f49c80e8be5 Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Sun, 15 Dec 2024 14:15:29 -0600
Subject: [PATCH 033/215] Use link.caffeinemc.net domain for some URLs
---
.../net/caffeinemc/mods/sodium/desktop/LaunchWarn.java | 2 +-
.../client/compatibility/checks/GraphicsDriverChecks.java | 8 ++++----
.../sodium/client/compatibility/checks/ModuleScanner.java | 8 ++++----
.../client/compatibility/checks/PreLaunchChecks.java | 2 +-
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/common/src/desktop/java/net/caffeinemc/mods/sodium/desktop/LaunchWarn.java b/common/src/desktop/java/net/caffeinemc/mods/sodium/desktop/LaunchWarn.java
index 577c762e52..1a612a41aa 100644
--- a/common/src/desktop/java/net/caffeinemc/mods/sodium/desktop/LaunchWarn.java
+++ b/common/src/desktop/java/net/caffeinemc/mods/sodium/desktop/LaunchWarn.java
@@ -7,7 +7,7 @@
import java.io.IOException;
public class LaunchWarn {
- private static final String HELP_URL = "https://github.com/CaffeineMC/sodium/wiki/Installation";
+ private static final String HELP_URL = "https://link.caffeinemc.net/guides/sodium/installation";
private static final String RICH_MESSAGE =
"" +
diff --git a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/GraphicsDriverChecks.java b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/GraphicsDriverChecks.java
index 5d410dadac..d37572b0f4 100644
--- a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/GraphicsDriverChecks.java
+++ b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/GraphicsDriverChecks.java
@@ -31,9 +31,9 @@ static void postContextInit(NativeWindowHandle window, GlContextInfo context) {
Installed version: ###CURRENT_DRIVER###
Required version: 10.18.10.5161 (or newer)
- You must update your graphics card driver in order to continue."""
+ Please click the 'Help' button to read more about how to fix this problem."""
.replace("###CURRENT_DRIVER###", installedVersionString),
- "https://github.com/CaffeineMC/sodium/wiki/Driver-Compatibility#windows-intel-gen7");
+ "https://link.caffeinemc.net/help/sodium/graphics-driver/windows/intel/gh-899");
}
}
@@ -53,9 +53,9 @@ static void postContextInit(NativeWindowHandle window, GlContextInfo context) {
Installed version: ###CURRENT_DRIVER###
Required version: 536.23 (or newer)
- You must update your graphics card driver in order to continue."""
+ Please click the 'Help' button to read more about how to fix this problem."""
.replace("###CURRENT_DRIVER###", installedVersionString),
- "https://github.com/CaffeineMC/sodium/wiki/Driver-Compatibility#nvidia-gpus");
+ "https://link.caffeinemc.net/help/sodium/graphics-driver/windows/nvidia/gh-1486");
}
}
diff --git a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/ModuleScanner.java b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/ModuleScanner.java
index 8107366ef7..8af1a8d70f 100644
--- a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/ModuleScanner.java
+++ b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/ModuleScanner.java
@@ -105,10 +105,10 @@ You appear to be using an older version of RivaTuner Statistics Server (RTSS) wh
You must either update to a newer version (7.3.4 and later) or close the RivaTuner Statistics Server application.
For more information on how to solve this problem, click the 'Help' button.""",
- "https://github.com/CaffeineMC/sodium/wiki/Known-Issues#rtss-incompatible");
+ "https://link.caffeinemc.net/help/sodium/incompatible-software/rivatuner-statistics-server/gh-2048");
throw new RuntimeException("The installed version of RivaTuner Statistics Server (RTSS) is not compatible with Sodium, " +
- "see here for more details: https://github.com/CaffeineMC/sodium/wiki/Known-Issues#rtss-incompatible");
+ "see here for more details: https://link.caffeinemc.net/help/sodium/incompatible-software/rivatuner-statistics-server/gh-2048");
}
}
@@ -133,10 +133,10 @@ private static void checkASUSGpuTweakIII(NativeWindowHandle window) {
b) Completely uninstall the ASUS GPU Tweak III application.
For more information on how to solve this problem, click the 'Help' button.""",
- "https://github.com/CaffeineMC/sodium/wiki/Known-Issues#asus-gtiii-incompatible");
+ "https://link.caffeinemc.net/help/sodium/incompatible-software/asus-gtiii/gh-2637");
throw new RuntimeException("ASUS GPU Tweak III is not compatible with Minecraft, " +
- "see here for more details: https://github.com/CaffeineMC/sodium/wiki/Known-Issues#asus-gtiii-incompatible");
+ "see here for more details: https://link.caffeinemc.net/help/sodium/incompatible-software/asus-gtiii/gh-2637");
}
private static @Nullable WindowsFileVersion findRTSSModuleVersion() {
diff --git a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/PreLaunchChecks.java b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/PreLaunchChecks.java
index 70cb73e27e..5912c283d2 100644
--- a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/PreLaunchChecks.java
+++ b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/PreLaunchChecks.java
@@ -49,7 +49,7 @@ private static void checkLwjglRuntimeVersion() {
.replace("###ADVICE_STRING###", advice);
PlatformHelper.showCriticalErrorAndClose(null, "Sodium Renderer - Unsupported LWJGL", message,
- "https://github.com/CaffeineMC/sodium/wiki/LWJGL-Compatibility");
+ "https://link.caffeinemc.net/help/sodium/runtime-issue/lwjgl3/gh-2561");
}
private static boolean isUsingKnownCompatibleLwjglVersion() {
From 842cdd67ac9d3f4d6a36ae53ff86d0a320233c78 Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Sun, 15 Dec 2024 17:12:27 -0600
Subject: [PATCH 034/215] Use ShellExecuteW from message box callbacks
This fixes a regression caused by 26f4263.
The underlying problem is that accessing Java's AWT *after*
LWJGL3 has initialized is not possible.
Minecraft has a utility class which uses rundll32 internally,
but we cannot access that due to classloader restrictions on
NeoForge.
That leaves us with having to implement the call ourselves,
and simply using Shell32 directly (like we do for other
Windows APIs) seems easiest.
---
.../sodium/client/platform/MessageBox.java | 7 +--
.../client/platform/windows/api/Shell32.java | 57 +++++++++++++++++++
2 files changed, 59 insertions(+), 5 deletions(-)
create mode 100644 common/src/workarounds/java/net/caffeinemc/mods/sodium/client/platform/windows/api/Shell32.java
diff --git a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/platform/MessageBox.java b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/platform/MessageBox.java
index bf0cfb47cb..fe80d7a501 100644
--- a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/platform/MessageBox.java
+++ b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/platform/MessageBox.java
@@ -1,6 +1,7 @@
package net.caffeinemc.mods.sodium.client.platform;
import net.caffeinemc.mods.sodium.client.compatibility.environment.OsUtils;
+import net.caffeinemc.mods.sodium.client.platform.windows.api.Shell32;
import net.caffeinemc.mods.sodium.client.platform.windows.api.User32;
import net.caffeinemc.mods.sodium.client.platform.windows.api.msgbox.MsgBoxCallback;
import net.caffeinemc.mods.sodium.client.platform.windows.api.msgbox.MsgBoxParamSw;
@@ -58,11 +59,7 @@ public void showMessageBox(NativeWindowHandle window,
if (helpUrl != null) {
msgBoxCallback = MsgBoxCallback.create(lpHelpInfo -> {
- try {
- Desktop.getDesktop().browse(URI.create(helpUrl));
- } catch (IOException e) {
- System.out.println("Failed to open! Giving up.");
- }
+ Shell32.browseUrl(window, helpUrl);
});
} else {
msgBoxCallback = null;
diff --git a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/platform/windows/api/Shell32.java b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/platform/windows/api/Shell32.java
new file mode 100644
index 0000000000..5409b7fcea
--- /dev/null
+++ b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/platform/windows/api/Shell32.java
@@ -0,0 +1,57 @@
+package net.caffeinemc.mods.sodium.client.platform.windows.api;
+
+import net.caffeinemc.mods.sodium.client.platform.NativeWindowHandle;
+import org.jetbrains.annotations.Nullable;
+import org.lwjgl.system.JNI;
+import org.lwjgl.system.MemoryStack;
+import org.lwjgl.system.SharedLibrary;
+
+import java.util.Objects;
+
+import static org.lwjgl.system.APIUtil.apiCreateLibrary;
+import static org.lwjgl.system.APIUtil.apiGetFunctionAddressOptional;
+import static org.lwjgl.system.MemoryUtil.NULL;
+
+public class Shell32 {
+ private static final SharedLibrary LIBRARY = apiCreateLibrary("shell32");
+
+ private static final long PFN_ShellExecuteW = apiGetFunctionAddressOptional(LIBRARY, "ShellExecuteW");
+
+ public static void browseUrl(@Nullable NativeWindowHandle window, String url) {
+ Objects.requireNonNull(url, "URL parameter must be non-null");
+
+ try (var stack = MemoryStack.stackPush()) {
+ stack.nUTF16("open", true);
+ var lpOperation = stack.getPointerAddress();
+
+ stack.nUTF16(url, true);
+ var lpFile = stack.getPointerAddress();
+
+ nShellExecuteW(window != null ? window.getWin32Handle() : NULL,
+ lpOperation,
+ lpFile,
+ NULL,
+ NULL,
+ 0x1 /* SW_NORMAL */);
+ }
+ }
+
+ public static long nShellExecuteW(
+ /* HWND */ long hwnd,
+ /* LPCWSTR */ long lpOperation,
+ /* LPCWSTR */ long lpFile,
+ /* LPCWSTR */ long lpParameters,
+ /* LPCWSTR */ long lpDirectory,
+ /* INT */ int nShowCmd
+ ) {
+ return JNI.invokePPPPPP(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd, checkPfn(PFN_ShellExecuteW));
+ }
+
+ private static long checkPfn(long pfn) {
+ if (pfn == NULL) {
+ throw new NullPointerException("Function pointer not available");
+ }
+
+ return pfn;
+ }
+}
From e03e3d7be328c0f38079ed292eeed36fdaae0f9a Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Sun, 15 Dec 2024 19:09:22 -0600
Subject: [PATCH 035/215] Do not bake ambient lighting into cached per-face
light data
Fixes #2806
---
.../light/smooth/SmoothLightPipeline.java | 62 ++++++++++++++-----
1 file changed, 47 insertions(+), 15 deletions(-)
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java
index 781f5780c2..1cbe1b1014 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java
@@ -6,10 +6,10 @@
import net.caffeinemc.mods.sodium.client.model.light.data.QuadLightData;
import net.caffeinemc.mods.sodium.client.model.quad.ModelQuadView;
import net.caffeinemc.mods.sodium.client.model.quad.properties.ModelQuadFlags;
+import net.caffeinemc.mods.sodium.client.util.DirectionUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
-import net.minecraft.world.level.material.FluidState;
import org.joml.Vector3f;
/**
@@ -58,12 +58,23 @@ public class SmoothLightPipeline implements LightPipeline {
*/
private final float[] weights = new float[4];
+ // Cached per-face brightness received from the dimension's ambient lighting.
+ // This data is static for a given world and dimension.
+ private final float[] ambientBrightnessShaded = new float[6];
+ private final float[] ambientBrightnessUnshaded = new float[6];
+
public SmoothLightPipeline(LightDataAccess cache) {
this.lightCache = cache;
for (int i = 0; i < this.cachedFaceData.length; i++) {
this.cachedFaceData[i] = new AoFaceData();
}
+
+ for (Direction direction : DirectionUtil.ALL_DIRECTIONS) {
+ var level = cache.getLevel();
+ this.ambientBrightnessShaded[direction.ordinal()] = level.getShade(direction, true);
+ this.ambientBrightnessUnshaded[direction.ordinal()] = level.getShade(direction, false);
+ }
}
@Override
@@ -102,6 +113,8 @@ public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, Direc
private void applyAlignedFullFace(AoNeighborInfo neighborInfo, BlockPos pos, Direction dir, QuadLightData out, boolean shade) {
AoFaceData faceData = this.getCachedFaceData(pos, dir, true, shade);
neighborInfo.mapCorners(faceData.lm, faceData.ao, out.lm, out.br);
+
+ this.applyAmbientLighting(out.br, dir, shade);
}
/**
@@ -119,6 +132,8 @@ private void applyAlignedPartialFace(AoNeighborInfo neighborInfo, ModelQuadView
neighborInfo.calculateCornerWeights(cx, cy, cz, weights);
this.applyAlignedPartialFaceVertex(pos, dir, weights, i, out, true, shade);
}
+
+ this.applyAmbientLighting(out.br, dir, shade);
}
/**
@@ -150,6 +165,8 @@ private void applyParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad,
this.applyInsetPartialFaceVertex(pos, dir, depth, 1.0f - depth, weights, i, out, shade);
}
}
+
+ this.applyAmbientLighting(out.br, dir, shade);
}
/**
@@ -178,6 +195,8 @@ private void applyNonParallelFace(AoNeighborInfo neighborInfo, ModelQuadView qua
this.applyInsetPartialFaceVertex(pos, dir, depth, 1.0f - depth, weights, i, out, shade);
}
}
+
+ this.applyAmbientLighting(out.br, dir, shade);
}
private void applyAlignedPartialFaceVertex(BlockPos pos, Direction dir, float[] w, int i, QuadLightData out, boolean offset, boolean shade) {
@@ -257,7 +276,7 @@ private void applyIrregularFace(BlockPos blockPos, ModelQuadView quad, QuadLight
final AoFaceData fd = gatherInsetFace(quad, blockPos, i, face, shade);
AoNeighborInfo.get(face).calculateCornerWeights(quad.getX(i), quad.getY(i), quad.getZ(i), w);
final float n = x * x;
- final float a = fd.getBlendedShade(w);
+ final float a = fd.getBlendedShade(w) * this.getAmbientBrightness(face, shade);
final float s = fd.getBlendedSkyLight(w);
final float b = fd.getBlendedBlockLight(w);
ao += n * a;
@@ -275,7 +294,7 @@ private void applyIrregularFace(BlockPos blockPos, ModelQuadView quad, QuadLight
final AoFaceData fd = gatherInsetFace(quad, blockPos, i, face, shade);
AoNeighborInfo.get(face).calculateCornerWeights(quad.getX(i), quad.getY(i), quad.getZ(i), w);
final float n = y * y;
- final float a = fd.getBlendedShade(w);
+ final float a = fd.getBlendedShade(w) * this.getAmbientBrightness(face, shade);
final float s = fd.getBlendedSkyLight(w);
final float b = fd.getBlendedBlockLight(w);
ao += n * a;
@@ -293,7 +312,7 @@ private void applyIrregularFace(BlockPos blockPos, ModelQuadView quad, QuadLight
final AoFaceData fd = gatherInsetFace(quad, blockPos, i, face, shade);
AoNeighborInfo.get(face).calculateCornerWeights(quad.getX(i), quad.getY(i), quad.getZ(i), w);
final float n = z * z;
- final float a = fd.getBlendedShade(w);
+ final float a = fd.getBlendedShade(w) * this.getAmbientBrightness(face, shade);
final float s = fd.getBlendedSkyLight(w);
final float b = fd.getBlendedBlockLight(w);
ao += n * a;
@@ -309,29 +328,42 @@ private void applyIrregularFace(BlockPos blockPos, ModelQuadView quad, QuadLight
}
}
- private void applySidedBrightness(AoFaceData out, Direction face, boolean shade) {
- float brightness = this.lightCache.getLevel().getShade(face, shade);
- float[] ao = out.ao;
+ /**
+ * Applies the "ambient" lighting from the dimension to a quad that is parallel with the block grid.
+ * @param brightness The array of brightnesses for each quad vertex
+ * @param face The facing of the quad
+ * @param shade Whether the quad should receive directional lighting
+ */
+ private void applyAmbientLighting(final float[] brightness, Direction face, boolean shade) {
+ final float multiplier = this.getAmbientBrightness(face, shade);
- for (int i = 0; i < ao.length; i++) {
- ao[i] *= brightness;
+ for (int i = 0; i < brightness.length; i++) {
+ brightness[i] *= multiplier;
}
}
+ /**
+ * Returns the "ambient" brightness a block face receives in the world.
+ * @param face The block face
+ * @param shade Whether the block face is receiving directional light
+ */
+ private float getAmbientBrightness(Direction face, boolean shade) {
+ return (shade ? this.ambientBrightnessShaded : this.ambientBrightnessUnshaded)[face.ordinal()];
+ }
+
/**
* Returns the cached data for a given facing or calculates it if it hasn't been cached.
*/
private AoFaceData getCachedFaceData(BlockPos pos, Direction face, boolean offset, boolean shade) {
AoFaceData data = this.cachedFaceData[offset ? face.ordinal() : face.ordinal() + 6];
- if (!data.hasLightData()) {
- data.initLightData(this.lightCache, pos, face, offset);
-
- this.applySidedBrightness(data, face, shade);
-
- data.unpackLightData();
+ if (data.hasLightData()) {
+ return data;
}
+ data.initLightData(this.lightCache, pos, face, offset);
+ data.unpackLightData();
+
return data;
}
From 2ffcf5f13e916e883ad57b1b2ba12ef654ffb49c Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Tue, 17 Dec 2024 14:09:29 -0600
Subject: [PATCH 036/215] Switch to Parchment mappings 2024.11.17
---
buildSrc/src/main/kotlin/BuildConfig.kt | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt
index 7fb32a3250..3a585d8c1e 100644
--- a/buildSrc/src/main/kotlin/BuildConfig.kt
+++ b/buildSrc/src/main/kotlin/BuildConfig.kt
@@ -7,8 +7,7 @@ object BuildConfig {
val FABRIC_API_VERSION: String = "0.110.0+1.21.1"
// This value can be set to null to disable Parchment.
- // TODO: Re-add Parchment
- val PARCHMENT_VERSION: String? = null
+ val PARCHMENT_VERSION: String? = "2024.11.17"
// https://semver.org/
var MOD_VERSION: String = "0.6.3"
From e0c7108d20909648e762a6a5f600bbfc9d1e6b41 Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Tue, 17 Dec 2024 14:09:38 -0600
Subject: [PATCH 037/215] Bump version and dependencies
---
buildSrc/src/main/kotlin/BuildConfig.kt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt
index 3a585d8c1e..4cc7434b9f 100644
--- a/buildSrc/src/main/kotlin/BuildConfig.kt
+++ b/buildSrc/src/main/kotlin/BuildConfig.kt
@@ -2,7 +2,7 @@ import org.gradle.api.Project
object BuildConfig {
val MINECRAFT_VERSION: String = "1.21.1"
- val NEOFORGE_VERSION: String = "21.1.83"
+ val NEOFORGE_VERSION: String = "21.1.90"
val FABRIC_LOADER_VERSION: String = "0.16.9"
val FABRIC_API_VERSION: String = "0.110.0+1.21.1"
@@ -10,7 +10,7 @@ object BuildConfig {
val PARCHMENT_VERSION: String? = "2024.11.17"
// https://semver.org/
- var MOD_VERSION: String = "0.6.3"
+ var MOD_VERSION: String = "0.6.4"
fun createVersionString(project: Project): String {
val builder = StringBuilder()
From 05fa4de11025c1511ded0cda84cac853e01b89af Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Tue, 17 Dec 2024 15:37:50 -0600
Subject: [PATCH 038/215] Do not cache ambient brightness at initialization
The world may not be assigned to the renderer at
initialization, which is the case for non-terrain
rendering (i.e. block entities.)
Likely, there is no performance benefit to caching
this data in the first place, so the easiest solution
is to just remove the code.
---
.../model/light/smooth/SmoothLightPipeline.java | 15 ++-------------
1 file changed, 2 insertions(+), 13 deletions(-)
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java
index 1cbe1b1014..09f888520a 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/model/light/smooth/SmoothLightPipeline.java
@@ -6,7 +6,6 @@
import net.caffeinemc.mods.sodium.client.model.light.data.QuadLightData;
import net.caffeinemc.mods.sodium.client.model.quad.ModelQuadView;
import net.caffeinemc.mods.sodium.client.model.quad.properties.ModelQuadFlags;
-import net.caffeinemc.mods.sodium.client.util.DirectionUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
@@ -58,23 +57,12 @@ public class SmoothLightPipeline implements LightPipeline {
*/
private final float[] weights = new float[4];
- // Cached per-face brightness received from the dimension's ambient lighting.
- // This data is static for a given world and dimension.
- private final float[] ambientBrightnessShaded = new float[6];
- private final float[] ambientBrightnessUnshaded = new float[6];
-
public SmoothLightPipeline(LightDataAccess cache) {
this.lightCache = cache;
for (int i = 0; i < this.cachedFaceData.length; i++) {
this.cachedFaceData[i] = new AoFaceData();
}
-
- for (Direction direction : DirectionUtil.ALL_DIRECTIONS) {
- var level = cache.getLevel();
- this.ambientBrightnessShaded[direction.ordinal()] = level.getShade(direction, true);
- this.ambientBrightnessUnshaded[direction.ordinal()] = level.getShade(direction, false);
- }
}
@Override
@@ -348,7 +336,8 @@ private void applyAmbientLighting(final float[] brightness, Direction face, bool
* @param shade Whether the block face is receiving directional light
*/
private float getAmbientBrightness(Direction face, boolean shade) {
- return (shade ? this.ambientBrightnessShaded : this.ambientBrightnessUnshaded)[face.ordinal()];
+ return this.lightCache.getLevel()
+ .getShade(face, shade);
}
/**
From 3c33071353ad65a77791923b92156c93fb372bd3 Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Tue, 17 Dec 2024 15:40:06 -0600
Subject: [PATCH 039/215] Bump version to 0.6.5
---
buildSrc/src/main/kotlin/BuildConfig.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt
index 4cc7434b9f..5b521b97db 100644
--- a/buildSrc/src/main/kotlin/BuildConfig.kt
+++ b/buildSrc/src/main/kotlin/BuildConfig.kt
@@ -10,7 +10,7 @@ object BuildConfig {
val PARCHMENT_VERSION: String? = "2024.11.17"
// https://semver.org/
- var MOD_VERSION: String = "0.6.4"
+ var MOD_VERSION: String = "0.6.5"
fun createVersionString(project: Project): String {
val builder = StringBuilder()
From 04a72b83a68c309f6f38908600ae023f9588c78b Mon Sep 17 00:00:00 2001
From: muzikbike <52297970+muzikbike@users.noreply.github.com>
Date: Tue, 31 Dec 2024 18:48:50 +0000
Subject: [PATCH 040/215] Rename model texture references to match Vanilla
(#2958)
Custom models which extended these base models would not properly have their textures applied, as the texture references were accidentally changed.
---
.../minecraft/models/block/cauldron.json | 94 +++++++++----------
.../minecraft/models/block/composter.json | 31 +++---
.../models/block/template_cauldron_full.json | 94 +++++++++----------
.../block/template_cauldron_level1.json | 94 +++++++++----------
.../block/template_cauldron_level2.json | 94 +++++++++----------
5 files changed, 204 insertions(+), 203 deletions(-)
diff --git a/common/src/main/resources/assets/minecraft/models/block/cauldron.json b/common/src/main/resources/assets/minecraft/models/block/cauldron.json
index 3b18fff1ef..f1e0e005c2 100644
--- a/common/src/main/resources/assets/minecraft/models/block/cauldron.json
+++ b/common/src/main/resources/assets/minecraft/models/block/cauldron.json
@@ -1,21 +1,21 @@
{
"ambientocclusion": false,
"textures": {
- "rim": "block/cauldron_top",
+ "top": "block/cauldron_top",
"particle": "block/cauldron_side",
- "outside": "block/cauldron_side",
+ "side": "block/cauldron_side",
"inside": "block/cauldron_inner",
- "feet": "block/cauldron_bottom"
+ "bottom": "block/cauldron_bottom"
},
"elements": [
{
"from": [ 0, 3, 0 ],
"to": [ 16, 16, 16 ],
"faces": {
- "north": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "north" },
- "east": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "east" },
- "south": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "south" },
- "west": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "west" },
+ "north": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "north" },
+ "east": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "east" },
+ "south": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "south" },
+ "west": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "west" },
"down": { "uv": [ 0, 0, 16, 16 ], "texture": "#inside" }
}
},
@@ -23,56 +23,56 @@
"from": [ 0, 16, 0 ],
"to": [ 14, 16, 2 ],
"faces": {
- "up": { "uv": [ 0, 0, 14, 2 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 0, 0, 14, 2 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 14, 16, 0 ],
"to": [ 16, 16, 14 ],
"faces": {
- "up": { "uv": [ 14, 0, 16, 14 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 14, 0, 16, 14 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 2, 16, 14 ],
"to": [ 16, 16, 16 ],
"faces": {
- "up": { "uv": [ 2, 14, 16, 16 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 2, 14, 16, 16 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 0, 16, 2 ],
"to": [ 2, 16, 16 ],
"faces": {
- "up": { "uv": [ 0, 2, 2, 16 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 0, 2, 2, 16 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 2, 4, 2 ],
"to": [ 14, 16, 2 ],
"faces": {
- "south": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "south": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
"from": [ 14, 4, 2 ],
"to": [ 14, 16, 14 ],
"faces": {
- "west": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "west": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
"from": [ 2, 4, 14 ],
"to": [ 14, 16, 14 ],
"faces": {
- "north": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "north": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
"from": [ 2, 4, 2 ],
"to": [ 2, 16, 14 ],
"faces": {
- "east": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "east": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
@@ -86,128 +86,128 @@
"from": [ 0, 0, 0 ],
"to": [ 4, 3, 4 ],
"faces": {
- "north": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "north" },
- "west": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "west" }
+ "north": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "north" },
+ "west": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "west" }
}
},
{
"from": [ 0, 0, 12 ],
"to": [ 4, 3, 16 ],
"faces": {
- "south": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "south" },
- "west": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "west" }
+ "south": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "south" },
+ "west": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "west" }
}
},
{
"from": [ 12, 0, 12 ],
"to": [ 16, 3, 16 ],
"faces": {
- "east": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "east" },
- "south": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "south" }
+ "east": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "east" },
+ "south": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "south" }
}
},
{
"from": [ 12, 0, 0 ],
"to": [ 16, 3, 4 ],
"faces": {
- "north": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "north" },
- "east": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "east" }
+ "north": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "north" },
+ "east": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "east" }
}
},
{
"from": [ 14, 0, 2 ],
"to": [ 16, 3, 4 ],
"faces": {
- "south": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "west": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "down": { "uv": [ 14, 12, 16, 14 ], "texture": "#feet", "cullface": "down" }
+ "south": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "west": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "down": { "uv": [ 14, 12, 16, 14 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 2, 0, 0 ],
"to": [ 4, 3, 2 ],
"faces": {
- "east": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "south": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "down": { "uv": [ 2, 14, 4, 16 ], "texture": "#feet", "cullface": "down" }
+ "east": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "south": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "down": { "uv": [ 2, 14, 4, 16 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 0, 0, 12 ],
"to": [ 2, 3, 14 ],
"faces": {
- "north": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "east": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "down": { "uv": [ 0, 2, 2, 4 ], "texture": "#feet", "cullface": "down" }
+ "north": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "east": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "down": { "uv": [ 0, 2, 2, 4 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 12, 0, 14 ],
"to": [ 14, 3, 16 ],
"faces": {
- "north": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "west": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "down": { "uv": [ 12, 0, 14, 2 ], "texture": "#feet", "cullface": "down" }
+ "north": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "west": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "down": { "uv": [ 12, 0, 14, 2 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 12, 0, 0 ],
"to": [ 16, 0, 2 ],
"faces": {
- "down": { "uv": [ 12, 14, 16, 16 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 12, 14, 16, 16 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 0, 0, 0 ],
"to": [ 2, 0, 4 ],
"faces": {
- "down": { "uv": [ 0, 12, 2, 16 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 0, 12, 2, 16 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 0, 0, 14 ],
"to": [ 4, 0, 16 ],
"faces": {
- "down": { "uv": [ 0, 0, 4, 2 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 0, 0, 4, 2 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 14, 0, 12 ],
"to": [ 16, 0, 16 ],
"faces": {
- "down": { "uv": [ 14, 0, 16, 4 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 14, 0, 16, 4 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 12, 0, 0 ],
"to": [ 14, 3, 2 ],
"faces": {
- "south": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" },
- "west": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" }
+ "south": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" },
+ "west": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" }
}
},
{
"from": [ 0, 0, 2 ],
"to": [ 2, 3, 4 ],
"faces": {
- "east": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" },
- "south": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" }
+ "east": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" },
+ "south": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" }
}
},
{
"from": [ 2, 0, 14 ],
"to": [ 4, 3, 16 ],
"faces": {
- "north": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" },
- "east": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" }
+ "north": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" },
+ "east": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" }
}
},
{
"from": [ 14, 0, 12 ],
"to": [ 16, 3, 14 ],
"faces": {
- "north": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" },
- "west": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" }
+ "north": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" },
+ "west": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" }
}
}
]
diff --git a/common/src/main/resources/assets/minecraft/models/block/composter.json b/common/src/main/resources/assets/minecraft/models/block/composter.json
index 88af7aed12..0bccf7e940 100644
--- a/common/src/main/resources/assets/minecraft/models/block/composter.json
+++ b/common/src/main/resources/assets/minecraft/models/block/composter.json
@@ -1,9 +1,10 @@
{
"parent": "minecraft:block/block",
"textures": {
- "rim": "block/composter_top",
+ "top": "block/composter_top",
+ "bottom": "block/composter_bottom",
"particle": "block/composter_side",
- "outside": "block/composter_side",
+ "side": "block/composter_side",
"inside": "block/composter_bottom"
},
"elements": [
@@ -11,67 +12,67 @@
"from": [ 0, 0, 0 ],
"to": [ 16, 16, 16 ],
"faces": {
- "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#outside", "cullface": "north" },
- "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#outside", "cullface": "east" },
- "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#outside", "cullface": "south" },
- "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#outside", "cullface": "west" },
- "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#inside", "cullface": "down" }
+ "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "north" },
+ "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "east" },
+ "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "south" },
+ "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "west" },
+ "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 0, 16, 0 ],
"to": [ 14, 16, 2 ],
"faces": {
- "up": { "uv": [ 0, 0, 14, 2 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 0, 0, 14, 2 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 14, 16, 0 ],
"to": [ 16, 16, 14 ],
"faces": {
- "up": { "uv": [ 14, 0, 16, 14 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 14, 0, 16, 14 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 2, 16, 14 ],
"to": [ 16, 16, 16 ],
"faces": {
- "up": { "uv": [ 2, 14, 16, 16 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 2, 14, 16, 16 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 0, 16, 2 ],
"to": [ 2, 16, 16 ],
"faces": {
- "up": { "uv": [ 0, 2, 2, 16 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 0, 2, 2, 16 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 2, 2, 2 ],
"to": [ 14, 16, 2 ],
"faces": {
- "south": { "uv": [ 2, 0, 14, 14 ], "texture": "#outside" }
+ "south": { "uv": [ 2, 0, 14, 14 ], "texture": "#side" }
}
},
{
"from": [ 14, 2, 2 ],
"to": [ 14, 16, 14 ],
"faces": {
- "west": { "uv": [ 2, 0, 14, 14 ], "texture": "#outside" }
+ "west": { "uv": [ 2, 0, 14, 14 ], "texture": "#side" }
}
},
{
"from": [ 2, 2, 14 ],
"to": [ 14, 16, 14 ],
"faces": {
- "north": { "uv": [ 2, 0, 14, 14 ], "texture": "#outside" }
+ "north": { "uv": [ 2, 0, 14, 14 ], "texture": "#side" }
}
},
{
"from": [ 2, 2, 2 ],
"to": [ 2, 16, 14 ],
"faces": {
- "east": { "uv": [ 2, 0, 14, 14 ], "texture": "#outside" }
+ "east": { "uv": [ 2, 0, 14, 14 ], "texture": "#side" }
}
},
{
diff --git a/common/src/main/resources/assets/minecraft/models/block/template_cauldron_full.json b/common/src/main/resources/assets/minecraft/models/block/template_cauldron_full.json
index 8b090ec92a..98f15eb9f9 100644
--- a/common/src/main/resources/assets/minecraft/models/block/template_cauldron_full.json
+++ b/common/src/main/resources/assets/minecraft/models/block/template_cauldron_full.json
@@ -1,21 +1,21 @@
{
"ambientocclusion": false,
"textures": {
- "rim": "block/cauldron_top",
+ "top": "block/cauldron_top",
"particle": "block/cauldron_side",
- "outside": "block/cauldron_side",
+ "side": "block/cauldron_side",
"inside": "block/cauldron_inner",
- "feet": "block/cauldron_bottom"
+ "bottom": "block/cauldron_bottom"
},
"elements": [
{
"from": [ 0, 3, 0 ],
"to": [ 16, 16, 16 ],
"faces": {
- "north": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "north" },
- "east": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "east" },
- "south": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "south" },
- "west": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "west" },
+ "north": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "north" },
+ "east": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "east" },
+ "south": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "south" },
+ "west": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "west" },
"down": { "uv": [ 0, 0, 16, 16 ], "texture": "#inside" }
}
},
@@ -23,56 +23,56 @@
"from": [ 0, 16, 0 ],
"to": [ 14, 16, 2 ],
"faces": {
- "up": { "uv": [ 0, 0, 14, 2 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 0, 0, 14, 2 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 14, 16, 0 ],
"to": [ 16, 16, 14 ],
"faces": {
- "up": { "uv": [ 14, 0, 16, 14 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 14, 0, 16, 14 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 2, 16, 14 ],
"to": [ 16, 16, 16 ],
"faces": {
- "up": { "uv": [ 2, 14, 16, 16 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 2, 14, 16, 16 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 0, 16, 2 ],
"to": [ 2, 16, 16 ],
"faces": {
- "up": { "uv": [ 0, 2, 2, 16 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 0, 2, 2, 16 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 2, 4, 2 ],
"to": [ 14, 16, 2 ],
"faces": {
- "south": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "south": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
"from": [ 14, 4, 2 ],
"to": [ 14, 16, 14 ],
"faces": {
- "west": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "west": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
"from": [ 2, 4, 14 ],
"to": [ 14, 16, 14 ],
"faces": {
- "north": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "north": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
"from": [ 2, 4, 2 ],
"to": [ 2, 16, 14 ],
"faces": {
- "east": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "east": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
@@ -86,128 +86,128 @@
"from": [ 0, 0, 0 ],
"to": [ 4, 3, 4 ],
"faces": {
- "north": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "north" },
- "west": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "west" }
+ "north": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "north" },
+ "west": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "west" }
}
},
{
"from": [ 0, 0, 12 ],
"to": [ 4, 3, 16 ],
"faces": {
- "south": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "south" },
- "west": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "west" }
+ "south": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "south" },
+ "west": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "west" }
}
},
{
"from": [ 12, 0, 12 ],
"to": [ 16, 3, 16 ],
"faces": {
- "east": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "east" },
- "south": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "south" }
+ "east": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "east" },
+ "south": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "south" }
}
},
{
"from": [ 12, 0, 0 ],
"to": [ 16, 3, 4 ],
"faces": {
- "north": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "north" },
- "east": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "east" }
+ "north": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "north" },
+ "east": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "east" }
}
},
{
"from": [ 14, 0, 2 ],
"to": [ 16, 3, 4 ],
"faces": {
- "south": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "west": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "down": { "uv": [ 14, 12, 16, 14 ], "texture": "#feet", "cullface": "down" }
+ "south": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "west": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "down": { "uv": [ 14, 12, 16, 14 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 2, 0, 0 ],
"to": [ 4, 3, 2 ],
"faces": {
- "east": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "south": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "down": { "uv": [ 2, 14, 4, 16 ], "texture": "#feet", "cullface": "down" }
+ "east": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "south": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "down": { "uv": [ 2, 14, 4, 16 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 0, 0, 12 ],
"to": [ 2, 3, 14 ],
"faces": {
- "north": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "east": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "down": { "uv": [ 0, 2, 2, 4 ], "texture": "#feet", "cullface": "down" }
+ "north": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "east": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "down": { "uv": [ 0, 2, 2, 4 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 12, 0, 14 ],
"to": [ 14, 3, 16 ],
"faces": {
- "north": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "west": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "down": { "uv": [ 12, 0, 14, 2 ], "texture": "#feet", "cullface": "down" }
+ "north": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "west": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "down": { "uv": [ 12, 0, 14, 2 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 12, 0, 0 ],
"to": [ 16, 0, 2 ],
"faces": {
- "down": { "uv": [ 12, 14, 16, 16 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 12, 14, 16, 16 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 0, 0, 0 ],
"to": [ 2, 0, 4 ],
"faces": {
- "down": { "uv": [ 0, 12, 2, 16 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 0, 12, 2, 16 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 0, 0, 14 ],
"to": [ 4, 0, 16 ],
"faces": {
- "down": { "uv": [ 0, 0, 4, 2 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 0, 0, 4, 2 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 14, 0, 12 ],
"to": [ 16, 0, 16 ],
"faces": {
- "down": { "uv": [ 14, 0, 16, 4 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 14, 0, 16, 4 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 12, 0, 0 ],
"to": [ 14, 3, 2 ],
"faces": {
- "south": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" },
- "west": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" }
+ "south": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" },
+ "west": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" }
}
},
{
"from": [ 0, 0, 2 ],
"to": [ 2, 3, 4 ],
"faces": {
- "east": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" },
- "south": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" }
+ "east": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" },
+ "south": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" }
}
},
{
"from": [ 2, 0, 14 ],
"to": [ 4, 3, 16 ],
"faces": {
- "north": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" },
- "east": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" }
+ "north": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" },
+ "east": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" }
}
},
{
"from": [ 14, 0, 12 ],
"to": [ 16, 3, 14 ],
"faces": {
- "north": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" },
- "west": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" }
+ "north": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" },
+ "west": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" }
}
},
{
diff --git a/common/src/main/resources/assets/minecraft/models/block/template_cauldron_level1.json b/common/src/main/resources/assets/minecraft/models/block/template_cauldron_level1.json
index afea17757e..c04f6ba3ae 100644
--- a/common/src/main/resources/assets/minecraft/models/block/template_cauldron_level1.json
+++ b/common/src/main/resources/assets/minecraft/models/block/template_cauldron_level1.json
@@ -1,21 +1,21 @@
{
"ambientocclusion": false,
"textures": {
- "rim": "block/cauldron_top",
+ "top": "block/cauldron_top",
"particle": "block/cauldron_side",
- "outside": "block/cauldron_side",
+ "side": "block/cauldron_side",
"inside": "block/cauldron_inner",
- "feet": "block/cauldron_bottom"
+ "bottom": "block/cauldron_bottom"
},
"elements": [
{
"from": [ 0, 3, 0 ],
"to": [ 16, 16, 16 ],
"faces": {
- "north": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "north" },
- "east": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "east" },
- "south": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "south" },
- "west": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "west" },
+ "north": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "north" },
+ "east": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "east" },
+ "south": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "south" },
+ "west": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "west" },
"down": { "uv": [ 0, 0, 16, 16 ], "texture": "#inside" }
}
},
@@ -23,56 +23,56 @@
"from": [ 0, 16, 0 ],
"to": [ 14, 16, 2 ],
"faces": {
- "up": { "uv": [ 0, 0, 14, 2 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 0, 0, 14, 2 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 14, 16, 0 ],
"to": [ 16, 16, 14 ],
"faces": {
- "up": { "uv": [ 14, 0, 16, 14 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 14, 0, 16, 14 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 2, 16, 14 ],
"to": [ 16, 16, 16 ],
"faces": {
- "up": { "uv": [ 2, 14, 16, 16 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 2, 14, 16, 16 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 0, 16, 2 ],
"to": [ 2, 16, 16 ],
"faces": {
- "up": { "uv": [ 0, 2, 2, 16 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 0, 2, 2, 16 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 2, 4, 2 ],
"to": [ 14, 16, 2 ],
"faces": {
- "south": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "south": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
"from": [ 14, 4, 2 ],
"to": [ 14, 16, 14 ],
"faces": {
- "west": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "west": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
"from": [ 2, 4, 14 ],
"to": [ 14, 16, 14 ],
"faces": {
- "north": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "north": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
"from": [ 2, 4, 2 ],
"to": [ 2, 16, 14 ],
"faces": {
- "east": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "east": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
@@ -86,128 +86,128 @@
"from": [ 0, 0, 0 ],
"to": [ 4, 3, 4 ],
"faces": {
- "north": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "north" },
- "west": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "west" }
+ "north": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "north" },
+ "west": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "west" }
}
},
{
"from": [ 0, 0, 12 ],
"to": [ 4, 3, 16 ],
"faces": {
- "south": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "south" },
- "west": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "west" }
+ "south": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "south" },
+ "west": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "west" }
}
},
{
"from": [ 12, 0, 12 ],
"to": [ 16, 3, 16 ],
"faces": {
- "east": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "east" },
- "south": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "south" }
+ "east": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "east" },
+ "south": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "south" }
}
},
{
"from": [ 12, 0, 0 ],
"to": [ 16, 3, 4 ],
"faces": {
- "north": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "north" },
- "east": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "east" }
+ "north": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "north" },
+ "east": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "east" }
}
},
{
"from": [ 14, 0, 2 ],
"to": [ 16, 3, 4 ],
"faces": {
- "south": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "west": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "down": { "uv": [ 14, 12, 16, 14 ], "texture": "#feet", "cullface": "down" }
+ "south": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "west": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "down": { "uv": [ 14, 12, 16, 14 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 2, 0, 0 ],
"to": [ 4, 3, 2 ],
"faces": {
- "east": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "south": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "down": { "uv": [ 2, 14, 4, 16 ], "texture": "#feet", "cullface": "down" }
+ "east": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "south": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "down": { "uv": [ 2, 14, 4, 16 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 0, 0, 12 ],
"to": [ 2, 3, 14 ],
"faces": {
- "north": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "east": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "down": { "uv": [ 0, 2, 2, 4 ], "texture": "#feet", "cullface": "down" }
+ "north": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "east": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "down": { "uv": [ 0, 2, 2, 4 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 12, 0, 14 ],
"to": [ 14, 3, 16 ],
"faces": {
- "north": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "west": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "down": { "uv": [ 12, 0, 14, 2 ], "texture": "#feet", "cullface": "down" }
+ "north": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "west": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "down": { "uv": [ 12, 0, 14, 2 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 12, 0, 0 ],
"to": [ 16, 0, 2 ],
"faces": {
- "down": { "uv": [ 12, 14, 16, 16 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 12, 14, 16, 16 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 0, 0, 0 ],
"to": [ 2, 0, 4 ],
"faces": {
- "down": { "uv": [ 0, 12, 2, 16 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 0, 12, 2, 16 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 0, 0, 14 ],
"to": [ 4, 0, 16 ],
"faces": {
- "down": { "uv": [ 0, 0, 4, 2 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 0, 0, 4, 2 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 14, 0, 12 ],
"to": [ 16, 0, 16 ],
"faces": {
- "down": { "uv": [ 14, 0, 16, 4 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 14, 0, 16, 4 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 12, 0, 0 ],
"to": [ 14, 3, 2 ],
"faces": {
- "south": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" },
- "west": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" }
+ "south": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" },
+ "west": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" }
}
},
{
"from": [ 0, 0, 2 ],
"to": [ 2, 3, 4 ],
"faces": {
- "east": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" },
- "south": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" }
+ "east": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" },
+ "south": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" }
}
},
{
"from": [ 2, 0, 14 ],
"to": [ 4, 3, 16 ],
"faces": {
- "north": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" },
- "east": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" }
+ "north": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" },
+ "east": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" }
}
},
{
"from": [ 14, 0, 12 ],
"to": [ 16, 3, 14 ],
"faces": {
- "north": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" },
- "west": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" }
+ "north": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" },
+ "west": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" }
}
},
{
diff --git a/common/src/main/resources/assets/minecraft/models/block/template_cauldron_level2.json b/common/src/main/resources/assets/minecraft/models/block/template_cauldron_level2.json
index 63ee8c7596..ef4fce285d 100644
--- a/common/src/main/resources/assets/minecraft/models/block/template_cauldron_level2.json
+++ b/common/src/main/resources/assets/minecraft/models/block/template_cauldron_level2.json
@@ -1,21 +1,21 @@
{
"ambientocclusion": false,
"textures": {
- "rim": "block/cauldron_top",
+ "top": "block/cauldron_top",
"particle": "block/cauldron_side",
- "outside": "block/cauldron_side",
+ "side": "block/cauldron_side",
"inside": "block/cauldron_inner",
- "feet": "block/cauldron_bottom"
+ "bottom": "block/cauldron_bottom"
},
"elements": [
{
"from": [ 0, 3, 0 ],
"to": [ 16, 16, 16 ],
"faces": {
- "north": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "north" },
- "east": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "east" },
- "south": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "south" },
- "west": { "uv": [ 0, 0, 16, 13 ], "texture": "#outside", "cullface": "west" },
+ "north": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "north" },
+ "east": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "east" },
+ "south": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "south" },
+ "west": { "uv": [ 0, 0, 16, 13 ], "texture": "#side", "cullface": "west" },
"down": { "uv": [ 0, 0, 16, 16 ], "texture": "#inside" }
}
},
@@ -23,56 +23,56 @@
"from": [ 0, 16, 0 ],
"to": [ 14, 16, 2 ],
"faces": {
- "up": { "uv": [ 0, 0, 14, 2 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 0, 0, 14, 2 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 14, 16, 0 ],
"to": [ 16, 16, 14 ],
"faces": {
- "up": { "uv": [ 14, 0, 16, 14 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 14, 0, 16, 14 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 2, 16, 14 ],
"to": [ 16, 16, 16 ],
"faces": {
- "up": { "uv": [ 2, 14, 16, 16 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 2, 14, 16, 16 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 0, 16, 2 ],
"to": [ 2, 16, 16 ],
"faces": {
- "up": { "uv": [ 0, 2, 2, 16 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 0, 2, 2, 16 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 2, 4, 2 ],
"to": [ 14, 16, 2 ],
"faces": {
- "south": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "south": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
"from": [ 14, 4, 2 ],
"to": [ 14, 16, 14 ],
"faces": {
- "west": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "west": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
"from": [ 2, 4, 14 ],
"to": [ 14, 16, 14 ],
"faces": {
- "north": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "north": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
"from": [ 2, 4, 2 ],
"to": [ 2, 16, 14 ],
"faces": {
- "east": { "uv": [ 2, 0, 14, 12 ], "texture": "#outside" }
+ "east": { "uv": [ 2, 0, 14, 12 ], "texture": "#side" }
}
},
{
@@ -86,128 +86,128 @@
"from": [ 0, 0, 0 ],
"to": [ 4, 3, 4 ],
"faces": {
- "north": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "north" },
- "west": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "west" }
+ "north": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "north" },
+ "west": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "west" }
}
},
{
"from": [ 0, 0, 12 ],
"to": [ 4, 3, 16 ],
"faces": {
- "south": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "south" },
- "west": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "west" }
+ "south": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "south" },
+ "west": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "west" }
}
},
{
"from": [ 12, 0, 12 ],
"to": [ 16, 3, 16 ],
"faces": {
- "east": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "east" },
- "south": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "south" }
+ "east": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "east" },
+ "south": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "south" }
}
},
{
"from": [ 12, 0, 0 ],
"to": [ 16, 3, 4 ],
"faces": {
- "north": { "uv": [ 0, 13, 4, 16 ], "texture": "#outside", "cullface": "north" },
- "east": { "uv": [ 12, 13, 16, 16 ], "texture": "#outside", "cullface": "east" }
+ "north": { "uv": [ 0, 13, 4, 16 ], "texture": "#side", "cullface": "north" },
+ "east": { "uv": [ 12, 13, 16, 16 ], "texture": "#side", "cullface": "east" }
}
},
{
"from": [ 14, 0, 2 ],
"to": [ 16, 3, 4 ],
"faces": {
- "south": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "west": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "down": { "uv": [ 14, 12, 16, 14 ], "texture": "#feet", "cullface": "down" }
+ "south": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "west": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "down": { "uv": [ 14, 12, 16, 14 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 2, 0, 0 ],
"to": [ 4, 3, 2 ],
"faces": {
- "east": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "south": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "down": { "uv": [ 2, 14, 4, 16 ], "texture": "#feet", "cullface": "down" }
+ "east": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "south": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "down": { "uv": [ 2, 14, 4, 16 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 0, 0, 12 ],
"to": [ 2, 3, 14 ],
"faces": {
- "north": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "east": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "down": { "uv": [ 0, 2, 2, 4 ], "texture": "#feet", "cullface": "down" }
+ "north": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "east": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "down": { "uv": [ 0, 2, 2, 4 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 12, 0, 14 ],
"to": [ 14, 3, 16 ],
"faces": {
- "north": { "uv": [ 2, 13, 4, 16 ], "texture": "#outside" },
- "west": { "uv": [ 14, 13, 16, 16 ], "texture": "#outside" },
- "down": { "uv": [ 12, 0, 14, 2 ], "texture": "#feet", "cullface": "down" }
+ "north": { "uv": [ 2, 13, 4, 16 ], "texture": "#side" },
+ "west": { "uv": [ 14, 13, 16, 16 ], "texture": "#side" },
+ "down": { "uv": [ 12, 0, 14, 2 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 12, 0, 0 ],
"to": [ 16, 0, 2 ],
"faces": {
- "down": { "uv": [ 12, 14, 16, 16 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 12, 14, 16, 16 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 0, 0, 0 ],
"to": [ 2, 0, 4 ],
"faces": {
- "down": { "uv": [ 0, 12, 2, 16 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 0, 12, 2, 16 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 0, 0, 14 ],
"to": [ 4, 0, 16 ],
"faces": {
- "down": { "uv": [ 0, 0, 4, 2 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 0, 0, 4, 2 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 14, 0, 12 ],
"to": [ 16, 0, 16 ],
"faces": {
- "down": { "uv": [ 14, 0, 16, 4 ], "texture": "#feet", "cullface": "down" }
+ "down": { "uv": [ 14, 0, 16, 4 ], "texture": "#bottom", "cullface": "down" }
}
},
{
"from": [ 12, 0, 0 ],
"to": [ 14, 3, 2 ],
"faces": {
- "south": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" },
- "west": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" }
+ "south": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" },
+ "west": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" }
}
},
{
"from": [ 0, 0, 2 ],
"to": [ 2, 3, 4 ],
"faces": {
- "east": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" },
- "south": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" }
+ "east": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" },
+ "south": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" }
}
},
{
"from": [ 2, 0, 14 ],
"to": [ 4, 3, 16 ],
"faces": {
- "north": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" },
- "east": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" }
+ "north": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" },
+ "east": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" }
}
},
{
"from": [ 14, 0, 12 ],
"to": [ 16, 3, 14 ],
"faces": {
- "north": { "uv": [ 0, 13, 2, 16 ], "texture": "#outside" },
- "west": { "uv": [ 12, 13, 14, 16 ], "texture": "#outside" }
+ "north": { "uv": [ 0, 13, 2, 16 ], "texture": "#side" },
+ "west": { "uv": [ 12, 13, 14, 16 ], "texture": "#side" }
}
},
{
From 6f07a9c566e5083e8e5c660622d3916629fec0b4 Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Sun, 29 Dec 2024 17:07:50 -0600
Subject: [PATCH 041/215] Do not apply optimizations to sprites with special
tickers
---
.../chunk/compile/pipeline/BlockRenderer.java | 19 ++++++++---
.../pipeline/TextureAtlasSpriteExtension.java | 5 +++
.../scan/TextureAtlasSpriteMixin.java | 33 +++++++++++++++++++
.../main/resources/sodium-common.mixins.json | 1 +
4 files changed, 53 insertions(+), 5 deletions(-)
create mode 100644 common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/TextureAtlasSpriteExtension.java
create mode 100644 common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/scan/TextureAtlasSpriteMixin.java
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java
index 7f8e8ae031..66b941192c 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java
@@ -256,14 +256,23 @@ private boolean validateQuadUVs(TextureAtlasSprite atlasSprite) {
}
private static TerrainRenderPass getDowngradedPass(TextureAtlasSprite sprite, TerrainRenderPass pass) {
- if (sprite.contents() instanceof SpriteContentsExtension contents) {
- if (pass == DefaultTerrainRenderPasses.TRANSLUCENT && !contents.sodium$hasTranslucentPixels()) {
- pass = DefaultTerrainRenderPasses.CUTOUT;
+ if (sprite instanceof TextureAtlasSpriteExtension spriteExt) {
+ // Some mods may use a custom ticker which we cannot look into. To avoid problems with these mods,
+ // do not attempt to downgrade the render pass.
+ if (spriteExt.sodium$hasUnknownImageContents()) {
+ return pass;
}
- if (pass == DefaultTerrainRenderPasses.CUTOUT && !contents.sodium$hasTransparentPixels()) {
- pass = DefaultTerrainRenderPasses.SOLID;
+
+ if (sprite.contents() instanceof SpriteContentsExtension contentsExt) {
+ if (pass == DefaultTerrainRenderPasses.TRANSLUCENT && !contentsExt.sodium$hasTranslucentPixels()) {
+ pass = DefaultTerrainRenderPasses.CUTOUT;
+ }
+ if (pass == DefaultTerrainRenderPasses.CUTOUT && !contentsExt.sodium$hasTransparentPixels()) {
+ pass = DefaultTerrainRenderPasses.SOLID;
+ }
}
}
+
return pass;
}
}
\ No newline at end of file
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/TextureAtlasSpriteExtension.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/TextureAtlasSpriteExtension.java
new file mode 100644
index 0000000000..462de88a24
--- /dev/null
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/TextureAtlasSpriteExtension.java
@@ -0,0 +1,5 @@
+package net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline;
+
+public interface TextureAtlasSpriteExtension {
+ boolean sodium$hasUnknownImageContents();
+}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/scan/TextureAtlasSpriteMixin.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/scan/TextureAtlasSpriteMixin.java
new file mode 100644
index 0000000000..521c67bc60
--- /dev/null
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/scan/TextureAtlasSpriteMixin.java
@@ -0,0 +1,33 @@
+package net.caffeinemc.mods.sodium.mixin.features.textures.scan;
+
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline.TextureAtlasSpriteExtension;
+import net.minecraft.client.renderer.texture.SpriteContents;
+import net.minecraft.client.renderer.texture.SpriteTicker;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.At;
+
+@Mixin(TextureAtlasSprite.class)
+public class TextureAtlasSpriteMixin implements TextureAtlasSpriteExtension {
+ @Unique
+ private boolean hasUnknownImageContents;
+
+ @WrapOperation(method = "createTicker", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/texture/SpriteContents;createTicker()Lnet/minecraft/client/renderer/texture/SpriteTicker;"))
+ private SpriteTicker hookTickerInstantiation(SpriteContents instance, Operation original) {
+ var ticker = original.call(instance);
+
+ if (ticker != null && !(ticker instanceof SpriteContents.Ticker)) {
+ this.hasUnknownImageContents = true;
+ }
+
+ return ticker;
+ }
+
+ @Override
+ public boolean sodium$hasUnknownImageContents() {
+ return this.hasUnknownImageContents;
+ }
+}
diff --git a/common/src/main/resources/sodium-common.mixins.json b/common/src/main/resources/sodium-common.mixins.json
index a41962e84e..95a130bd95 100644
--- a/common/src/main/resources/sodium-common.mixins.json
+++ b/common/src/main/resources/sodium-common.mixins.json
@@ -87,6 +87,7 @@
"features.textures.mipmaps.MipmapGeneratorMixin",
"features.textures.mipmaps.SpriteContentsMixin",
"features.textures.scan.SpriteContentsMixin",
+ "features.textures.scan.TextureAtlasSpriteMixin",
"workarounds.context_creation.WindowMixin",
"workarounds.event_loop.RenderSystemMixin"
]
From 8188df6fe02ea060cc649080e484741f3dd35f25 Mon Sep 17 00:00:00 2001
From: Apollo <102649729+Apollounknowndev@users.noreply.github.com>
Date: Fri, 3 Jan 2025 23:23:47 -0500
Subject: [PATCH 042/215] Fixup model texture names for Hoppers (#2964)
---
.../main/resources/assets/minecraft/models/block/hopper.json | 4 ++--
.../resources/assets/minecraft/models/block/hopper_side.json | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/common/src/main/resources/assets/minecraft/models/block/hopper.json b/common/src/main/resources/assets/minecraft/models/block/hopper.json
index b1b655b3c9..89031c44a8 100644
--- a/common/src/main/resources/assets/minecraft/models/block/hopper.json
+++ b/common/src/main/resources/assets/minecraft/models/block/hopper.json
@@ -1,9 +1,9 @@
{
"ambientocclusion": false,
"textures": {
- "rim": "block/hopper_top",
+ "top": "block/hopper_top",
"particle": "block/hopper_outside",
- "outside": "block/hopper_outside",
+ "side": "block/hopper_outside",
"inside": "block/hopper_inside"
},
"elements": [
diff --git a/common/src/main/resources/assets/minecraft/models/block/hopper_side.json b/common/src/main/resources/assets/minecraft/models/block/hopper_side.json
index 10667bdac5..06de0dbb26 100644
--- a/common/src/main/resources/assets/minecraft/models/block/hopper_side.json
+++ b/common/src/main/resources/assets/minecraft/models/block/hopper_side.json
@@ -1,9 +1,9 @@
{
"ambientocclusion": false,
"textures": {
- "rim": "block/hopper_top",
+ "top": "block/hopper_top",
"particle": "block/hopper_outside",
- "outside": "block/hopper_outside",
+ "side": "block/hopper_outside",
"inside": "block/hopper_inside"
},
"elements": [
From 145921c676aa6cedcaa2f981cd4d9aee190ed7c3 Mon Sep 17 00:00:00 2001
From: lowercasebtw <126462578+lowercasebtw@users.noreply.github.com>
Date: Sat, 4 Jan 2025 15:53:14 -0600
Subject: [PATCH 043/215] Rewrite injections in ItemRendererMixin to be less
invasive (#2968)
---
.../render/vertex/VertexConsumerUtils.java | 4 +-
.../render/model/item/ItemRendererMixin.java | 80 +++++++++----------
2 files changed, 42 insertions(+), 42 deletions(-)
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/vertex/VertexConsumerUtils.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/vertex/VertexConsumerUtils.java
index 6118d3df41..978da79efd 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/vertex/VertexConsumerUtils.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/vertex/VertexConsumerUtils.java
@@ -3,6 +3,8 @@
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.caffeinemc.mods.sodium.api.vertex.buffer.VertexBufferWriter;
+import javax.annotation.Nullable;
+
public class VertexConsumerUtils {
/**
* Attempt to convert a {@link VertexConsumer} into a {@link VertexBufferWriter}. If this fails, return null
@@ -10,7 +12,7 @@ public class VertexConsumerUtils {
* @param consumer the consumer to convert
* @return a {@link VertexBufferWriter}, or null if the consumer does not support this
*/
- public static VertexBufferWriter convertOrLog(VertexConsumer consumer) {
+ public static @Nullable VertexBufferWriter convertOrLog(VertexConsumer consumer) {
VertexBufferWriter writer = VertexBufferWriter.tryOf(consumer);
if (writer == null) {
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/item/ItemRendererMixin.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/item/ItemRendererMixin.java
index a3b15c4252..8ea16da500 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/item/ItemRendererMixin.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/item/ItemRendererMixin.java
@@ -1,28 +1,29 @@
package net.caffeinemc.mods.sodium.mixin.features.render.model.item;
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.blaze3d.vertex.VertexConsumer;
+import net.caffeinemc.mods.sodium.api.util.ColorARGB;
+import net.caffeinemc.mods.sodium.api.vertex.buffer.VertexBufferWriter;
import net.caffeinemc.mods.sodium.client.model.quad.BakedQuadView;
import net.caffeinemc.mods.sodium.client.render.immediate.model.BakedModelEncoder;
import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.client.render.vertex.VertexConsumerUtils;
-import net.caffeinemc.mods.sodium.client.model.color.interop.ItemColorsExtension;
import net.caffeinemc.mods.sodium.client.util.DirectionUtil;
-import net.caffeinemc.mods.sodium.api.util.ColorARGB;
-import net.caffeinemc.mods.sodium.api.vertex.buffer.VertexBufferWriter;
-import net.minecraft.client.color.item.ItemColor;
import net.minecraft.client.color.item.ItemColors;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.entity.ItemRenderer;
-import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.Direction;
import net.minecraft.util.RandomSource;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.levelgen.SingleThreadedRandomSource;
-import org.spongepowered.asm.mixin.*;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import com.mojang.blaze3d.vertex.PoseStack;
-import com.mojang.blaze3d.vertex.VertexConsumer;
+
import java.util.List;
@Mixin(ItemRenderer.class)
@@ -35,48 +36,45 @@ public class ItemRendererMixin {
private ItemColors itemColors;
/**
- * @reason Avoid allocations
- * @author JellySquid
+ * @reason Avoid Allocations
+ * @return JellySquid
*/
- @Inject(method = "renderModelLists", at = @At("HEAD"), cancellable = true)
- private void renderModelFast(BakedModel model, ItemStack itemStack, int light, int overlay, PoseStack matrixStack, VertexConsumer vertexConsumer, CallbackInfo ci) {
+ @WrapOperation(method = "renderModelLists", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/RandomSource;create()Lnet/minecraft/util/RandomSource;"))
+ private RandomSource renderModelFastRandom(Operation original) {
+ return this.random;
+ }
+
+ /**
+ * @reason Avoid Allocations
+ * @return JellySquid
+ */
+ @WrapOperation(method = "renderModelLists", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/Direction;values()[Lnet/minecraft/core/Direction;"))
+ private Direction[] renderModelFastDirections(Operation original) {
+ return DirectionUtil.ALL_DIRECTIONS;
+ }
+
+ /**
+ * @reason Avoid Allocations
+ * @return JellySquid
+ */
+ @WrapOperation(method = "renderModelLists", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/ItemRenderer;renderQuadList(Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;Ljava/util/List;Lnet/minecraft/world/item/ItemStack;II)V"))
+ private void renderModelFast(ItemRenderer itemRenderer, PoseStack poseStack, VertexConsumer vertexConsumer, List quads, ItemStack itemStack, int light, int overlay, Operation original) {
var writer = VertexConsumerUtils.convertOrLog(vertexConsumer);
if (writer == null) {
+ original.call(itemRenderer, poseStack, vertexConsumer, quads, itemStack, light, overlay);
return;
}
- ci.cancel();
-
- RandomSource random = this.random;
- PoseStack.Pose matrices = matrixStack.last();
-
- ItemColor colorProvider = null;
-
- if (!itemStack.isEmpty()) {
- colorProvider = ((ItemColorsExtension) this.itemColors).sodium$getColorProvider(itemStack);
- }
-
- for (Direction direction : DirectionUtil.ALL_DIRECTIONS) {
- random.setSeed(42L);
- List quads = model.getQuads(null, direction, random);
-
- if (!quads.isEmpty()) {
- this.renderBakedItemQuads(matrices, writer, quads, itemStack, colorProvider, light, overlay);
- }
- }
-
- random.setSeed(42L);
- List quads = model.getQuads(null, null, random);
-
+ // TODO/NOTE: Should .last be a LocalRef?
if (!quads.isEmpty()) {
- this.renderBakedItemQuads(matrices, writer, quads, itemStack, colorProvider, light, overlay);
+ this.renderBakedItemQuads(poseStack.last(), writer, quads, itemStack, light, overlay);
}
}
@Unique
@SuppressWarnings("ForLoopReplaceableByForEach")
- private void renderBakedItemQuads(PoseStack.Pose matrices, VertexBufferWriter writer, List quads, ItemStack itemStack, ItemColor colorProvider, int light, int overlay) {
+ private void renderBakedItemQuads(PoseStack.Pose matrices, VertexBufferWriter writer, List quads, ItemStack itemStack, int light, int overlay) {
for (int i = 0; i < quads.size(); i++) {
BakedQuad bakedQuad = quads.get(i);
@@ -88,8 +86,8 @@ private void renderBakedItemQuads(PoseStack.Pose matrices, VertexBufferWriter wr
int color = 0xFFFFFFFF;
- if (colorProvider != null && quad.hasColor()) {
- color = ColorARGB.toABGR((colorProvider.getColor(itemStack, quad.getColorIndex())));
+ if (quad.hasColor()) {
+ color = ColorARGB.toABGR((this.itemColors.getColor(itemStack, quad.getColorIndex())));
}
BakedModelEncoder.writeQuadVertices(writer, matrices, quad, color, light, overlay, BakedModelEncoder.shouldMultiplyAlpha());
From 42aea7e6ddbad27d36d64af4d44374679f9001e5 Mon Sep 17 00:00:00 2001
From: douira
Date: Sat, 4 Jan 2025 22:53:37 +0100
Subject: [PATCH 044/215] Fix invalid texture name in Hopper model (#2966)
---
.../assets/minecraft/models/block/hopper.json | 40 +++++++++----------
.../minecraft/models/block/hopper_side.json | 40 +++++++++----------
2 files changed, 40 insertions(+), 40 deletions(-)
diff --git a/common/src/main/resources/assets/minecraft/models/block/hopper.json b/common/src/main/resources/assets/minecraft/models/block/hopper.json
index 89031c44a8..a28b8f787e 100644
--- a/common/src/main/resources/assets/minecraft/models/block/hopper.json
+++ b/common/src/main/resources/assets/minecraft/models/block/hopper.json
@@ -11,10 +11,10 @@
"from": [ 6, 0, 6 ],
"to": [ 10, 4, 10 ],
"faces": {
- "north": { "uv": [ 6, 12, 10, 16 ], "texture": "#outside" },
- "east": { "uv": [ 6, 12, 10, 16 ], "texture": "#outside" },
- "south": { "uv": [ 6, 12, 10, 16 ], "texture": "#outside" },
- "west": { "uv": [ 6, 12, 10, 16 ], "texture": "#outside" },
+ "north": { "uv": [ 6, 12, 10, 16 ], "texture": "#side" },
+ "east": { "uv": [ 6, 12, 10, 16 ], "texture": "#side" },
+ "south": { "uv": [ 6, 12, 10, 16 ], "texture": "#side" },
+ "west": { "uv": [ 6, 12, 10, 16 ], "texture": "#side" },
"down": { "uv": [ 6, 6, 10, 10 ], "texture": "#inside", "cullface": "down" }
}
},
@@ -22,10 +22,10 @@
"from": [ 4, 4, 4 ],
"to": [ 12, 10, 12 ],
"faces": {
- "north": { "uv": [ 4, 6, 12, 12 ], "texture": "#outside" },
- "east": { "uv": [ 4, 6, 12, 12 ], "texture": "#outside" },
- "south": { "uv": [ 4, 6, 12, 12 ], "texture": "#outside" },
- "west": { "uv": [ 4, 6, 12, 12 ], "texture": "#outside" },
+ "north": { "uv": [ 4, 6, 12, 12 ], "texture": "#side" },
+ "east": { "uv": [ 4, 6, 12, 12 ], "texture": "#side" },
+ "south": { "uv": [ 4, 6, 12, 12 ], "texture": "#side" },
+ "west": { "uv": [ 4, 6, 12, 12 ], "texture": "#side" },
"down": { "uv": [ 4, 4, 12, 12 ], "texture": "#inside" }
}
},
@@ -33,10 +33,10 @@
"from": [ 0, 10, 0 ],
"to": [ 16, 16, 16 ],
"faces": {
- "north": { "uv": [ 0, 0, 16, 6 ], "texture": "#outside", "cullface": "north" },
- "east": { "uv": [ 0, 0, 16, 6 ], "texture": "#outside", "cullface": "east" },
- "south": { "uv": [ 0, 0, 16, 6 ], "texture": "#outside", "cullface": "south" },
- "west": { "uv": [ 0, 0, 16, 6 ], "texture": "#outside", "cullface": "west" },
+ "north": { "uv": [ 0, 0, 16, 6 ], "texture": "#side", "cullface": "north" },
+ "east": { "uv": [ 0, 0, 16, 6 ], "texture": "#side", "cullface": "east" },
+ "south": { "uv": [ 0, 0, 16, 6 ], "texture": "#side", "cullface": "south" },
+ "west": { "uv": [ 0, 0, 16, 6 ], "texture": "#side", "cullface": "west" },
"down": { "uv": [ 0, 0, 16, 16 ], "texture": "#inside" }
}
},
@@ -44,56 +44,56 @@
"from": [ 0, 16, 0 ],
"to": [ 14, 16, 2 ],
"faces": {
- "up": { "uv": [ 0, 0, 14, 2 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 0, 0, 14, 2 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 14, 16, 0 ],
"to": [ 16, 16, 14 ],
"faces": {
- "up": { "uv": [ 14, 0, 16, 14 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 14, 0, 16, 14 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 2, 16, 14 ],
"to": [ 16, 16, 16 ],
"faces": {
- "up": { "uv": [ 2, 14, 16, 16 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 2, 14, 16, 16 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 0, 16, 2 ],
"to": [ 2, 16, 16 ],
"faces": {
- "up": { "uv": [ 0, 2, 2, 16 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 0, 2, 2, 16 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 2, 11, 2 ],
"to": [ 14, 16, 2 ],
"faces": {
- "south": { "uv": [ 2, 0, 14, 5 ], "texture": "#outside", "cullface": "up" }
+ "south": { "uv": [ 2, 0, 14, 5 ], "texture": "#side", "cullface": "up" }
}
},
{
"from": [ 14, 11, 2 ],
"to": [ 14, 16, 14 ],
"faces": {
- "west": { "uv": [ 2, 0, 14, 5 ], "texture": "#outside", "cullface": "up" }
+ "west": { "uv": [ 2, 0, 14, 5 ], "texture": "#side", "cullface": "up" }
}
},
{
"from": [ 2, 11, 14 ],
"to": [ 14, 16, 14 ],
"faces": {
- "north": { "uv": [ 2, 0, 14, 5 ], "texture": "#outside", "cullface": "up" }
+ "north": { "uv": [ 2, 0, 14, 5 ], "texture": "#side", "cullface": "up" }
}
},
{
"from": [ 2, 11, 2 ],
"to": [ 2, 16, 14 ],
"faces": {
- "east": { "uv": [ 2, 0, 14, 5 ], "texture": "#outside", "cullface": "up" }
+ "east": { "uv": [ 2, 0, 14, 5 ], "texture": "#side", "cullface": "up" }
}
},
{
diff --git a/common/src/main/resources/assets/minecraft/models/block/hopper_side.json b/common/src/main/resources/assets/minecraft/models/block/hopper_side.json
index 06de0dbb26..21973342ad 100644
--- a/common/src/main/resources/assets/minecraft/models/block/hopper_side.json
+++ b/common/src/main/resources/assets/minecraft/models/block/hopper_side.json
@@ -11,10 +11,10 @@
"from": [ 6, 4, 0 ],
"to": [ 10, 8, 4 ],
"faces": {
- "north": { "uv": [ 6, 8, 10, 12 ], "texture": "#outside", "cullface": "north" },
- "east": { "uv": [ 12, 8, 16, 12 ], "texture": "#outside" },
- "west": { "uv": [ 0, 8, 4, 12 ], "texture": "#outside" },
- "up": { "uv": [ 6, 0, 10, 4 ], "texture": "#outside" },
+ "north": { "uv": [ 6, 8, 10, 12 ], "texture": "#side", "cullface": "north" },
+ "east": { "uv": [ 12, 8, 16, 12 ], "texture": "#side" },
+ "west": { "uv": [ 0, 8, 4, 12 ], "texture": "#side" },
+ "up": { "uv": [ 6, 0, 10, 4 ], "texture": "#side" },
"down": { "uv": [ 6, 12, 10, 16 ], "texture": "#inside" }
}
},
@@ -22,10 +22,10 @@
"from": [ 4, 4, 4 ],
"to": [ 12, 10, 12 ],
"faces": {
- "north": { "uv": [ 4, 6, 12, 12 ], "texture": "#outside" },
- "east": { "uv": [ 4, 6, 12, 12 ], "texture": "#outside" },
- "south": { "uv": [ 4, 6, 12, 12 ], "texture": "#outside" },
- "west": { "uv": [ 4, 6, 12, 12 ], "texture": "#outside" },
+ "north": { "uv": [ 4, 6, 12, 12 ], "texture": "#side" },
+ "east": { "uv": [ 4, 6, 12, 12 ], "texture": "#side" },
+ "south": { "uv": [ 4, 6, 12, 12 ], "texture": "#side" },
+ "west": { "uv": [ 4, 6, 12, 12 ], "texture": "#side" },
"down": { "uv": [ 4, 4, 12, 12 ], "texture": "#inside" }
}
},
@@ -33,10 +33,10 @@
"from": [ 0, 10, 0 ],
"to": [ 16, 16, 16 ],
"faces": {
- "north": { "uv": [ 0, 0, 16, 6 ], "texture": "#outside", "cullface": "north" },
- "east": { "uv": [ 0, 0, 16, 6 ], "texture": "#outside", "cullface": "east" },
- "south": { "uv": [ 0, 0, 16, 6 ], "texture": "#outside", "cullface": "south" },
- "west": { "uv": [ 0, 0, 16, 6 ], "texture": "#outside", "cullface": "west" },
+ "north": { "uv": [ 0, 0, 16, 6 ], "texture": "#side", "cullface": "north" },
+ "east": { "uv": [ 0, 0, 16, 6 ], "texture": "#side", "cullface": "east" },
+ "south": { "uv": [ 0, 0, 16, 6 ], "texture": "#side", "cullface": "south" },
+ "west": { "uv": [ 0, 0, 16, 6 ], "texture": "#side", "cullface": "west" },
"down": { "uv": [ 0, 0, 16, 16 ], "texture": "#inside" }
}
},
@@ -44,56 +44,56 @@
"from": [ 0, 16, 0 ],
"to": [ 14, 16, 2 ],
"faces": {
- "up": { "uv": [ 0, 0, 14, 2 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 0, 0, 14, 2 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 14, 16, 0 ],
"to": [ 16, 16, 14 ],
"faces": {
- "up": { "uv": [ 14, 0, 16, 14 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 14, 0, 16, 14 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 2, 16, 14 ],
"to": [ 16, 16, 16 ],
"faces": {
- "up": { "uv": [ 2, 14, 16, 16 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 2, 14, 16, 16 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 0, 16, 2 ],
"to": [ 2, 16, 16 ],
"faces": {
- "up": { "uv": [ 0, 2, 2, 16 ], "texture": "#rim", "cullface": "up" }
+ "up": { "uv": [ 0, 2, 2, 16 ], "texture": "#top", "cullface": "up" }
}
},
{
"from": [ 2, 11, 2 ],
"to": [ 14, 16, 2 ],
"faces": {
- "south": { "uv": [ 2, 0, 14, 5 ], "texture": "#outside", "cullface": "up" }
+ "south": { "uv": [ 2, 0, 14, 5 ], "texture": "#side", "cullface": "up" }
}
},
{
"from": [ 14, 11, 2 ],
"to": [ 14, 16, 14 ],
"faces": {
- "west": { "uv": [ 2, 0, 14, 5 ], "texture": "#outside", "cullface": "up" }
+ "west": { "uv": [ 2, 0, 14, 5 ], "texture": "#side", "cullface": "up" }
}
},
{
"from": [ 2, 11, 14 ],
"to": [ 14, 16, 14 ],
"faces": {
- "north": { "uv": [ 2, 0, 14, 5 ], "texture": "#outside", "cullface": "up" }
+ "north": { "uv": [ 2, 0, 14, 5 ], "texture": "#side", "cullface": "up" }
}
},
{
"from": [ 2, 11, 2 ],
"to": [ 2, 16, 14 ],
"faces": {
- "east": { "uv": [ 2, 0, 14, 5 ], "texture": "#outside", "cullface": "up" }
+ "east": { "uv": [ 2, 0, 14, 5 ], "texture": "#side", "cullface": "up" }
}
},
{
From a93f1d29c7a338d01193b5d486da1dde3d493cd4 Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Mon, 6 Jan 2025 12:10:25 -0600
Subject: [PATCH 045/215] Use correct pointer shifts on 32-bit platforms
This fixes rendering glitches in translucent render passes
when using a 32-bit runtime/operating system.
---
.../sodium/client/render/chunk/DefaultChunkRenderer.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java
index e273e61744..1d1165c705 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java
@@ -25,6 +25,7 @@
import net.caffeinemc.mods.sodium.client.util.BitwiseMath;
import net.caffeinemc.mods.sodium.client.util.UInt32;
import org.lwjgl.system.MemoryUtil;
+import org.lwjgl.system.Pointer;
import java.util.Iterator;
@@ -172,7 +173,7 @@ private static void addNonIndexedDrawCommands(MultiDrawBatch batch, long pMeshDa
// Uint32 -> Int32 cast is always safe and should be optimized away
MemoryUtil.memPutInt(pBaseVertex + (size << 2), (int) SectionRenderDataUnsafe.getVertexOffset(pMeshData, facing));
MemoryUtil.memPutInt(pElementCount + (size << 2), (int) SectionRenderDataUnsafe.getElementCount(pMeshData, facing));
- MemoryUtil.memPutAddress(pElementPointer + (size << 3), 0 /* using a shared index buffer */);
+ MemoryUtil.memPutAddress(pElementPointer + (size << Pointer.POINTER_SHIFT), 0 /* using a shared index buffer */);
size += (mask >> facing) & 1;
}
@@ -204,7 +205,7 @@ private static void addIndexedDrawCommands(MultiDrawBatch batch, long pMeshData,
// * 4 to convert to bytes (the index buffer contains integers)
// the section render data storage for the indices stores the offset in indices (also called elements)
- MemoryUtil.memPutAddress(pElementPointer + (size << 3), elementOffset << 2);
+ MemoryUtil.memPutAddress(pElementPointer + (size << Pointer.POINTER_SHIFT), elementOffset << 2);
// adding the number of elements works because the index data has one index per element (which are the indices)
elementOffset += elementCount;
From ecf166b5ee368ac339ae8d84b2e559908ca6f4ab Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Fri, 17 Jan 2025 20:14:25 -0600
Subject: [PATCH 046/215] Try to handle exceptions during block entity
iteration
Other mods are mutating the block entity list from other threads
and violating memory safety. This often causes crashes when
we iterate over the list, and it's *very* difficult for the average
user to understand why it's happening.
To address the problem, this patch wraps the iterator, and
wraps any uncaught exception so it can be handled by the
caller.
If known-problematic mods are installed, a more helpful
error message will be shown to the user instead of the current
cryptic message.
---
.../client/util/iterator/WrappedIterator.java | 39 +++++++++++++++
.../world/cloned/ClonedChunkSection.java | 48 ++++++++++++++-----
2 files changed, 74 insertions(+), 13 deletions(-)
create mode 100644 common/src/main/java/net/caffeinemc/mods/sodium/client/util/iterator/WrappedIterator.java
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/util/iterator/WrappedIterator.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/util/iterator/WrappedIterator.java
new file mode 100644
index 0000000000..02543ffdfb
--- /dev/null
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/util/iterator/WrappedIterator.java
@@ -0,0 +1,39 @@
+package net.caffeinemc.mods.sodium.client.util.iterator;
+
+import java.util.Iterator;
+
+public class WrappedIterator implements Iterator {
+ private final Iterator delegate;
+
+ private WrappedIterator(Iterator delegate) {
+ this.delegate = delegate;
+ }
+
+ public static WrappedIterator create(Iterable iterable) {
+ return new WrappedIterator<>(iterable.iterator());
+ }
+
+ @Override
+ public boolean hasNext() {
+ try {
+ return this.delegate.hasNext();
+ } catch (Throwable t) {
+ throw new Exception("Iterator#hasNext() threw unhandled exception", t);
+ }
+ }
+
+ @Override
+ public T next() {
+ try {
+ return this.delegate.next();
+ } catch (Throwable t) {
+ throw new Exception("Iterator#next() threw unhandled exception", t);
+ }
+ }
+
+ public static class Exception extends RuntimeException {
+ private Exception(String message, Throwable t) {
+ super(message, t);
+ }
+ }
+}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/world/cloned/ClonedChunkSection.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/world/cloned/ClonedChunkSection.java
index 6390b26921..b1eff5852c 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/world/cloned/ClonedChunkSection.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/world/cloned/ClonedChunkSection.java
@@ -4,10 +4,10 @@
import it.unimi.dsi.fastutil.ints.Int2ReferenceMaps;
import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
import net.caffeinemc.mods.sodium.client.services.*;
-import net.caffeinemc.mods.sodium.client.world.PalettedContainerROExtension;
+import net.caffeinemc.mods.sodium.client.util.iterator.WrappedIterator;
import net.caffeinemc.mods.sodium.client.world.LevelSlice;
+import net.caffeinemc.mods.sodium.client.world.PalettedContainerROExtension;
import net.caffeinemc.mods.sodium.client.world.SodiumAuxiliaryLightManager;
-import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.SectionPos;
import net.minecraft.world.level.Level;
@@ -17,18 +17,12 @@
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
-import net.minecraft.world.level.chunk.DataLayer;
-import net.minecraft.world.level.chunk.LevelChunk;
-import net.minecraft.world.level.chunk.LevelChunkSection;
-import net.minecraft.world.level.chunk.PalettedContainer;
-import net.minecraft.world.level.chunk.PalettedContainerRO;
+import net.minecraft.world.level.chunk.*;
import net.minecraft.world.level.levelgen.DebugLevelSource;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.Map;
-
public class ClonedChunkSection {
private static final DataLayer DEFAULT_SKY_LIGHT_ARRAY = new DataLayer(15);
private static final DataLayer DEFAULT_BLOCK_LIGHT_ARRAY = new DataLayer(0);
@@ -67,7 +61,7 @@ public ClonedChunkSection(Level level, LevelChunk chunk, @Nullable LevelChunkSec
} else {
blockData = constructDebugWorldContainer(pos);
}
- blockEntityMap = copyBlockEntities(chunk, pos);
+ blockEntityMap = tryCopyBlockEntities(chunk, pos);
if (blockEntityMap != null && PlatformBlockAccess.getInstance().platformHasBlockData()) {
blockEntityRenderDataMap = copyBlockEntityRenderData(level, blockEntityMap);
}
@@ -150,6 +144,30 @@ private static DataLayer copyLightArray(Level level, LightLayer type, SectionPos
return array;
}
+ @Nullable
+ private static Int2ReferenceMap tryCopyBlockEntities(LevelChunk chunk, SectionPos chunkCoord) {
+ try {
+ // Some mods are violating memory safety, and the block entity iterator occasionally returns garbage results
+ // or otherwise throws exceptions because of this. To better diagnose these crashes, wrap the iterator
+ // so that we can handle any uncaught exceptions with the following special case.
+ return copyBlockEntities(chunk, chunkCoord);
+ } catch (WrappedIterator.Exception t) {
+ // Very infrequent check, only going to be called on game crash. Don't bother caching this.
+ if (PlatformRuntimeInformation.getInstance().isModInLoadingList("entityculling")) {
+ // The Entity Culling mod is known to mangle the block entity set, so try to attribute it directly
+ // if we know it's installed. Yes, this is accusatory, but we are tired of these cryptic crashes,
+ // and users need more information about how to resolve the problem themselves. This was the
+ // second-best option to outright preventing the launch of Sodium when Entity Culling is installed.
+ throw new RuntimeException("Failed to iterate block entities! This is *very likely* the fault of the " +
+ "Entity Culling mod, and cannot be fixed by Sodium. See here for more details: " +
+ "https://link.caffeinemc.net/help/sodium/mod-issue/entity-culling/gh-2985", t);
+ } else {
+ throw new RuntimeException("Failed to iterate block entities! This is *very likely* the fault of " +
+ "another misbehaving mod, not Sodium. Please check your mods list.", t);
+ }
+ }
+ }
+
@Nullable
private static Int2ReferenceMap copyBlockEntities(LevelChunk chunk, SectionPos chunkCoord) {
BoundingBox box = new BoundingBox(chunkCoord.minBlockX(), chunkCoord.minBlockY(), chunkCoord.minBlockZ(),
@@ -157,10 +175,14 @@ private static Int2ReferenceMap copyBlockEntities(LevelChunk chunk,
Int2ReferenceOpenHashMap blockEntities = null;
+ // Catch exceptions thrown by the iterator and handle them specially via the wrapped exception type
+ var it = WrappedIterator.create(chunk.getBlockEntities().entrySet());
+
// Copy the block entities from the chunk into our cloned section
- for (Map.Entry entry : chunk.getBlockEntities().entrySet()) {
- BlockPos pos = entry.getKey();
- BlockEntity entity = entry.getValue();
+ while (it.hasNext()) {
+ var entry = it.next();
+ var pos = entry.getKey();
+ var entity = entry.getValue();
if (box.isInside(pos)) {
if (blockEntities == null) {
From 02bcc3472279734abf20e15b95488f259ff8c1cd Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Fri, 17 Jan 2025 20:50:22 -0600
Subject: [PATCH 047/215] Bump version to 0.6.7-rc.1
---
buildSrc/src/main/kotlin/BuildConfig.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt
index 5b521b97db..4dd1916587 100644
--- a/buildSrc/src/main/kotlin/BuildConfig.kt
+++ b/buildSrc/src/main/kotlin/BuildConfig.kt
@@ -10,7 +10,7 @@ object BuildConfig {
val PARCHMENT_VERSION: String? = "2024.11.17"
// https://semver.org/
- var MOD_VERSION: String = "0.6.5"
+ var MOD_VERSION: String = "0.6.7-rc.1"
fun createVersionString(project: Project): String {
val builder = StringBuilder()
From dc1d9138d753563efe8fb54aab63934b95754607 Mon Sep 17 00:00:00 2001
From: IMS212
Date: Thu, 23 Jan 2025 15:02:07 -0800
Subject: [PATCH 048/215] Workaround incorrect quad ordering caused by material
downgrading
This fixes observers appearing red on XyCraft.
---
.../chunk/compile/pipeline/BlockRenderer.java | 20 ++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java
index 66b941192c..5d451302b7 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java
@@ -43,6 +43,8 @@
import org.jetbrains.annotations.Nullable;
import org.joml.Vector3f;
+import java.util.Iterator;
+
public class BlockRenderer extends AbstractBlockRenderContext {
private final ColorProviderRegistry colorProviderRegistry;
private final int[] vertexColors = new int[4];
@@ -55,6 +57,7 @@ public class BlockRenderer extends AbstractBlockRenderContext {
@Nullable
private ColorProvider colorProvider;
private TranslucentGeometryCollector collector;
+ private boolean allowDowngrade;
public BlockRenderer(ColorProviderRegistry colorRegistry, LightPipelineProvider lighters) {
this.colorProviderRegistry = colorRegistry;
@@ -99,9 +102,20 @@ public void renderModel(BakedModel model, BlockState state, BlockPos pos, BlockP
modelData = PlatformModelAccess.getInstance().getModelData(slice, model, state, pos, slice.getPlatformModelData(pos));
Iterable renderTypes = PlatformModelAccess.getInstance().getModelRenderTypes(level, model, state, pos, random, modelData);
+ this.allowDowngrade = true;
+
+ Iterator it = renderTypes.iterator();
+ var defaultType = ItemBlockRenderTypes.getChunkRenderType(state);
+
+ while (it.hasNext()) {
+ this.type = it.next();
+
+ // TODO: This can be removed once we have a better solution for https://github.com/CaffeineMC/sodium/issues/2868
+ // If the model contains any materials that are not the default, we can't allow the block to be downgraded. This avoids a potentially incorrect render order if there are overlapping quads.
+ if (it.hasNext() || this.type != defaultType) {
+ this.allowDowngrade = false;
+ }
- for (RenderType type : renderTypes) {
- this.type = type;
((FabricBakedModel) model).emitBlockQuads(this.level, state, pos, this.randomSupplier, this);
}
@@ -228,7 +242,7 @@ private boolean validateQuadUVs(TextureAtlasSprite atlasSprite) {
}
private @Nullable TerrainRenderPass attemptPassDowngrade(TextureAtlasSprite sprite, TerrainRenderPass pass) {
- if (Workarounds.isWorkaroundEnabled(Workarounds.Reference.INTEL_DEPTH_BUFFER_COMPARISON_UNRELIABLE)) {
+ if (!allowDowngrade || Workarounds.isWorkaroundEnabled(Workarounds.Reference.INTEL_DEPTH_BUFFER_COMPARISON_UNRELIABLE)) {
return null;
}
From eb9831f92f862f9dd1e47beb76d439f7981acda4 Mon Sep 17 00:00:00 2001
From: douira
Date: Sat, 7 Dec 2024 21:04:23 +0100
Subject: [PATCH 049/215] Use correct coordinates for sorting chunk sections
(#2924)
Fix section and region sorting by using the correct section coordinate instead of the integer part of the camera transform, which is incorrect near the origin.
Closes #2918
---
.../render/chunk/lists/ChunkRenderList.java | 10 +++++-----
.../render/chunk/lists/VisibleChunkCollector.java | 15 +++++++++------
2 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/lists/ChunkRenderList.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/lists/ChunkRenderList.java
index 6212573773..e45638b8ad 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/lists/ChunkRenderList.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/lists/ChunkRenderList.java
@@ -4,10 +4,10 @@
import net.caffeinemc.mods.sodium.client.render.chunk.RenderSection;
import net.caffeinemc.mods.sodium.client.render.chunk.RenderSectionFlags;
import net.caffeinemc.mods.sodium.client.render.chunk.region.RenderRegion;
-import net.caffeinemc.mods.sodium.client.render.viewport.CameraTransform;
import net.caffeinemc.mods.sodium.client.util.iterator.ByteArrayIterator;
import net.caffeinemc.mods.sodium.client.util.iterator.ByteIterator;
import net.caffeinemc.mods.sodium.client.util.iterator.ReversibleByteArrayIterator;
+import net.minecraft.core.SectionPos;
import net.minecraft.util.Mth;
import org.jetbrains.annotations.Nullable;
@@ -43,10 +43,10 @@ public void reset(int frame) {
// clamping the relative camera position to the region bounds means there can only be very few different distances
private static final int SORTING_HISTOGRAM_SIZE = RenderRegion.REGION_WIDTH + RenderRegion.REGION_HEIGHT + RenderRegion.REGION_LENGTH - 2;
- public void sortSections(CameraTransform transform, int[] sortItems) {
- var cameraX = Mth.clamp((transform.intX >> 4) - this.region.getChunkX(), 0, RenderRegion.REGION_WIDTH - 1);
- var cameraY = Mth.clamp((transform.intY >> 4) - this.region.getChunkY(), 0, RenderRegion.REGION_HEIGHT - 1);
- var cameraZ = Mth.clamp((transform.intZ >> 4) - this.region.getChunkZ(), 0, RenderRegion.REGION_LENGTH - 1);
+ public void sortSections(SectionPos cameraPos, int[] sortItems) {
+ var cameraX = Mth.clamp(cameraPos.getX() - this.region.getChunkX(), 0, RenderRegion.REGION_WIDTH - 1);
+ var cameraY = Mth.clamp(cameraPos.getY() - this.region.getChunkY(), 0, RenderRegion.REGION_HEIGHT - 1);
+ var cameraZ = Mth.clamp(cameraPos.getZ() - this.region.getChunkZ(), 0, RenderRegion.REGION_LENGTH - 1);
int[] histogram = new int[SORTING_HISTOGRAM_SIZE];
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/lists/VisibleChunkCollector.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/lists/VisibleChunkCollector.java
index 1eda00204c..89cf22cf78 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/lists/VisibleChunkCollector.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/lists/VisibleChunkCollector.java
@@ -8,7 +8,10 @@
import net.caffeinemc.mods.sodium.client.render.chunk.region.RenderRegion;
import net.caffeinemc.mods.sodium.client.render.viewport.Viewport;
-import java.util.*;
+import java.util.ArrayDeque;
+import java.util.EnumMap;
+import java.util.Map;
+import java.util.Queue;
/**
* The visible chunk collector is passed to the occlusion graph search culler to
@@ -67,10 +70,10 @@ private void addToRebuildLists(RenderSection section) {
public SortedRenderLists createRenderLists(Viewport viewport) {
// sort the regions by distance to fix rare region ordering bugs
- var transform = viewport.getTransform();
- var cameraX = transform.intX >> (4 + RenderRegion.REGION_WIDTH_SH);
- var cameraY = transform.intY >> (4 + RenderRegion.REGION_HEIGHT_SH);
- var cameraZ = transform.intZ >> (4 + RenderRegion.REGION_LENGTH_SH);
+ var sectionPos = viewport.getChunkCoord();
+ var cameraX = sectionPos.getX() >> RenderRegion.REGION_WIDTH_SH;
+ var cameraY = sectionPos.getY() >> RenderRegion.REGION_HEIGHT_SH;
+ var cameraZ = sectionPos.getZ() >> RenderRegion.REGION_LENGTH_SH;
var size = this.sortedRenderLists.size();
if (sortItems.length < size) {
@@ -95,7 +98,7 @@ public SortedRenderLists createRenderLists(Viewport viewport) {
}
for (var list : sorted) {
- list.sortSections(transform, sortItems);
+ list.sortSections(sectionPos, sortItems);
}
return new SortedRenderLists(sorted);
From 4689ab555178b9f95ff6ec462c608faed163d4f8 Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Tue, 28 Jan 2025 00:17:11 -0600
Subject: [PATCH 050/215] Add Javadoc to BugChecks.java
---
.../compatibility/checks/BugChecks.java | 48 +++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/BugChecks.java b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/BugChecks.java
index c4ef0b2a3e..e42457e2fb 100644
--- a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/BugChecks.java
+++ b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/BugChecks.java
@@ -5,10 +5,58 @@
* failing checks will crash the game and prompt the user for intervention.
*/
class BugChecks {
+ /**
+ * Some older drivers for Intel Gen7 Graphics on Windows are defective and will never return from
+ * a call to glClientWaitSync
. As there is no way to recover the main thread after the
+ * deadlock occurs, trying to work around this seems to be impossible. Updating the driver to version
+ * 15.33.53.5161 resolves the problem, and is the currently recommended solution.
+ * GitHub Issue
+ */
public static final boolean ISSUE_899 = configureCheck("issue899", true);
+
+ /**
+ * Since version 526.47 of the NVIDIA Graphics Driver, the OpenGL user-mode driver will attempt to detect
+ * Minecraft with hard-coded logic in the driver, and enable broken optimizations (referred to as "Threaded
+ * Optimizations"). This will cause crashes during framebuffer initialization (and some draw calls) for unclear
+ * reasons, especially on systems with hybrid graphics. Furthermore, performance is often severely degraded
+ * due to bubbles in the NVIDIA command submission thread, especially when other mods query context state.
+ *
+ * Sodium can prevent the detection of Minecraft and the enablement of these unstable optimizations, but the logic
+ * is extensive and depends heavily on the exact operating system and graphics driver version used. Some older
+ * graphics driver versions have no workaround available presently.
+ * GitHub Issue
+ */
public static final boolean ISSUE_1486 = configureCheck("issue1486", true);
+
+ /**
+ * Older versions of the RivaTuner Statistics Server will attempt to use legacy OpenGL functions in a Core
+ * profile, which causes either a crash or excessive log spam, depending on the OpenGL implementation. This is
+ * because RivaTuner relies on replacing the OpenGL context immediately after the application initializes it,
+ * but does so improperly when a No Error Context is used. This problem can't be avoided by simply configuring
+ * RivaTuner to not inject into Minecraft, as it *always* injects first to modify the context, and *then* disables
+ * itself.
+ * GitHub Issue
+ */
public static final boolean ISSUE_2048 = configureCheck("issue2048", true);
+
+ /**
+ * LWJGL does not provide API stability guarantees for other libraries using it to create their own C bindings.
+ * Because of this, the game will crash due to breaking method/type signature changes very early at startup. We
+ * should not be using these "internal" classes in LWJGL, but the amount of work involved doing everything ourselves
+ * is astronomical. When Minecraft ships a version of OpenJDK with the Foreign Function & Memory API, we can replace
+ * our dependency on LWJGL and remove this check.
+ * GitHub Issue
+ */
public static final boolean ISSUE_2561 = configureCheck("issue2561", true);
+
+ /**
+ * ASUS's GPU Tweak III does not correctly restore OpenGL context state after rendering its in-game overlay,
+ * which frequently causes graphical corruption, excessive log file spam, and crashes. These problems are
+ * actually reproducible without any mods installed, but it seems to be exacerbated with Sodium due to how different
+ * the rendering pipeline is. This problem can be avoided by configuring the application to not inject into
+ * Minecraft (or Java applications).
+ * GitHub Issue
+ */
public static final boolean ISSUE_2637 = configureCheck("issue2637", true);
private static boolean configureCheck(String name, boolean defaultValue) {
From 6b293a5657e84b6447937d6d8d3294002c13491f Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Tue, 4 Feb 2025 16:55:24 -0600
Subject: [PATCH 051/215] Add vendor detection for Intel Xe2 graphics
Closes #3005
---
.../environment/probe/GraphicsAdapterVendor.java | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java
index 57ddb79400..1db4d3df8a 100644
--- a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java
+++ b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java
@@ -18,11 +18,10 @@ public enum GraphicsAdapterVendor {
// Intel Gen 8 - ig8icd
// Intel Gen 9, 9.5 - ig9icd
// Intel Gen 11 - ig11icd
- // Intel Gen 12 - ig12icd (UHD Graphics, with early drivers)
- // igxelpicd (Xe-LP; integrated)
- // igxehpicd (Xe-HP; dedicated)
+ // Intel Xe - ig12icd (Xe-LP; early drivers) or igxelpicd (Xe-LP; later drivers), and igxehpicd (Xe-HP)
+ // Intel Xe2 - igxe2lpicd (Xe2-LP) and igxe2lpicd (Xe2-HP)
private static final Pattern INTEL_ICD_PATTERN =
- Pattern.compile("ig(4|7|75|8|9|11|12|xelp|xehp)icd(32|64)\\.dll", Pattern.CASE_INSENSITIVE);
+ Pattern.compile("ig(4|7|75|8|9|11|12|(xe(2)?(hp|lp)))icd(32|64)\\.dll", Pattern.CASE_INSENSITIVE);
private static final Pattern NVIDIA_ICD_PATTERN =
Pattern.compile("nvoglv(32|64)\\.dll", Pattern.CASE_INSENSITIVE);
From 410a730ccb0db1ef7fe8f56da276a41b3506e725 Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Sat, 8 Feb 2025 17:32:21 -0600
Subject: [PATCH 052/215] Bump version to 0.6.7
---
buildSrc/src/main/kotlin/BuildConfig.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt
index 4dd1916587..aab51ecdd8 100644
--- a/buildSrc/src/main/kotlin/BuildConfig.kt
+++ b/buildSrc/src/main/kotlin/BuildConfig.kt
@@ -10,7 +10,7 @@ object BuildConfig {
val PARCHMENT_VERSION: String? = "2024.11.17"
// https://semver.org/
- var MOD_VERSION: String = "0.6.7-rc.1"
+ var MOD_VERSION: String = "0.6.7"
fun createVersionString(project: Project): String {
val builder = StringBuilder()
From f9eee565c173ded8a0fd1cf0f105ab0bd5bc5eaf Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Thu, 13 Feb 2025 19:29:57 -0600
Subject: [PATCH 053/215] Move SpriteUtil to API package
The existing private interface is kept intact as to
not break any mods currently relying on it.
---
.../mods/sodium/api/texture/SpriteUtil.java | 31 +++++++++++++++++++
.../render/chunk/RenderSectionManager.java | 6 ++--
.../buffers/BakedChunkModelBuilder.java | 3 +-
.../compile/buffers/ChunkModelBuilder.java | 3 +-
.../chunk/compile/pipeline/BlockRenderer.java | 4 ++-
.../render/chunk/data/BuiltSectionInfo.java | 6 ++--
.../frapi/render/ItemRenderContext.java | 7 +++--
.../render/NonTerrainBlockRenderContext.java | 7 +++--
.../client/render/texture/SpriteUtil.java | 20 +++++++-----
.../client/render/texture/SpriteUtilImpl.java | 23 ++++++++++++++
.../intrinsics/BufferBuilderMixin.java | 22 ++++++++-----
.../render/model/item/ItemRendererMixin.java | 6 ++--
.../animations/tracking/GuiGraphicsMixin.java | 6 ++--
.../tracking/ModelBlockRendererMixin.java | 6 ++--
.../tracking/TextureAtlasMixin.java | 4 +--
.../tracking/TextureSheetParticleMixin.java | 6 ++--
.../model/block/ModelBlockRendererMixin.java | 6 ++--
.../model/block/ModelBlockRendererMixin.java | 6 ++--
18 files changed, 128 insertions(+), 44 deletions(-)
create mode 100644 common/src/api/java/net/caffeinemc/mods/sodium/api/texture/SpriteUtil.java
create mode 100644 common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteUtilImpl.java
diff --git a/common/src/api/java/net/caffeinemc/mods/sodium/api/texture/SpriteUtil.java b/common/src/api/java/net/caffeinemc/mods/sodium/api/texture/SpriteUtil.java
new file mode 100644
index 0000000000..4f33c26a7f
--- /dev/null
+++ b/common/src/api/java/net/caffeinemc/mods/sodium/api/texture/SpriteUtil.java
@@ -0,0 +1,31 @@
+package net.caffeinemc.mods.sodium.api.texture;
+
+import net.caffeinemc.mods.sodium.api.internal.DependencyInjection;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Utility functions for querying sprite information and updating per-frame information about sprite visibility.
+ */
+@ApiStatus.Experimental
+public interface SpriteUtil {
+ SpriteUtil INSTANCE = DependencyInjection.load(SpriteUtil.class,
+ "net.caffeinemc.mods.sodium.client.render.texture.SpriteUtilImpl");
+
+ /**
+ * Marks the sprite as "active", meaning that it is visible during this frame and should have the animation
+ * state updated. Mods which perform their own rendering without the use of Minecraft's helpers will need to
+ * call this method once every frame, when their sprite is actively being used in rendering.
+ * @param sprite The sprite to mark as active
+ */
+ void markSpriteActive(@NotNull TextureAtlasSprite sprite);
+
+ /**
+ * Returns if the provided sprite has an animation.
+ *
+ * @param sprite The sprite to query an animation for
+ * @return {@code true} if the provided sprite has an animation, otherwise {@code false}
+ */
+ boolean hasAnimation(@NotNull TextureAtlasSprite sprite);
+}
\ No newline at end of file
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager.java
index d6564985b9..b955b6b08a 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager.java
@@ -8,6 +8,7 @@
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
import it.unimi.dsi.fastutil.objects.ReferenceSet;
import it.unimi.dsi.fastutil.objects.ReferenceSets;
+import net.caffeinemc.mods.sodium.api.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.client.SodiumClientMod;
import net.caffeinemc.mods.sodium.client.gl.device.CommandList;
import net.caffeinemc.mods.sodium.client.gl.device.RenderDevice;
@@ -15,8 +16,8 @@
import net.caffeinemc.mods.sodium.client.render.chunk.compile.ChunkBuildOutput;
import net.caffeinemc.mods.sodium.client.render.chunk.compile.ChunkSortOutput;
import net.caffeinemc.mods.sodium.client.render.chunk.compile.executor.ChunkBuilder;
-import net.caffeinemc.mods.sodium.client.render.chunk.compile.executor.ChunkJobResult;
import net.caffeinemc.mods.sodium.client.render.chunk.compile.executor.ChunkJobCollector;
+import net.caffeinemc.mods.sodium.client.render.chunk.compile.executor.ChunkJobResult;
import net.caffeinemc.mods.sodium.client.render.chunk.compile.tasks.ChunkBuilderMeshingTask;
import net.caffeinemc.mods.sodium.client.render.chunk.compile.tasks.ChunkBuilderSortingTask;
import net.caffeinemc.mods.sodium.client.render.chunk.compile.tasks.ChunkBuilderTask;
@@ -37,7 +38,6 @@
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.trigger.CameraMovement;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.trigger.SortTriggering;
import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkMeshFormats;
-import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.client.render.util.RenderAsserts;
import net.caffeinemc.mods.sodium.client.render.viewport.CameraTransform;
import net.caffeinemc.mods.sodium.client.render.viewport.Viewport;
@@ -276,7 +276,7 @@ public void tickVisibleRenders() {
}
for (TextureAtlasSprite sprite : sprites) {
- SpriteUtil.markSpriteActive(sprite);
+ SpriteUtil.INSTANCE.markSpriteActive(sprite);
}
}
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/BakedChunkModelBuilder.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/BakedChunkModelBuilder.java
index 36e5aad24d..3c1b798305 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/BakedChunkModelBuilder.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/BakedChunkModelBuilder.java
@@ -7,6 +7,7 @@
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.TranslucentGeometryCollector;
import net.caffeinemc.mods.sodium.client.render.chunk.vertex.builder.ChunkMeshBufferBuilder;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import org.jetbrains.annotations.NotNull;
public class BakedChunkModelBuilder implements ChunkModelBuilder {
private final ChunkMeshBufferBuilder[] vertexBuffers;
@@ -24,7 +25,7 @@ public ChunkMeshBufferBuilder getVertexBuffer(ModelQuadFacing facing) {
}
@Override
- public void addSprite(TextureAtlasSprite sprite) {
+ public void addSprite(@NotNull TextureAtlasSprite sprite) {
this.renderData.addSprite(sprite);
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/ChunkModelBuilder.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/ChunkModelBuilder.java
index 637d1ce082..3b2f4e44b8 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/ChunkModelBuilder.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/ChunkModelBuilder.java
@@ -6,11 +6,12 @@
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.TranslucentGeometryCollector;
import net.caffeinemc.mods.sodium.client.render.chunk.vertex.builder.ChunkMeshBufferBuilder;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import org.jetbrains.annotations.NotNull;
public interface ChunkModelBuilder {
ChunkMeshBufferBuilder getVertexBuffer(ModelQuadFacing facing);
- void addSprite(TextureAtlasSprite sprite);
+ void addSprite(@NotNull TextureAtlasSprite sprite);
/**
* This method should not be used unless absolutely necessary! It exists only for compatibility purposes.
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java
index 5d451302b7..3ab498a662 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/BlockRenderer.java
@@ -220,7 +220,9 @@ private void bufferQuad(MutableQuadViewImpl quad, float[] brightnesses, Material
ChunkMeshBufferBuilder vertexBuffer = builder.getVertexBuffer(normalFace);
vertexBuffer.push(vertices, materialBits);
- builder.addSprite(atlasSprite);
+ if (atlasSprite != null) {
+ builder.addSprite(atlasSprite);
+ }
}
private boolean validateQuadUVs(TextureAtlasSprite atlasSprite) {
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/data/BuiltSectionInfo.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/data/BuiltSectionInfo.java
index 25bf883a4d..744e06224d 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/data/BuiltSectionInfo.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/data/BuiltSectionInfo.java
@@ -1,10 +1,10 @@
package net.caffeinemc.mods.sodium.client.render.chunk.data;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
+import net.caffeinemc.mods.sodium.api.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.client.render.chunk.RenderSectionFlags;
import net.caffeinemc.mods.sodium.client.render.chunk.occlusion.VisibilityEncoding;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.TerrainRenderPass;
-import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil;
import net.minecraft.client.renderer.chunk.VisibilitySet;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.Direction;
@@ -78,8 +78,8 @@ public void setOcclusionData(VisibilitySet data) {
* before rendering as necessary.
* @param sprite The sprite
*/
- public void addSprite(TextureAtlasSprite sprite) {
- if (SpriteUtil.hasAnimation(sprite)) {
+ public void addSprite(@NotNull TextureAtlasSprite sprite) {
+ if (SpriteUtil.INSTANCE.hasAnimation(sprite)) {
this.animatedSprites.add(sprite);
}
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/frapi/render/ItemRenderContext.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/frapi/render/ItemRenderContext.java
index fc52217c50..f2fe41f95b 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/frapi/render/ItemRenderContext.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/frapi/render/ItemRenderContext.java
@@ -19,12 +19,12 @@
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.MatrixUtil;
+import net.caffeinemc.mods.sodium.api.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.api.util.ColorMixer;
import net.caffeinemc.mods.sodium.client.render.frapi.helper.ColorHelper;
import net.caffeinemc.mods.sodium.client.render.frapi.mesh.EncodingFormat;
import net.caffeinemc.mods.sodium.client.render.frapi.mesh.MutableQuadViewImpl;
import net.caffeinemc.mods.sodium.client.render.texture.SpriteFinderCache;
-import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.mixin.features.render.frapi.ItemRendererAccessor;
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
@@ -224,7 +224,10 @@ private void shadeQuad(MutableQuadViewImpl quad, boolean emissive) {
private void bufferQuad(MutableQuadViewImpl quad, VertexConsumer vertexConsumer) {
QuadEncoder.writeQuadVertices(quad, vertexConsumer, overlay, matPosition, trustedNormals, matNormal);
- SpriteUtil.markSpriteActive(quad.sprite(SpriteFinderCache.forBlockAtlas()));
+ var sprite = quad.sprite(SpriteFinderCache.forBlockAtlas());
+ if (sprite != null) {
+ SpriteUtil.INSTANCE.markSpriteActive(sprite);
+ }
}
/**
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/frapi/render/NonTerrainBlockRenderContext.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/frapi/render/NonTerrainBlockRenderContext.java
index a0220a8776..3e9e938cce 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/frapi/render/NonTerrainBlockRenderContext.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/frapi/render/NonTerrainBlockRenderContext.java
@@ -18,6 +18,7 @@
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
+import net.caffeinemc.mods.sodium.api.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.api.util.ColorARGB;
import net.caffeinemc.mods.sodium.api.util.ColorMixer;
import net.caffeinemc.mods.sodium.client.model.light.LightMode;
@@ -25,7 +26,6 @@
import net.caffeinemc.mods.sodium.client.model.light.data.SingleBlockLightDataCache;
import net.caffeinemc.mods.sodium.client.render.frapi.mesh.MutableQuadViewImpl;
import net.caffeinemc.mods.sodium.client.render.texture.SpriteFinderCache;
-import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.client.services.SodiumModelData;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.fabricmc.fabric.api.renderer.v1.material.ShadeMode;
@@ -128,6 +128,9 @@ protected void shadeQuad(MutableQuadViewImpl quad, LightMode lightMode, boolean
private void bufferQuad(MutableQuadViewImpl quad) {
QuadEncoder.writeQuadVertices(quad, vertexConsumer, overlay, matPosition, trustedNormals, matNormal);
- SpriteUtil.markSpriteActive(quad.sprite(SpriteFinderCache.forBlockAtlas()));
+ var sprite = quad.sprite(SpriteFinderCache.forBlockAtlas());
+ if (sprite != null) {
+ SpriteUtil.INSTANCE.markSpriteActive(sprite);
+ }
}
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteUtil.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteUtil.java
index 084acc18b5..09e0369b96 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteUtil.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteUtil.java
@@ -3,18 +3,22 @@
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import org.jetbrains.annotations.Nullable;
+// Kept for mod compatibility, to be removed in next major release.
+@Deprecated(forRemoval = true)
public class SpriteUtil {
+ @Deprecated(forRemoval = true)
public static void markSpriteActive(@Nullable TextureAtlasSprite sprite) {
- if (sprite == null) {
- // Can happen in some cases, for example if a mod passes a BakedQuad with a null sprite
- // to a VertexConsumer that does not have a texture element.
- return;
+ if (sprite != null) {
+ net.caffeinemc.mods.sodium.api.texture.SpriteUtil.INSTANCE.markSpriteActive(sprite);
}
-
- ((SpriteContentsExtension) sprite.contents()).sodium$setActive(true);
}
- public static boolean hasAnimation(TextureAtlasSprite sprite) {
- return ((SpriteContentsExtension) sprite.contents()).sodium$hasAnimation();
+ @Deprecated(forRemoval = true)
+ public static boolean hasAnimation(@Nullable TextureAtlasSprite sprite) {
+ if (sprite != null) {
+ return net.caffeinemc.mods.sodium.api.texture.SpriteUtil.INSTANCE.hasAnimation(sprite);
+ }
+
+ return false;
}
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteUtilImpl.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteUtilImpl.java
new file mode 100644
index 0000000000..2c03d76e06
--- /dev/null
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteUtilImpl.java
@@ -0,0 +1,23 @@
+package net.caffeinemc.mods.sodium.client.render.texture;
+
+import net.caffeinemc.mods.sodium.api.texture.SpriteUtil;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Objects;
+
+public class SpriteUtilImpl implements SpriteUtil {
+ @Override
+ public void markSpriteActive(@NotNull TextureAtlasSprite sprite) {
+ Objects.requireNonNull(sprite);
+
+ ((SpriteContentsExtension) sprite.contents()).sodium$setActive(true);
+ }
+
+ @Override
+ public boolean hasAnimation(@NotNull TextureAtlasSprite sprite) {
+ Objects.requireNonNull(sprite);
+
+ return ((SpriteContentsExtension) sprite.contents()).sodium$hasAnimation();
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/immediate/buffer_builder/intrinsics/BufferBuilderMixin.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/immediate/buffer_builder/intrinsics/BufferBuilderMixin.java
index a72f45f5bc..9232a508e5 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/immediate/buffer_builder/intrinsics/BufferBuilderMixin.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/immediate/buffer_builder/intrinsics/BufferBuilderMixin.java
@@ -3,11 +3,11 @@
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
-import net.caffeinemc.mods.sodium.client.model.quad.ModelQuadView;
-import net.caffeinemc.mods.sodium.client.render.immediate.model.BakedModelEncoder;
-import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil;
+import net.caffeinemc.mods.sodium.api.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.api.util.ColorABGR;
import net.caffeinemc.mods.sodium.api.vertex.buffer.VertexBufferWriter;
+import net.caffeinemc.mods.sodium.client.model.quad.ModelQuadView;
+import net.caffeinemc.mods.sodium.client.render.immediate.model.BakedModelEncoder;
import net.minecraft.client.renderer.block.model.BakedQuad;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@@ -25,7 +25,9 @@ public void putBulkData(PoseStack.Pose matrices, BakedQuad bakedQuad, float r, f
if (!this.fastFormat) {
VertexConsumer.super.putBulkData(matrices, bakedQuad, r, g, b, a, light, overlay);
- SpriteUtil.markSpriteActive(bakedQuad.getSprite());
+ if (bakedQuad.getSprite() != null) {
+ SpriteUtil.INSTANCE.markSpriteActive(bakedQuad.getSprite());
+ }
return;
}
@@ -41,7 +43,9 @@ public void putBulkData(PoseStack.Pose matrices, BakedQuad bakedQuad, float r, f
int color = ColorABGR.pack(r, g, b, a);
BakedModelEncoder.writeQuadVertices(writer, matrices, quad, color, light, overlay, false);
- SpriteUtil.markSpriteActive(quad.getSprite());
+ if (quad.getSprite() != null) {
+ SpriteUtil.INSTANCE.markSpriteActive(quad.getSprite());
+ }
}
@Override
@@ -49,7 +53,9 @@ public void putBulkData(PoseStack.Pose matrices, BakedQuad bakedQuad, float[] br
if (!this.fastFormat) {
VertexConsumer.super.putBulkData(matrices, bakedQuad, brightnessTable, r, g, b, a, light, overlay, colorize);
- SpriteUtil.markSpriteActive(bakedQuad.getSprite());
+ if (bakedQuad.getSprite() != null) {
+ SpriteUtil.INSTANCE.markSpriteActive(bakedQuad.getSprite());
+ }
return;
}
@@ -64,6 +70,8 @@ public void putBulkData(PoseStack.Pose matrices, BakedQuad bakedQuad, float[] br
BakedModelEncoder.writeQuadVertices(writer, matrices, quad, r, g, b, a, brightnessTable, colorize, light, overlay);
- SpriteUtil.markSpriteActive(quad.getSprite());
+ if (quad.getSprite() != null) {
+ SpriteUtil.INSTANCE.markSpriteActive(quad.getSprite());
+ }
}
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/item/ItemRendererMixin.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/item/ItemRendererMixin.java
index 8ea16da500..fc3576589e 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/item/ItemRendererMixin.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/item/ItemRendererMixin.java
@@ -4,11 +4,11 @@
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
+import net.caffeinemc.mods.sodium.api.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.api.util.ColorARGB;
import net.caffeinemc.mods.sodium.api.vertex.buffer.VertexBufferWriter;
import net.caffeinemc.mods.sodium.client.model.quad.BakedQuadView;
import net.caffeinemc.mods.sodium.client.render.immediate.model.BakedModelEncoder;
-import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.client.render.vertex.VertexConsumerUtils;
import net.caffeinemc.mods.sodium.client.util.DirectionUtil;
import net.minecraft.client.color.item.ItemColors;
@@ -92,7 +92,9 @@ private void renderBakedItemQuads(PoseStack.Pose matrices, VertexBufferWriter wr
BakedModelEncoder.writeQuadVertices(writer, matrices, quad, color, light, overlay, BakedModelEncoder.shouldMultiplyAlpha());
- SpriteUtil.markSpriteActive(quad.getSprite());
+ if (quad.getSprite() != null) {
+ SpriteUtil.INSTANCE.markSpriteActive(quad.getSprite());
+ }
}
}
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/GuiGraphicsMixin.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/GuiGraphicsMixin.java
index 49d71efb44..fed72a54e8 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/GuiGraphicsMixin.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/GuiGraphicsMixin.java
@@ -1,6 +1,6 @@
package net.caffeinemc.mods.sodium.mixin.features.textures.animations.tracking;
-import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil;
+import net.caffeinemc.mods.sodium.api.texture.SpriteUtil;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import org.spongepowered.asm.mixin.Mixin;
@@ -16,7 +16,7 @@ private void preDrawSprite(int x, int y, int z,
TextureAtlasSprite sprite,
CallbackInfo ci)
{
- SpriteUtil.markSpriteActive(sprite);
+ SpriteUtil.INSTANCE.markSpriteActive(sprite);
}
@Inject(method = "blit(IIIIILnet/minecraft/client/renderer/texture/TextureAtlasSprite;FFFF)V", at = @At("HEAD"))
@@ -26,6 +26,6 @@ private void preDrawSprite(int x, int y, int z,
float red, float green, float blue, float alpha,
CallbackInfo ci)
{
- SpriteUtil.markSpriteActive(sprite);
+ SpriteUtil.INSTANCE.markSpriteActive(sprite);
}
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/ModelBlockRendererMixin.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/ModelBlockRendererMixin.java
index 020ee3cb27..4444d4c71c 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/ModelBlockRendererMixin.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/ModelBlockRendererMixin.java
@@ -2,7 +2,7 @@
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
-import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil;
+import net.caffeinemc.mods.sodium.api.texture.SpriteUtil;
import net.minecraft.client.renderer.block.ModelBlockRenderer;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.core.BlockPos;
@@ -22,6 +22,8 @@ public class ModelBlockRendererMixin {
*/
@Inject(method = "putQuadData", at = @At("HEAD"))
private void preRenderQuad(BlockAndTintGetter level, BlockState state, BlockPos pos, VertexConsumer vertexConsumer, PoseStack.Pose matrices, BakedQuad quad, float brightness0, float brightness1, float brightness2, float brightness3, int light0, int light1, int light2, int light3, int overlay, CallbackInfo ci) {
- SpriteUtil.markSpriteActive(quad.getSprite());
+ if (quad.getSprite() != null) {
+ SpriteUtil.INSTANCE.markSpriteActive(quad.getSprite());
+ }
}
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/TextureAtlasMixin.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/TextureAtlasMixin.java
index d60038f2c4..f23ca8fe4f 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/TextureAtlasMixin.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/TextureAtlasMixin.java
@@ -1,6 +1,6 @@
package net.caffeinemc.mods.sodium.mixin.features.textures.animations.tracking;
-import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil;
+import net.caffeinemc.mods.sodium.api.texture.SpriteUtil;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import org.spongepowered.asm.mixin.Mixin;
@@ -15,7 +15,7 @@ private void preReturnSprite(CallbackInfoReturnable cir) {
TextureAtlasSprite sprite = cir.getReturnValue();
if (sprite != null) {
- SpriteUtil.markSpriteActive(sprite);
+ SpriteUtil.INSTANCE.markSpriteActive(sprite);
}
}
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/TextureSheetParticleMixin.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/TextureSheetParticleMixin.java
index 6773925be4..a4f162ab15 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/TextureSheetParticleMixin.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/TextureSheetParticleMixin.java
@@ -1,7 +1,7 @@
package net.caffeinemc.mods.sodium.mixin.features.textures.animations.tracking;
import com.mojang.blaze3d.vertex.VertexConsumer;
-import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil;
+import net.caffeinemc.mods.sodium.api.texture.SpriteUtil;
import net.minecraft.client.Camera;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.particle.SingleQuadParticle;
@@ -28,13 +28,13 @@ protected TextureSheetParticleMixin(ClientLevel level, double x, double y, doubl
@Inject(method = "setSprite(Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;)V", at = @At("RETURN"))
private void afterSetSprite(TextureAtlasSprite sprite, CallbackInfo ci) {
- this.shouldTickSprite = sprite != null && SpriteUtil.hasAnimation(sprite);
+ this.shouldTickSprite = sprite != null && SpriteUtil.INSTANCE.hasAnimation(sprite);
}
@Override
public void render(VertexConsumer vertexConsumer, Camera camera, float tickDelta) {
if (this.shouldTickSprite) {
- SpriteUtil.markSpriteActive(this.sprite);
+ SpriteUtil.INSTANCE.markSpriteActive(this.sprite);
}
super.render(vertexConsumer, camera, tickDelta);
diff --git a/fabric/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/block/ModelBlockRendererMixin.java b/fabric/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/block/ModelBlockRendererMixin.java
index 6fbc0d2ecf..636c9974eb 100644
--- a/fabric/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/block/ModelBlockRendererMixin.java
+++ b/fabric/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/block/ModelBlockRendererMixin.java
@@ -2,11 +2,11 @@
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
+import net.caffeinemc.mods.sodium.api.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.api.util.ColorABGR;
import net.caffeinemc.mods.sodium.api.vertex.buffer.VertexBufferWriter;
import net.caffeinemc.mods.sodium.client.model.quad.BakedQuadView;
import net.caffeinemc.mods.sodium.client.render.immediate.model.BakedModelEncoder;
-import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.client.render.vertex.VertexConsumerUtils;
import net.caffeinemc.mods.sodium.client.util.DirectionUtil;
import net.minecraft.client.renderer.block.ModelBlockRenderer;
@@ -46,7 +46,9 @@ private static void renderQuads(PoseStack.Pose matrices, VertexBufferWriter writ
BakedModelEncoder.writeQuadVertices(writer, matrices, quad, color, light, overlay, false);
- SpriteUtil.markSpriteActive(quad.getSprite());
+ if (quad.getSprite() != null) {
+ SpriteUtil.INSTANCE.markSpriteActive(quad.getSprite());
+ }
}
}
diff --git a/neoforge/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/block/ModelBlockRendererMixin.java b/neoforge/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/block/ModelBlockRendererMixin.java
index c87264a58e..c93024b0fd 100644
--- a/neoforge/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/block/ModelBlockRendererMixin.java
+++ b/neoforge/src/main/java/net/caffeinemc/mods/sodium/mixin/features/render/model/block/ModelBlockRendererMixin.java
@@ -2,11 +2,11 @@
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
+import net.caffeinemc.mods.sodium.api.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.api.util.ColorABGR;
import net.caffeinemc.mods.sodium.api.vertex.buffer.VertexBufferWriter;
import net.caffeinemc.mods.sodium.client.model.quad.BakedQuadView;
import net.caffeinemc.mods.sodium.client.render.immediate.model.BakedModelEncoder;
-import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil;
import net.caffeinemc.mods.sodium.client.render.vertex.VertexConsumerUtils;
import net.caffeinemc.mods.sodium.client.util.DirectionUtil;
import net.minecraft.client.renderer.RenderType;
@@ -48,7 +48,9 @@ private static void renderQuads(PoseStack.Pose matrices, VertexBufferWriter writ
BakedModelEncoder.writeQuadVertices(writer, matrices, quad, color, light, overlay, false);
- SpriteUtil.markSpriteActive(quad.getSprite());
+ if (quad.getSprite() != null) {
+ SpriteUtil.INSTANCE.markSpriteActive(quad.getSprite());
+ }
}
}
From 9d702c0bdf8df56792ab87e7089a2765ffe2b8fd Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Fri, 14 Feb 2025 17:54:11 -0600
Subject: [PATCH 054/215] Fixup OpenGL ICD names for Intel Xe1 and Xe2
`igxe(2)?(lp|hp)gicd` should have been `igxe(2)?(lpg|hpg)`
---
.../environment/probe/GraphicsAdapterVendor.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java
index 1db4d3df8a..b6b89443a8 100644
--- a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java
+++ b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java
@@ -18,10 +18,10 @@ public enum GraphicsAdapterVendor {
// Intel Gen 8 - ig8icd
// Intel Gen 9, 9.5 - ig9icd
// Intel Gen 11 - ig11icd
- // Intel Xe - ig12icd (Xe-LP; early drivers) or igxelpicd (Xe-LP; later drivers), and igxehpicd (Xe-HP)
- // Intel Xe2 - igxe2lpicd (Xe2-LP) and igxe2lpicd (Xe2-HP)
+ // Intel Xe - ig12icd (Xe-LP; early drivers) or igxelpgicd (Xe-LP; later drivers), and igxehpgicd (Xe-HP)
+ // Intel Xe2 - igxe2lpgicd (Xe2-LP) and igxe2hpgicd (Xe2-HP)
private static final Pattern INTEL_ICD_PATTERN =
- Pattern.compile("ig(4|7|75|8|9|11|12|(xe(2)?(hp|lp)))icd(32|64)\\.dll", Pattern.CASE_INSENSITIVE);
+ Pattern.compile("ig(4|7|75|8|9|11|12|(xe(2)?(hpg|lpg)))icd(32|64)\\.dll", Pattern.CASE_INSENSITIVE);
private static final Pattern NVIDIA_ICD_PATTERN =
Pattern.compile("nvoglv(32|64)\\.dll", Pattern.CASE_INSENSITIVE);
From adae07ef3bb3eb0e281be88f54e00d3ab275c95a Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Fri, 14 Feb 2025 18:18:41 -0600
Subject: [PATCH 055/215] Distinguish between LP/HP and LPG/HPG in Intel Xe
detection
---
.../environment/probe/GraphicsAdapterVendor.java | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java
index b6b89443a8..436bee2ae7 100644
--- a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java
+++ b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/environment/probe/GraphicsAdapterVendor.java
@@ -18,10 +18,13 @@ public enum GraphicsAdapterVendor {
// Intel Gen 8 - ig8icd
// Intel Gen 9, 9.5 - ig9icd
// Intel Gen 11 - ig11icd
- // Intel Xe - ig12icd (Xe-LP; early drivers) or igxelpgicd (Xe-LP; later drivers), and igxehpgicd (Xe-HP)
- // Intel Xe2 - igxe2lpgicd (Xe2-LP) and igxe2hpgicd (Xe2-HP)
+ // Intel Xe-LP - ig12icd (early drivers) or igxelpicd (later drivers)
+ // Intel Xe-HP - igxehpicd
+ // Intel Xe-HPG - igxehpgicd
+ // Intel Xe2-LPG - igxe2lpgicd
+ // Intel Xe2-HPG - igxe2hpgicd
private static final Pattern INTEL_ICD_PATTERN =
- Pattern.compile("ig(4|7|75|8|9|11|12|(xe(2)?(hpg|lpg)))icd(32|64)\\.dll", Pattern.CASE_INSENSITIVE);
+ Pattern.compile("ig(4|7|75|8|9|11|12|(xe2?(hpg?|lpg?)))icd(32|64)\\.dll", Pattern.CASE_INSENSITIVE);
private static final Pattern NVIDIA_ICD_PATTERN =
Pattern.compile("nvoglv(32|64)\\.dll", Pattern.CASE_INSENSITIVE);
From f16b9cb051e863af314dcc63df1c1a20289e4aca Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Fri, 17 Jan 2025 18:43:27 -0600
Subject: [PATCH 056/215] Make texture sampling more robust in terrain
rendering
The epsilon used to prevent texture bleeding between
sprites in the atlas is now dynamically computed according
to hardware capabilities and atlas size.
Using a dynamic value solves a problem where Sodium
would compute an epsilon that is too small (less than one
sub-texel) with very large atlases, and therefore introduce
texture bleeding at the edges of blocks.
By default, this patch assumes that all hardware is capable
of 8 bits of sub-texel precision, which seems to hold true
in the general case since nearly all hardware is also
Direct3D-compatible.
The only exception to this rule happens to be with Apple's
OpenGL implementation, where the precision is instead
limited to 4 bits (the minimum of which is required by
OpenGL's spec.)
This is also the reason why texture bleeding was observed
to be a much bigger issue on macOS, since the fixed epsilon
used before was simply too small when limited to 4 bits of
sub-texel precision.
Additionally, the rounding behavior of texture coordinate
encoding is refined to avoid problems with block models
that encode their own epsilon for other reasons, which has
been observed with some mods.
---
.../client/gl/device/GLRenderDevice.java | 14 +++++++++++
.../sodium/client/gl/device/RenderDevice.java | 2 ++
.../gl/shader/uniform/GlUniformFloat2v.java | 22 +++++++++++++++++
.../chunk/shader/DefaultShaderInterface.java | 24 +++++++++++++++++++
.../format/impl/CompactChunkVertex.java | 9 +++----
.../render/texture/TextureAtlasAccessor.java | 9 ++++---
.../shaders/blocks/block_layer_opaque.vsh | 3 ++-
.../sodium/shaders/include/chunk_vertex.glsl | 10 ++++----
8 files changed, 75 insertions(+), 18 deletions(-)
create mode 100644 common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/uniform/GlUniformFloat2v.java
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/device/GLRenderDevice.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/device/GLRenderDevice.java
index 98af1f3ba3..95d3a9d8b7 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/device/GLRenderDevice.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/device/GLRenderDevice.java
@@ -1,5 +1,6 @@
package net.caffeinemc.mods.sodium.client.gl.device;
+import net.caffeinemc.mods.sodium.client.compatibility.environment.OsUtils;
import net.caffeinemc.mods.sodium.client.gl.array.GlVertexArray;
import net.caffeinemc.mods.sodium.client.gl.buffer.*;
import net.caffeinemc.mods.sodium.client.gl.functions.DeviceFunctions;
@@ -60,6 +61,19 @@ public DeviceFunctions getDeviceFunctions() {
return this.functions;
}
+ @Override
+ public int getSubTexelPrecisionBits() {
+ // OpenGL only specifies "at least" 4 bits of sub-texel precision for texture fetches. Thankfully, nearly every
+ // graphics card is Direct3D-compatible and capable of providing 8 bits of precision. The only exception to this
+ // rule seems to be when using OpenGL on macOS, where it appears to arbitrarily limit the precision to 4 bits
+ // *even if* the hardware is capable of better.
+ if (OsUtils.getOs() == OsUtils.OperatingSystem.MAC) {
+ return 4;
+ }
+
+ return 8;
+ }
+
private void checkDeviceActive() {
if (!this.isActive) {
throw new IllegalStateException("Tried to access device from unmanaged context");
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/device/RenderDevice.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/device/RenderDevice.java
index e87edf1cec..9787b829b6 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/device/RenderDevice.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/device/RenderDevice.java
@@ -22,4 +22,6 @@ static void exitManagedCode() {
GLCapabilities getCapabilities();
DeviceFunctions getDeviceFunctions();
+
+ int getSubTexelPrecisionBits();
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/uniform/GlUniformFloat2v.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/uniform/GlUniformFloat2v.java
new file mode 100644
index 0000000000..428458f8cc
--- /dev/null
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/uniform/GlUniformFloat2v.java
@@ -0,0 +1,22 @@
+package net.caffeinemc.mods.sodium.client.gl.shader.uniform;
+
+import org.lwjgl.opengl.GL30C;
+
+public class GlUniformFloat2v extends GlUniform {
+ public GlUniformFloat2v(int index) {
+ super(index);
+ }
+
+ @Override
+ public void set(float[] value) {
+ if (value.length != 2) {
+ throw new IllegalArgumentException("value.length != 2");
+ }
+
+ GL30C.glUniform2fv(this.index, value);
+ }
+
+ public void set(float x, float y) {
+ GL30C.glUniform2f(this.index, x, y);
+ }
+}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/DefaultShaderInterface.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/DefaultShaderInterface.java
index 1ce8947477..f039ca3a01 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/DefaultShaderInterface.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/DefaultShaderInterface.java
@@ -1,10 +1,16 @@
package net.caffeinemc.mods.sodium.client.render.chunk.shader;
import com.mojang.blaze3d.platform.GlStateManager;
+import net.caffeinemc.mods.sodium.client.gl.device.GLRenderDevice;
+import net.caffeinemc.mods.sodium.client.gl.shader.uniform.GlUniformFloat2v;
import net.caffeinemc.mods.sodium.client.gl.shader.uniform.GlUniformFloat3v;
import net.caffeinemc.mods.sodium.client.gl.shader.uniform.GlUniformInt;
import net.caffeinemc.mods.sodium.client.gl.shader.uniform.GlUniformMatrix4f;
+import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.impl.CompactChunkVertex;
import net.caffeinemc.mods.sodium.client.util.TextureUtil;
+import net.caffeinemc.mods.sodium.mixin.core.render.texture.TextureAtlasAccessor;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.texture.TextureAtlas;
import org.joml.Matrix4fc;
import org.lwjgl.opengl.GL32C;
@@ -20,6 +26,7 @@ public class DefaultShaderInterface implements ChunkShaderInterface {
private final GlUniformMatrix4f uniformModelViewMatrix;
private final GlUniformMatrix4f uniformProjectionMatrix;
private final GlUniformFloat3v uniformRegionOffset;
+ private final GlUniformFloat2v uniformTexCoordShrink;
// The fog shader component used by this program in order to setup the appropriate GL state
private final ChunkShaderFogComponent fogShader;
@@ -28,6 +35,7 @@ public DefaultShaderInterface(ShaderBindingContext context, ChunkShaderOptions o
this.uniformModelViewMatrix = context.bindUniform("u_ModelViewMatrix", GlUniformMatrix4f::new);
this.uniformProjectionMatrix = context.bindUniform("u_ProjectionMatrix", GlUniformMatrix4f::new);
this.uniformRegionOffset = context.bindUniform("u_RegionOffset", GlUniformFloat3v::new);
+ this.uniformTexCoordShrink = context.bindUniform("u_TexCoordShrink", GlUniformFloat2v::new);
this.uniformTextures = new EnumMap<>(ChunkShaderTextureSlot.class);
this.uniformTextures.put(ChunkShaderTextureSlot.BLOCK, context.bindUniform("u_BlockTex", GlUniformInt::new));
@@ -38,9 +46,25 @@ public DefaultShaderInterface(ShaderBindingContext context, ChunkShaderOptions o
@Override // the shader interface should not modify pipeline state
public void setupState() {
+ // TODO: Bind to these textures directly rather than using fragile RenderSystem state
this.bindTexture(ChunkShaderTextureSlot.BLOCK, TextureUtil.getBlockTextureId());
this.bindTexture(ChunkShaderTextureSlot.LIGHT, TextureUtil.getLightTextureId());
+ var textureAtlas = (TextureAtlasAccessor) Minecraft.getInstance()
+ .getTextureManager()
+ .getTexture(TextureAtlas.LOCATION_BLOCKS);
+
+ // There is a limited amount of sub-texel precision when using hardware texture sampling. The mapped texture
+ // area must be "shrunk" by at least one sub-texel to avoid bleed between textures in the atlas. And since we
+ // offset texture coordinates in the vertex format by one texel, we also need to undo that here.
+ double subTexelPrecision = (1 << GLRenderDevice.INSTANCE.getSubTexelPrecisionBits());
+ double subTexelOffset = 1.0f / CompactChunkVertex.TEXTURE_MAX_VALUE;
+
+ this.uniformTexCoordShrink.set(
+ (float) (subTexelOffset - (((1.0D / textureAtlas.getWidth()) / subTexelPrecision))),
+ (float) (subTexelOffset - (((1.0D / textureAtlas.getHeight()) / subTexelPrecision)))
+ );
+
this.fogShader.setup();
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java
index 44c73a8719..ab191b9934 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java
@@ -18,8 +18,8 @@ public class CompactChunkVertex implements ChunkVertexType {
.addElement(DefaultChunkMeshAttributes.LIGHT_MATERIAL_INDEX, ChunkShaderBindingPoints.ATTRIBUTE_LIGHT_MATERIAL_INDEX, 16)
.build();
- private static final int POSITION_MAX_VALUE = 1 << 20;
- private static final int TEXTURE_MAX_VALUE = 1 << 15;
+ public static final int POSITION_MAX_VALUE = 1 << 20;
+ public static final int TEXTURE_MAX_VALUE = 1 << 15;
private static final float MODEL_ORIGIN = 8.0f;
private static final float MODEL_RANGE = 32.0f;
@@ -101,7 +101,7 @@ private static int encodeTexture(float center, float x) {
// This makes it possible to use much smaller epsilons for avoiding texture bleed, since the epsilon is no
// longer encoded into the vertex data (instead, we only store the sign.)
int bias = (x < center) ? 1 : -1;
- int quantized = floorInt(x * TEXTURE_MAX_VALUE) + bias;
+ int quantized = Math.round(x * TEXTURE_MAX_VALUE) + bias;
return (quantized & 0x7FFF) | (sign(bias) << 15);
}
@@ -125,7 +125,4 @@ private static int sign(int x) {
return (x >>> 31);
}
- private static int floorInt(float x) {
- return (int) Math.floor(x);
- }
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/core/render/texture/TextureAtlasAccessor.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/core/render/texture/TextureAtlasAccessor.java
index f95d1f8f59..7f9a6b060b 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/core/render/texture/TextureAtlasAccessor.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/core/render/texture/TextureAtlasAccessor.java
@@ -1,15 +1,14 @@
package net.caffeinemc.mods.sodium.mixin.core.render.texture;
import net.minecraft.client.renderer.texture.TextureAtlas;
-import net.minecraft.client.renderer.texture.TextureAtlasSprite;
-import net.minecraft.resources.ResourceLocation;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
-import java.util.Map;
-
@Mixin(TextureAtlas.class)
public interface TextureAtlasAccessor {
@Accessor
- Map getTexturesByName();
+ int getWidth();
+
+ @Accessor
+ int getHeight();
}
diff --git a/common/src/main/resources/assets/sodium/shaders/blocks/block_layer_opaque.vsh b/common/src/main/resources/assets/sodium/shaders/blocks/block_layer_opaque.vsh
index e281de1eae..fcd0ddfc50 100644
--- a/common/src/main/resources/assets/sodium/shaders/blocks/block_layer_opaque.vsh
+++ b/common/src/main/resources/assets/sodium/shaders/blocks/block_layer_opaque.vsh
@@ -19,6 +19,7 @@ out float v_FragDistance;
uniform int u_FogShape;
uniform vec3 u_RegionOffset;
+uniform vec2 u_TexCoordShrink;
uniform sampler2D u_LightTex; // The light map texture sampler
@@ -47,7 +48,7 @@ void main() {
// Add the light color to the vertex color, and pass the texture coordinates to the fragment shader
v_Color = _vert_color * texture(u_LightTex, _vert_tex_light_coord);
- v_TexCoord = _vert_tex_diffuse_coord;
+ v_TexCoord = (_vert_tex_diffuse_coord_bias * u_TexCoordShrink) + _vert_tex_diffuse_coord; // FMA for precision
v_MaterialMipBias = _material_mip_bias(_material_params);
#ifdef USE_FRAGMENT_DISCARD
diff --git a/common/src/main/resources/assets/sodium/shaders/include/chunk_vertex.glsl b/common/src/main/resources/assets/sodium/shaders/include/chunk_vertex.glsl
index 3ce9949258..e392ffa901 100644
--- a/common/src/main/resources/assets/sodium/shaders/include/chunk_vertex.glsl
+++ b/common/src/main/resources/assets/sodium/shaders/include/chunk_vertex.glsl
@@ -3,6 +3,7 @@ vec3 _vert_position;
// The block texture coordinate of the vertex
vec2 _vert_tex_diffuse_coord;
+vec2 _vert_tex_diffuse_coord_bias;
// The light texture coordinate of the vertex
vec2 _vert_tex_light_coord;
@@ -28,10 +29,6 @@ const uint TEXTURE_MAX_VALUE = TEXTURE_MAX_COORD - 1u;
const float VERTEX_SCALE = 32.0 / float(POSITION_MAX_COORD);
const float VERTEX_OFFSET = -8.0;
-// The amount of inset the texture coordinates from the edges of the texture, to avoid texture bleeding
-const float TEXTURE_FUZZ_AMOUNT = 1.0 / 64.0;
-const float TEXTURE_GROW_FACTOR = (1.0 - TEXTURE_FUZZ_AMOUNT) / TEXTURE_MAX_COORD;
-
in uvec2 a_Position;
in vec4 a_Color;
in uvec2 a_TexCoord;
@@ -49,13 +46,14 @@ vec2 _get_texcoord() {
}
vec2 _get_texcoord_bias() {
- return mix(vec2(-TEXTURE_GROW_FACTOR), vec2(TEXTURE_GROW_FACTOR), bvec2(a_TexCoord >> TEXTURE_BITS));
+ return mix(vec2(-1.0), vec2(1.0), bvec2(a_TexCoord >> TEXTURE_BITS));
}
void _vert_init() {
_vert_position = (_deinterleave_u20x3(a_Position) * VERTEX_SCALE) + VERTEX_OFFSET;
_vert_color = a_Color;
- _vert_tex_diffuse_coord = _get_texcoord() + _get_texcoord_bias();
+ _vert_tex_diffuse_coord = _get_texcoord();
+ _vert_tex_diffuse_coord_bias = _get_texcoord_bias();
_vert_tex_light_coord = vec2(a_LightAndData.xy) / vec2(256.0);
From a8d9e1f468aad4784ede83868eeb092324b84392 Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Wed, 19 Feb 2025 16:22:31 -0600
Subject: [PATCH 057/215] Update list of incompatible mods
---
fabric/src/main/resources/fabric.mod.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json
index b80dfa1aa9..4ccd5a11e1 100644
--- a/fabric/src/main/resources/fabric.mod.json
+++ b/fabric/src/main/resources/fabric.mod.json
@@ -94,14 +94,14 @@
"custom_hud" : "<3.4.2",
"farsight" : "<=1.21-4.3",
"iceberg" : "<1.2.7",
- "iris" : "<1.8.1",
+ "iris" : "<1.8.7",
"movingelevators" : "<=1.4.7",
"notenoughcrashes" : "<4.4.8",
"noxesium" : "<2.3.3",
"reeses-sodium-options" : "<1.8.0",
"sodium-extra" : "<0.6.0",
"sspb" : "<4.0.0",
- "moreculling": "<1.0.0",
+ "moreculling": "<1.0.4",
"simply-no-shading": "<7.6.2"
},
"provides" : [
From fd41efa81b88269d2021ad4c187fb34e2c2d083a Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Wed, 19 Feb 2025 16:23:34 -0600
Subject: [PATCH 058/215] Bump version to 0.6.9
---
buildSrc/src/main/kotlin/BuildConfig.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt
index aab51ecdd8..4b55391309 100644
--- a/buildSrc/src/main/kotlin/BuildConfig.kt
+++ b/buildSrc/src/main/kotlin/BuildConfig.kt
@@ -10,7 +10,7 @@ object BuildConfig {
val PARCHMENT_VERSION: String? = "2024.11.17"
// https://semver.org/
- var MOD_VERSION: String = "0.6.7"
+ var MOD_VERSION: String = "0.6.9"
fun createVersionString(project: Project): String {
val builder = StringBuilder()
From f3c5775b0905e9c3f4fbf3712a4e1d91a5898358 Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Sun, 9 Mar 2025 13:21:33 -0500
Subject: [PATCH 059/215] Re-enable block entity data fetching
This was probably disabled by accident during a port
and is required for some mods.
---
.../mods/sodium/neoforge/block/NeoForgeBlockAccess.java | 2 +-
.../mods/sodium/neoforge/level/NeoForgeLevelAccess.java | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/neoforge/src/main/java/net/caffeinemc/mods/sodium/neoforge/block/NeoForgeBlockAccess.java b/neoforge/src/main/java/net/caffeinemc/mods/sodium/neoforge/block/NeoForgeBlockAccess.java
index 3712c8217e..793fdf9e84 100644
--- a/neoforge/src/main/java/net/caffeinemc/mods/sodium/neoforge/block/NeoForgeBlockAccess.java
+++ b/neoforge/src/main/java/net/caffeinemc/mods/sodium/neoforge/block/NeoForgeBlockAccess.java
@@ -37,7 +37,7 @@ public boolean shouldShowFluidOverlay(BlockState block, BlockAndTintGetter level
@Override
public boolean platformHasBlockData() {
- return false;
+ return true;
}
@Override
diff --git a/neoforge/src/main/java/net/caffeinemc/mods/sodium/neoforge/level/NeoForgeLevelAccess.java b/neoforge/src/main/java/net/caffeinemc/mods/sodium/neoforge/level/NeoForgeLevelAccess.java
index beedc67b4f..540957fe48 100644
--- a/neoforge/src/main/java/net/caffeinemc/mods/sodium/neoforge/level/NeoForgeLevelAccess.java
+++ b/neoforge/src/main/java/net/caffeinemc/mods/sodium/neoforge/level/NeoForgeLevelAccess.java
@@ -2,6 +2,7 @@
import net.caffeinemc.mods.sodium.client.services.PlatformLevelAccess;
import net.caffeinemc.mods.sodium.client.world.SodiumAuxiliaryLightManager;
+import net.fabricmc.fabric.api.blockview.v2.RenderDataBlockEntity;
import net.minecraft.core.SectionPos;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.chunk.LevelChunk;
@@ -10,7 +11,7 @@
public class NeoForgeLevelAccess implements PlatformLevelAccess {
@Override
public @Nullable Object getBlockEntityData(BlockEntity blockEntity) {
- return null;
+ return ((RenderDataBlockEntity) blockEntity).getRenderData();
}
@Override
From 281f81e282ce7934534fd49f12a1dc5148824c29 Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Sun, 16 Feb 2025 15:36:52 -0600
Subject: [PATCH 060/215] Modify startup warning shown when using unsupported
launchers
---
common/src/main/resources/assets/sodium/lang/en_us.json | 1 -
.../client/compatibility/checks/PostLaunchChecks.java | 6 ++----
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/common/src/main/resources/assets/sodium/lang/en_us.json b/common/src/main/resources/assets/sodium/lang/en_us.json
index d1d1e6b6a7..4ab5645094 100644
--- a/common/src/main/resources/assets/sodium/lang/en_us.json
+++ b/common/src/main/resources/assets/sodium/lang/en_us.json
@@ -59,7 +59,6 @@
"sodium.options.buttons.donate": "Buy us a coffee!",
"sodium.console.game_restart": "The game must be restarted to apply one or more video settings!",
"sodium.console.broken_nvidia_driver": "Your NVIDIA graphics drivers are out of date!\n * This will cause severe performance issues and crashes when Sodium is installed.\n * Please update your graphics drivers to the latest version (version 536.23 or newer.)",
- "sodium.console.pojav_launcher": "PojavLauncher is not supported when using Sodium.\n * You are very likely to run into extreme performance issues, graphical bugs, and crashes.\n * You will be on your own if you decide to continue -- we will not help you with any bugs or crashes!",
"sodium.console.core_shaders_error": "The following resource packs are incompatible with Sodium:",
"sodium.console.core_shaders_warn": "The following resource packs may be incompatible with Sodium:",
"sodium.console.core_shaders_info": "Check the game log for detailed information.",
diff --git a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/PostLaunchChecks.java b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/PostLaunchChecks.java
index 907b877afe..6180199456 100644
--- a/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/PostLaunchChecks.java
+++ b/common/src/workarounds/java/net/caffeinemc/mods/sodium/client/compatibility/checks/PostLaunchChecks.java
@@ -21,10 +21,8 @@ public static void onContextInitialized(NativeWindowHandle window, GlContextInfo
// FIXME: This can be determined earlier, but we can't access the GUI classes in pre-launch
if (isUsingPojavLauncher()) {
- Console.instance().logMessage(MessageLevel.SEVERE, "sodium.console.pojav_launcher", true, 30.0);
- LOGGER.error("It appears that PojavLauncher is being used with an OpenGL compatibility layer. This will " +
- "likely cause severe performance issues, graphical issues, and crashes when used with Sodium. This " +
- "configuration is not supported -- you are on your own!");
+ throw new RuntimeException("It appears that you are using PojavLauncher, which is not supported when " +
+ "using Sodium. Please check your mods list.");
}
}
From d9c20ed93b4fefcd696b83286f430c584ac750c2 Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Wed, 5 Mar 2025 12:58:11 -0600
Subject: [PATCH 061/215] Mark BetterEnd <=21.0.11 as incompatible
BetterEnd illegally accesses the client's World
object from the chunk meshing threads, which causes
memory corruption and cryptic crashes.
These crashes are reported to us frequently and
are difficult for users to debug. Since there is
no workaround for the time being, and it is
unlikely there will be an update on BetterEnd's
part to resolve the issue in the near future,
mark all current versions of the mod as
incompatible.
See #2869 for more information.
---
fabric/src/main/resources/fabric.mod.json | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json
index 4ccd5a11e1..05f43d540e 100644
--- a/fabric/src/main/resources/fabric.mod.json
+++ b/fabric/src/main/resources/fabric.mod.json
@@ -102,7 +102,8 @@
"sodium-extra" : "<0.6.0",
"sspb" : "<4.0.0",
"moreculling": "<1.0.4",
- "simply-no-shading": "<7.6.2"
+ "simply-no-shading": "<7.6.2",
+ "betterend": "<=21.0.11"
},
"provides" : [
"indium"
From ac2579f4ed37616531a93b070ac9d3356a1373a7 Mon Sep 17 00:00:00 2001
From: katie! <136929759+katietheqt@users.noreply.github.com>
Date: Sat, 29 Mar 2025 22:12:29 +0000
Subject: [PATCH 062/215] Add `rendertype_clouds` to the shader program
blacklist (#3063)
---
.../mods/sodium/client/checks/ResourcePackScanner.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/checks/ResourcePackScanner.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/checks/ResourcePackScanner.java
index 6f9ad8117c..ff6be4cb8c 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/checks/ResourcePackScanner.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/checks/ResourcePackScanner.java
@@ -38,7 +38,10 @@ public class ResourcePackScanner {
"rendertype_translucent.json",
"rendertype_tripwire.vsh",
"rendertype_tripwire.fsh",
- "rendertype_tripwire.json"
+ "rendertype_tripwire.json",
+ "rendertype_clouds.vsh",
+ "rendertype_clouds.fsh",
+ "rendertype_clouds.json"
);
private static final Set SHADER_INCLUDE_BLACKLIST = Set.of(
From 737c645dea7b246eda7a7515b231a86befe046e6 Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Thu, 3 Apr 2025 13:35:35 -0500
Subject: [PATCH 063/215] Bump version to 0.6.13
---
buildSrc/src/main/kotlin/BuildConfig.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt
index 4b55391309..4a09090f85 100644
--- a/buildSrc/src/main/kotlin/BuildConfig.kt
+++ b/buildSrc/src/main/kotlin/BuildConfig.kt
@@ -10,7 +10,7 @@ object BuildConfig {
val PARCHMENT_VERSION: String? = "2024.11.17"
// https://semver.org/
- var MOD_VERSION: String = "0.6.9"
+ var MOD_VERSION: String = "0.6.13"
fun createVersionString(project: Project): String {
val builder = StringBuilder()
From 678c4689efe1b45af1ea8593f7136f40ce922e1c Mon Sep 17 00:00:00 2001
From: IMS212
Date: Thu, 3 Apr 2025 12:34:13 -0700
Subject: [PATCH 064/215] Update Forgified Fabric API
---
buildSrc/src/main/kotlin/BuildConfig.kt | 2 +-
neoforge/build.gradle.kts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt
index 4a09090f85..9906d57c02 100644
--- a/buildSrc/src/main/kotlin/BuildConfig.kt
+++ b/buildSrc/src/main/kotlin/BuildConfig.kt
@@ -2,7 +2,7 @@ import org.gradle.api.Project
object BuildConfig {
val MINECRAFT_VERSION: String = "1.21.1"
- val NEOFORGE_VERSION: String = "21.1.90"
+ val NEOFORGE_VERSION: String = "21.1.143"
val FABRIC_LOADER_VERSION: String = "0.16.9"
val FABRIC_API_VERSION: String = "0.110.0+1.21.1"
diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts
index e2703e8483..d9dfb42273 100644
--- a/neoforge/build.gradle.kts
+++ b/neoforge/build.gradle.kts
@@ -54,7 +54,7 @@ dependencies {
}
addEmbeddedFabricModule("org.sinytra.forgified-fabric-api:fabric-api-base:0.4.42+d1308ded19")
- addEmbeddedFabricModule("org.sinytra.forgified-fabric-api:fabric-renderer-api-v1:3.4.0+acb05a3919")
+ addEmbeddedFabricModule("org.sinytra.forgified-fabric-api:fabric-renderer-api-v1:3.4.0+9c40919e19")
addEmbeddedFabricModule("org.sinytra.forgified-fabric-api:fabric-rendering-data-attachment-v1:0.3.48+73761d2e19")
addEmbeddedFabricModule("org.sinytra.forgified-fabric-api:fabric-block-view-api-v2:1.0.10+9afaaf8c19")
From 8672650501117e72f5a809867092378fb5bc908a Mon Sep 17 00:00:00 2001
From: JellySquid
Date: Thu, 3 Apr 2025 18:26:30 -0500
Subject: [PATCH 065/215] Don't allow debug options to be enabled in production
---
.../mods/sodium/client/SodiumClientMod.java | 10 ++++---
.../client/gui/SodiumGameOptionPages.java | 27 +++++--------------
.../sodium/client/gui/SodiumGameOptions.java | 26 ++++++++++++------
.../render/chunk/DefaultChunkRenderer.java | 2 +-
.../render/chunk/RenderSectionManager.java | 4 +--
.../tasks/ChunkBuilderMeshingTask.java | 2 +-
.../TranslucentGeometryCollector.java | 4 +--
.../trigger/SortTriggering.java | 2 +-
.../resources/assets/sodium/lang/en_us.json | 2 --
9 files changed, 38 insertions(+), 41 deletions(-)
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/SodiumClientMod.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/SodiumClientMod.java
index 9dba7b3641..3731c70020 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/SodiumClientMod.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/SodiumClientMod.java
@@ -1,11 +1,11 @@
package net.caffeinemc.mods.sodium.client;
+import net.caffeinemc.mods.sodium.client.console.Console;
+import net.caffeinemc.mods.sodium.client.console.message.MessageLevel;
import net.caffeinemc.mods.sodium.client.data.fingerprint.FingerprintMeasure;
import net.caffeinemc.mods.sodium.client.data.fingerprint.HashedFingerprint;
import net.caffeinemc.mods.sodium.client.gui.SodiumGameOptions;
-import net.caffeinemc.mods.sodium.client.console.Console;
-import net.caffeinemc.mods.sodium.client.console.message.MessageLevel;
-import net.minecraft.network.chat.Component;
+import net.caffeinemc.mods.sodium.client.services.PlatformRuntimeInformation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -107,4 +107,8 @@ private static void updateFingerprint() {
}
}
}
+
+ public static boolean allowDebuggingOptions() {
+ return PlatformRuntimeInformation.getInstance().isDevelopmentEnvironment();
+ }
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/SodiumGameOptionPages.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/SodiumGameOptionPages.java
index b97e3fa433..1c0e355aba 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/SodiumGameOptionPages.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/SodiumGameOptionPages.java
@@ -6,20 +6,18 @@
import com.mojang.blaze3d.platform.VideoMode;
import com.mojang.blaze3d.platform.Window;
import net.caffeinemc.mods.sodium.client.compatibility.environment.OsUtils;
+import net.caffeinemc.mods.sodium.client.compatibility.workarounds.Workarounds;
import net.caffeinemc.mods.sodium.client.gl.arena.staging.MappedStagingBuffer;
import net.caffeinemc.mods.sodium.client.gl.device.RenderDevice;
import net.caffeinemc.mods.sodium.client.gui.options.*;
import net.caffeinemc.mods.sodium.client.gui.options.binding.compat.VanillaBooleanOptionBinding;
-import net.caffeinemc.mods.sodium.client.gui.options.control.*;
+import net.caffeinemc.mods.sodium.client.gui.options.control.ControlValueFormatter;
+import net.caffeinemc.mods.sodium.client.gui.options.control.CyclingControl;
+import net.caffeinemc.mods.sodium.client.gui.options.control.SliderControl;
+import net.caffeinemc.mods.sodium.client.gui.options.control.TickBoxControl;
import net.caffeinemc.mods.sodium.client.gui.options.storage.MinecraftOptionsStorage;
import net.caffeinemc.mods.sodium.client.gui.options.storage.SodiumOptionsStorage;
-import net.caffeinemc.mods.sodium.client.compatibility.workarounds.Workarounds;
-import net.caffeinemc.mods.sodium.client.services.PlatformRuntimeInformation;
-import net.minecraft.client.AttackIndicatorStatus;
-import net.minecraft.client.CloudStatus;
-import net.minecraft.client.GraphicsStatus;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.ParticleStatus;
+import net.minecraft.client.*;
import net.minecraft.network.chat.Component;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GLCapabilities;
@@ -336,19 +334,6 @@ public static OptionPage performance() {
.build())
.build());
- if (PlatformRuntimeInformation.getInstance().isDevelopmentEnvironment()) {
- groups.add(OptionGroup.createBuilder()
- .add(OptionImpl.createBuilder(boolean.class, sodiumOpts)
- .setName(Component.translatable("sodium.options.sort_behavior.name"))
- .setTooltip(Component.translatable("sodium.options.sort_behavior.tooltip"))
- .setControl(TickBoxControl::new)
- .setBinding((opts, value) -> opts.performance.sortingEnabled = value, opts -> opts.performance.sortingEnabled)
- .setImpact(OptionImpact.LOW)
- .setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD)
- .build())
- .build());
- }
-
return new OptionPage(Component.translatable("sodium.options.pages.performance"), ImmutableList.copyOf(groups));
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/SodiumGameOptions.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/SodiumGameOptions.java
index ec681430b8..0fa4bc88fb 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/SodiumGameOptions.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/SodiumGameOptions.java
@@ -5,11 +5,13 @@
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
import net.caffeinemc.mods.sodium.client.gui.options.TextProvider;
+import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.SortBehavior;
import net.caffeinemc.mods.sodium.client.services.PlatformRuntimeInformation;
import net.caffeinemc.mods.sodium.client.util.FileUtil;
-import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.SortBehavior;
import net.minecraft.client.GraphicsStatus;
import net.minecraft.network.chat.Component;
+import org.jetbrains.annotations.NotNull;
+
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Modifier;
@@ -24,6 +26,7 @@ public class SodiumGameOptions {
public final AdvancedSettings advanced = new AdvancedSettings();
public final PerformanceSettings performance = new PerformanceSettings();
public final NotificationSettings notifications = new NotificationSettings();
+ public @NotNull DebugSettings debug = new DebugSettings();
private boolean readOnly;
@@ -45,13 +48,6 @@ public static class PerformanceSettings {
public boolean useFogOcclusion = true;
public boolean useBlockFaceCulling = true;
public boolean useNoErrorGLContext = true;
-
- @SerializedName("sorting_enabled_v2") // reset the older option in configs before we started hiding it
- public boolean sortingEnabled = true;
-
- public SortBehavior getSortBehavior() {
- return this.sortingEnabled ? SortBehavior.DYNAMIC_DEFER_NEARBY_ZERO_FRAMES : SortBehavior.OFF;
- }
}
public static class AdvancedSettings {
@@ -61,6 +57,20 @@ public static class AdvancedSettings {
public int cpuRenderAheadLimit = 3;
}
+ public static class DebugSettings {
+ public boolean terrainSortingEnabled = true;
+
+ @Deprecated(forRemoval = true)
+ public SortBehavior getSortBehavior() {
+ // TODO: This logic should not exist here, we need to move it into renderer initialization
+ if (PlatformRuntimeInformation.getInstance().isDevelopmentEnvironment()) {
+ return this.terrainSortingEnabled ? SortBehavior.DYNAMIC_DEFER_NEARBY_ZERO_FRAMES : SortBehavior.OFF;
+ }
+
+ return SortBehavior.DYNAMIC_DEFER_NEARBY_ZERO_FRAMES;
+ }
+ }
+
public static class QualitySettings {
public GraphicsQuality weatherQuality = GraphicsQuality.DEFAULT;
public GraphicsQuality leavesQuality = GraphicsQuality.DEFAULT;
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java
index 1d1165c705..e2c9d16f8d 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java
@@ -101,7 +101,7 @@ public void render(ChunkRenderMatrices matrices,
}
private static boolean isTranslucentRenderPass(TerrainRenderPass renderPass) {
- return renderPass.isTranslucent() && SodiumClientMod.options().performance.getSortBehavior() != SortBehavior.OFF;
+ return renderPass.isTranslucent() && SodiumClientMod.options().debug.getSortBehavior() != SortBehavior.OFF;
}
private static void fillCommandBuffer(MultiDrawBatch batch,
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager.java
index b955b6b08a..2644c5430f 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/RenderSectionManager.java
@@ -415,7 +415,7 @@ public void updateChunks(boolean updateImmediately) {
// if zero frame delay is allowed, submit important sorts with the current frame blocking collector.
// otherwise submit with the collector that the next frame is blocking on.
- if (SodiumClientMod.options().performance.getSortBehavior().getDeferMode() == DeferMode.ZERO_FRAMES) {
+ if (SodiumClientMod.options().debug.getSortBehavior().getDeferMode() == DeferMode.ZERO_FRAMES) {
this.submitSectionTasks(thisFrameBlockingCollector, nextFrameBlockingCollector, deferredCollector);
} else {
this.submitSectionTasks(nextFrameBlockingCollector, nextFrameBlockingCollector, deferredCollector);
@@ -577,7 +577,7 @@ public void scheduleSort(long sectionPos, boolean isDirectTrigger) {
if (section != null) {
var pendingUpdate = ChunkUpdateType.SORT;
- var priorityMode = SodiumClientMod.options().performance.getSortBehavior().getPriorityMode();
+ var priorityMode = SodiumClientMod.options().debug.getSortBehavior().getPriorityMode();
if (priorityMode == PriorityMode.ALL
|| priorityMode == PriorityMode.NEARBY && this.shouldPrioritizeTask(section, NEARBY_SORT_DISTANCE)) {
pendingUpdate = ChunkUpdateType.IMPORTANT_SORT;
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/tasks/ChunkBuilderMeshingTask.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/tasks/ChunkBuilderMeshingTask.java
index f3992c935a..64b85e6a70 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/tasks/ChunkBuilderMeshingTask.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/tasks/ChunkBuilderMeshingTask.java
@@ -81,7 +81,7 @@ public ChunkBuildOutput execute(ChunkBuildContext buildContext, CancellationToke
BlockPos.MutableBlockPos modelOffset = new BlockPos.MutableBlockPos();
TranslucentGeometryCollector collector;
- if (SodiumClientMod.options().performance.getSortBehavior() != SortBehavior.OFF) {
+ if (SodiumClientMod.options().debug.getSortBehavior() != SortBehavior.OFF) {
collector = new TranslucentGeometryCollector(render.getPosition());
} else {
collector = null;
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/TranslucentGeometryCollector.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/TranslucentGeometryCollector.java
index 2125b23b45..6c02bc1fa8 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/TranslucentGeometryCollector.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/TranslucentGeometryCollector.java
@@ -284,7 +284,7 @@ public void appendQuad(int packedNormal, ChunkVertexEncoder.Vertex[] vertices, M
* @param sortType the sort type to filter
*/
private static SortType filterSortType(SortType sortType) {
- SortBehavior sortBehavior = SodiumClientMod.options().performance.getSortBehavior();
+ SortBehavior sortBehavior = SodiumClientMod.options().debug.getSortBehavior();
switch (sortBehavior) {
case OFF:
return SortType.NONE;
@@ -348,7 +348,7 @@ private SortType sortTypeHeuristic() {
return SortType.NONE;
}
- SortBehavior sortBehavior = SodiumClientMod.options().performance.getSortBehavior();
+ SortBehavior sortBehavior = SodiumClientMod.options().debug.getSortBehavior();
if (sortBehavior.getSortMode() == SortBehavior.SortMode.NONE) {
return SortType.NONE;
}
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/trigger/SortTriggering.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/trigger/SortTriggering.java
index b58cd10aa7..b5c33809c5 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/trigger/SortTriggering.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/trigger/SortTriggering.java
@@ -224,7 +224,7 @@ public void integrateTranslucentData(TranslucentData oldData, TranslucentData ne
}
public void addDebugStrings(List list) {
- var sortBehavior = SodiumClientMod.options().performance.getSortBehavior();
+ var sortBehavior = SodiumClientMod.options().debug.getSortBehavior();
if (sortBehavior.getSortMode() == SortBehavior.SortMode.NONE) {
list.add("TS OFF");
} else {
diff --git a/common/src/main/resources/assets/sodium/lang/en_us.json b/common/src/main/resources/assets/sodium/lang/en_us.json
index 4ab5645094..7651c158c5 100644
--- a/common/src/main/resources/assets/sodium/lang/en_us.json
+++ b/common/src/main/resources/assets/sodium/lang/en_us.json
@@ -50,8 +50,6 @@
"sodium.options.chunk_update_threads.tooltip": "Specifies the number of threads to use for chunk building and sorting. Using more threads can speed up chunk loading and update speed, but may negatively impact frame times. The default value is usually good enough for all situations.",
"sodium.options.always_defer_chunk_updates.name": "Always Defer Chunk Updates",
"sodium.options.always_defer_chunk_updates.tooltip": "If enabled, rendering will never wait for chunk updates to finish, even if they are important. This can greatly improve frame rates in some scenarios, but it may create significant visual lag where blocks take a while to appear or disappear.",
- "sodium.options.sort_behavior.name": "Translucency Sorting",
- "sodium.options.sort_behavior.tooltip": "Enables translucency sorting. This avoids glitches in translucent blocks like water and glass when enabled and attempts to correctly present them even when the camera is in motion. This has a small performance impact on chunk loading and update speeds, but is usually not noticeable in frame rates.",
"sodium.options.use_no_error_context.name": "Use No Error Context",
"sodium.options.use_no_error_context.tooltip": "When enabled, the OpenGL context will be created with error checking disabled. This slightly improves rendering performance, but it can make debugging sudden unexplained crashes much harder.",
"sodium.options.buttons.undo": "Undo",
From 7b7f0d44a1f0e62c2e98f01e7834ecec94954e4a Mon Sep 17 00:00:00 2001
From: coco875 <59367621+coco875@users.noreply.github.com>
Date: Thu, 24 Jul 2025 19:36:44 +0000
Subject: [PATCH 066/215] Use default classloader when resolving shader sources
(#3132)
This allows other mods to replace these sources more easily, even though doing so is still strictly unsupported.
---
.../caffeinemc/mods/sodium/client/gl/shader/ShaderLoader.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/ShaderLoader.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/ShaderLoader.java
index 03d04c0e97..302347fca3 100644
--- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/ShaderLoader.java
+++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/ShaderLoader.java
@@ -25,7 +25,7 @@ public static GlShader loadShader(ShaderType type, ResourceLocation name, Shader
public static String getShaderSource(ResourceLocation name) {
String path = String.format("/assets/%s/shaders/%s", name.getNamespace(), name.getPath());
- try (InputStream in = ShaderLoader.class.getResourceAsStream(path)) {
+ try (InputStream in = ShaderLoader.class.getClassLoader().getResourceAsStream(path)) {
if (in == null) {
throw new RuntimeException("Shader not found: " + path);
}
From 58ab808ac8a0b0f72979a8cf3fca9a851a2204a0 Mon Sep 17 00:00:00 2001
From: douira
Date: Sat, 2 May 2026 23:22:19 +0200
Subject: [PATCH 067/215] Backport: Add modern publishing infrastructure
---
.editorconfig | 2 +-
.github/CODEOWNERS | 2 +
...ild-tag.yml => build-commit-nopublish.yml} | 25 ++---
.github/workflows/build-commit.yml | 27 ++++--
.github/workflows/build-pull-request.yml | 20 ++--
.github/workflows/build-release.yml | 32 -------
.github/workflows/publish-release.yml | 65 +++++++++++++
.gitignore | 3 +
CHANGELOG.md | 7 ++
CONTRIBUTING.md | 6 +-
README.md | 14 +--
build.gradle.kts | 87 ++++++++++++++++++
buildSrc/src/main/kotlin/BuildConfig.kt | 34 +++++--
.../kotlin/multiloader-platform.gradle.kts | 26 ++++--
common/build.gradle.kts | 2 +-
fabric/build.gradle.kts | 2 +-
gradle/wrapper/gradle-wrapper.jar | Bin 43504 -> 48966 bytes
gradle/wrapper/gradle-wrapper.properties | 2 +-
gradlew | 14 +--
gradlew.bat | 3 +-
neoforge/build.gradle.kts | 2 +-
settings.gradle.kts | 1 +
22 files changed, 278 insertions(+), 98 deletions(-)
create mode 100644 .github/CODEOWNERS
rename .github/workflows/{build-tag.yml => build-commit-nopublish.yml} (63%)
delete mode 100644 .github/workflows/build-release.yml
create mode 100644 .github/workflows/publish-release.yml
create mode 100644 CHANGELOG.md
diff --git a/.editorconfig b/.editorconfig
index 6fdb37b49c..c2362ce336 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -548,7 +548,7 @@ ij_json_keep_indents_on_empty_lines = false
ij_json_keep_line_breaks = true
ij_json_space_after_colon = true
ij_json_space_after_comma = true
-ij_json_space_before_colon = true
+ij_json_space_before_colon = false
ij_json_space_before_comma = false
ij_json_spaces_within_braces = false
ij_json_spaces_within_brackets = false
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000000..6c889429c3
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,2 @@
+/.github/CODEOWNERS @jellysquid3
+/.github/workflows @jellysquid3
diff --git a/.github/workflows/build-tag.yml b/.github/workflows/build-commit-nopublish.yml
similarity index 63%
rename from .github/workflows/build-tag.yml
rename to .github/workflows/build-commit-nopublish.yml
index 478c3b3d2b..38f050550e 100644
--- a/.github/workflows/build-tag.yml
+++ b/.github/workflows/build-commit-nopublish.yml
@@ -1,11 +1,11 @@
-# Used when a commit is tagged and pushed to the repository
+# Used when a commit is pushed to the repository
# This makes use of caching for faster builds and uploads the resulting artifacts
-name: build-tag
+name: build-commit-nopublish
on:
push:
- tags:
- - '*'
+ branches-ignore:
+ - dev
jobs:
build:
@@ -17,23 +17,26 @@ jobs:
# bash pattern expansion to grab branch name without slashes
run: ref="${GITHUB_REF#refs/heads/}" && echo "branch=${ref////-}" >> $GITHUB_OUTPUT
id: ref
+
- name: Checkout sources
- uses: actions/checkout@v4
- - uses: actions/setup-java@v4
+ uses: actions/checkout@v6
+
+ - name: Setup Java 21
+ uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
- name: Setup Gradle
- uses: gradle/actions/setup-gradle@v4
+ uses: gradle/actions/setup-gradle@v5
with:
- cache-read-only: true
+ cache-read-only: false
- name: Execute Gradle build
- run: ./gradlew build -Pbuild.release=true
+ run: ./gradlew build
- name: Upload artifacts
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: sodium-artifacts-${{ steps.ref.outputs.branch }}
- path: build/mods/*.jar
\ No newline at end of file
+ path: build/mods/*.jar
diff --git a/.github/workflows/build-commit.yml b/.github/workflows/build-commit.yml
index b73702a561..cd737b6d7a 100644
--- a/.github/workflows/build-commit.yml
+++ b/.github/workflows/build-commit.yml
@@ -2,11 +2,15 @@
# This makes use of caching for faster builds and uploads the resulting artifacts
name: build-commit
-on: [ push ]
+on:
+ push:
+ branches:
+ - dev
jobs:
build:
runs-on: ubuntu-latest
+ environment: staging
steps:
- name: Extract current branch name
@@ -14,20 +18,18 @@ jobs:
# bash pattern expansion to grab branch name without slashes
run: ref="${GITHUB_REF#refs/heads/}" && echo "branch=${ref////-}" >> $GITHUB_OUTPUT
id: ref
- - name: Checkout sources
- uses: actions/checkout@v4
- - name: Validate Gradle Wrapper
- uses: gradle/actions/wrapper-validation@v3
+ - name: Checkout sources
+ uses: actions/checkout@v6
- name: Setup Java 21
- uses: actions/setup-java@v4
+ uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
- name: Setup Gradle
- uses: gradle/actions/setup-gradle@v4
+ uses: gradle/actions/setup-gradle@v5
with:
cache-read-only: false
@@ -35,7 +37,14 @@ jobs:
run: ./gradlew build
- name: Upload artifacts
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: sodium-artifacts-${{ steps.ref.outputs.branch }}
- path: build/mods/*.jar
\ No newline at end of file
+ path: build/mods/*.jar
+
+ - name: Publish Release Snapshot to CaffeineMC Maven
+ env:
+ ORG_GRADLE_PROJECT_caffeineMCMavenUsername: ${{ secrets.CAFFEINEMC_MAVEN_USERNAME }}
+ ORG_GRADLE_PROJECT_caffeineMCMavenPassword: ${{ secrets.CAFFEINEMC_MAVEN_PASSWORD }}
+ if: ${{ env.ORG_GRADLE_PROJECT_caffeineMCMavenUsername != '' && env.ORG_GRADLE_PROJECT_caffeineMCMavenPassword != '' }}
+ run: ./gradlew publishAllPublicationsToCaffeineMCRepository
diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml
index 045dd53920..2ae9dc38fc 100644
--- a/.github/workflows/build-pull-request.yml
+++ b/.github/workflows/build-pull-request.yml
@@ -9,15 +9,23 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
- - uses: gradle/actions/wrapper-validation@v3
- - uses: actions/setup-java@v4
+ - name: Extract current branch name
+ shell: bash
+ # bash pattern expansion to grab branch name without slashes
+ run: ref="${GITHUB_REF#refs/heads/}" && echo "branch=${ref////-}" >> $GITHUB_OUTPUT
+ id: ref
+
+ - name: Checkout sources
+ uses: actions/checkout@v6
+
+ - name: Setup Java 21
+ uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
- name: Setup Gradle
- uses: gradle/actions/setup-gradle@v4
+ uses: gradle/actions/setup-gradle@v5
with:
cache-read-only: true
@@ -25,7 +33,7 @@ jobs:
run: ./gradlew build
- name: Upload artifacts
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: sodium-artifacts-${{ steps.ref.outputs.branch }}
- path: build/mods/*.jar
\ No newline at end of file
+ path: build/mods/*.jar
diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml
deleted file mode 100644
index ab751d49b9..0000000000
--- a/.github/workflows/build-release.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-# Used when a release is pushed to GitHub
-# This does not make use of any caching as to ensure a clean build
-name: build-release
-
-on:
- release:
- types:
- - published
-
-jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-java@v4
- with:
- distribution: temurin
- java-version: 21
-
- - name: Setup Gradle
- uses: gradle/actions/setup-gradle@v4
- with:
- cache-read-only: true
-
- - name: Execute Gradle build
- run: ./gradlew build -Pbuild.release=true
-
- - name: Upload assets to GitHub
- uses: AButler/upload-release-assets@v2.0
- with:
- files: 'build/mods/*.jar'
- repo-token: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml
new file mode 100644
index 0000000000..7fbe0020d6
--- /dev/null
+++ b/.github/workflows/publish-release.yml
@@ -0,0 +1,65 @@
+# Used when a developer decides to publish a release
+# This makes use of caching for faster builds and uploads the resulting artifacts
+name: Release GH+MR+CF
+permissions:
+ contents: write # Needed to publish a GitHub release
+
+on:
+ workflow_dispatch:
+ inputs:
+ platform:
+ type: choice
+ description: Platform
+ options:
+ - both
+ - fabric
+ - neoforge
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ environment:
+ name: prod
+
+ steps:
+ - name: Extract current branch name
+ shell: bash
+ # bash pattern expansion to grab branch name without slashes
+ run: ref="${GITHUB_REF#refs/heads/}" && echo "branch=${ref////-}" >> $GITHUB_OUTPUT
+ id: ref
+
+ - name: Checkout sources
+ uses: actions/checkout@v6
+
+ - uses: actions/setup-java@v5
+ with:
+ distribution: temurin
+ java-version: 21
+
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v5
+ with:
+ cache-read-only: true
+
+ - name: Execute Gradle build
+ run: ./gradlew build -Pbuild.release=true
+
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: sodium-artifacts-${{ steps.ref.outputs.branch }}
+ path: build/mods/*.jar
+
+ - name: Publish Modrinth, Curseforge and Github Releases
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ CURSEFORGE_API_KEY: ${{ secrets.CURSEFORGE_API_KEY }}
+ MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
+ run: ./gradlew publishMods -Pbuild.release=true -Pbuild.release.platform=${{ inputs.platform }}
+
+ - name: Publish Tag Release to CaffeineMC Maven
+ env:
+ ORG_GRADLE_PROJECT_caffeineMCMavenUsername: ${{ secrets.CAFFEINEMC_MAVEN_USERNAME }}
+ ORG_GRADLE_PROJECT_caffeineMCMavenPassword: ${{ secrets.CAFFEINEMC_MAVEN_PASSWORD }}
+ if: ${{ env.ORG_GRADLE_PROJECT_caffeineMCMavenUsername != '' && env.ORG_GRADLE_PROJECT_caffeineMCMavenPassword != '' }}
+ run: ./gradlew publishAllPublicationsToCaffeineMCRepository -Pbuild.release=true
diff --git a/.gitignore b/.gitignore
index 69cd50978c..ec97f0641b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,3 +29,6 @@ neoforge/runs
.DS_Store
.AppleDouble
.LSOverride
+
+# Kotlin compiler working directory
+.kotlin
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000000..1df59e9278
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,7 @@
+[ReleaseTag]() is automatically replaced with the release tag, e.g. mc26.1-0.8.9
+[MCVersion]() is automatically replaced with the minecraft version, e.g. 26.1
+[SodiumVersion]() is automatically replaced with the sodium version, e.g. 0.8.9
+Everything above the line is ignored and not included in the changelog. Everything below will be in the
+changelog on GitHub, Modrinth and CurseForge.
+----------
+Sodium [SodiumVersion]() fixes some bugs and updates to the latest version of NeoForge.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 60221b425c..9ca9757920 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -3,6 +3,10 @@
When submitting a pull request, you are granting [JellySquid](https://jellysquid.me) the right to license
your contributions under the [Polyform Shield License (Version 1.0.0)](LICENSE.md).
+Without exception, it is required that all code being submitted to the project is of your original work. We
+will not accept pull requests which contain *any amount* of AI-generated code, regardless of the particular
+circumstances.
+
If you have any questions about these terms, please [get in contact with us](https://caffeinemc.net/discord).
### Code Style
@@ -56,4 +60,4 @@ style guidelines.
If you're adding new Mixin patches to the project, please ensure that you have created appropriate entries to disable
them in the config file. Mixins should always be self-contained and grouped into "patch sets" which are easy to isolate,
-and where that is not possible, they should be placed into the "core" package.
\ No newline at end of file
+and where that is not possible, they should be placed into the "core" package.
diff --git a/README.md b/README.md
index e8af77f8ca..ab9929ea6a 100644
--- a/README.md
+++ b/README.md
@@ -23,14 +23,10 @@ The latest stable release of Sodium can be downloaded from our official [Modrint
#### Nightly builds (for developers)
We also provide bleeding-edge builds ("nightlies") which are useful for testing the very latest changes before they're
-packaged into a release. These builds are only provided for other mod developers and users with expert skills, and do
-not come with any support or warranty. It is often the case they have issues and lack compatibility with other mods.
+packaged into a release. These builds are primarily intended for other mod developers and users with expert skills, and do
+not come with any support or warranty.
-The latest nightly build for each current branch of development can be downloaded below.
-
-- Minecraft 1.21.4 (latest): [Download nightly](https://nightly.link/CaffeineMC/sodium/workflows/build-commit/dev/sodium-artifacts-dev.zip) or [View all builds](https://github.com/CaffeineMC/sodium/actions/workflows/build-commit.yml?query=branch%3Adev)
-- Minecraft 1.21.3: [Download nightly](https://nightly.link/CaffeineMC/sodium/workflows/build-commit/1.21.3%2Fstable/sodium-artifacts-1.21.3-stable.zip) or [View all builds](https://github.com/CaffeineMC/sodium/actions/workflows/build-commit.yml?query=branch%3A1.21.3%2Fstable)
-- Minecraft 1.21.1: [Download nightly](https://nightly.link/CaffeineMC/sodium/workflows/build-commit/1.21.1%2Fstable/sodium-artifacts-1.21.1-stable.zip) or [View all builds](https://github.com/CaffeineMC/sodium/actions/workflows/build-commit.yml?query=branch%3A1.21.1%2Fstable)
+For a complete listing of available nightly builds, please see [the wiki page](https://github.com/CaffeineMC/sodium/wiki/Nightly-Builds). We also have a Maven repository for including Sodium in your development workspace or build process, for which you can also find [documentation on our wiki](https://github.com/CaffeineMC/sodium/wiki/CaffeineMC-Maven-&-Config-API).
### 🖥️ Installation
@@ -77,8 +73,8 @@ not work with future versions of Sodium.
#### OpenGL Compatibility Layers
-Devices which need to use OpenGL translation layers (such as GL4ES, ANGLE, etc) are not supported and will very likely
-not work with Sodium. These translation layers do not implement required functionality and they suffer from underlying
+Devices which need to use OpenGL translation layers (such as GL4ES, ANGLE, etc.) are not supported and will very likely
+not work with Sodium. These translation layers do not implement required functionality, and they suffer from underlying
driver bugs which cannot be worked around.
## 🛠️ Building from sources
diff --git a/build.gradle.kts b/build.gradle.kts
index e69de29bb2..fb1b8fe2cc 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -0,0 +1,87 @@
+import me.modmuss50.mpp.ReleaseType
+import me.modmuss50.mpp.platforms.curseforge.CurseforgeOptions
+import me.modmuss50.mpp.platforms.modrinth.ModrinthOptions
+import java.util.*
+
+plugins {
+ id("me.modmuss50.mod-publish-plugin") version("1.1.0")
+}
+
+gradle.projectsEvaluated {
+ publishMods {
+ if (!project.hasProperty("build.release")) {
+ return@publishMods println("Publishing is disabled, please use the CI publishing workflow")
+ }
+
+ val releasePlatform: String = project.providers.gradleProperty("build.release.platform").orNull
+ ?: return@publishMods println("build.release.platform must be defined (expected: both, fabric, neoforge)")
+
+ val modVersion = BuildConfig.createVersionString(project);
+
+ type = when {
+ modVersion.contains("alpha") -> ReleaseType.ALPHA
+ modVersion.contains("beta") -> ReleaseType.BETA
+ else -> ReleaseType.STABLE
+ }
+ changelog = BuildConfig.getChangelog(project)
+
+ val curseforgeShared = curseforgeOptions {
+ accessToken = project.providers.environmentVariable("CURSEFORGE_API_KEY")
+ projectId = BuildConfig.CURSEFORGE_PROJECT_ID
+ minecraftVersions.add(BuildConfig.MINECRAFT_VERSION)
+ }
+
+ val modrinthShared = modrinthOptions {
+ accessToken = project.providers.environmentVariable("MODRINTH_API_KEY")
+ projectId = BuildConfig.MODRINTH_PROJECT_ID
+ minecraftVersions.add(BuildConfig.MINECRAFT_VERSION)
+ }
+
+ setupFor("Fabric", releasePlatform, curseforgeShared, modrinthShared)
+ setupFor("NeoForge", releasePlatform, curseforgeShared, modrinthShared)
+
+ github {
+ accessToken = project.providers.environmentVariable("GITHUB_TOKEN")
+ repository = "CaffeineMC/sodium"
+ commitish = BuildConfig.calculateGitHash(project)
+ version = BuildConfig.RELEASE_TAG
+ displayName = "Sodium ${BuildConfig.MOD_VERSION} for Minecraft ${BuildConfig.MINECRAFT_VERSION}"
+ file.unset()
+ file.unsetConvention()
+
+ allowEmptyFiles = true
+ }
+ }
+}
+
+fun me.modmuss50.mpp.ModPublishExtension.setupFor(loaderName: String, releasePlatform: String, curseforgeOptions: Provider, modrinthOptions: Provider) {
+ val loaderLowercase = loaderName.lowercase(Locale.ROOT)
+
+ if (releasePlatform == "both" || releasePlatform == loaderLowercase) {
+ val jar = project(":$loaderLowercase").tasks.named("jar").get().archiveFile
+
+ val releaseTitle = "Sodium ${BuildConfig.MOD_VERSION} for $loaderName ${BuildConfig.MINECRAFT_VERSION}"
+ val releaseVersion = "${BuildConfig.RELEASE_TAG}-$loaderLowercase"
+
+ curseforge("curseforge$loaderName") {
+ from(curseforgeOptions)
+
+ file.set(jar)
+ displayName = releaseTitle
+ version = releaseVersion
+ modLoaders.add(loaderLowercase)
+
+ clientRequired = true
+ serverRequired = false
+ }
+
+ modrinth("modrinth$loaderName") {
+ from(modrinthOptions)
+
+ file.set(jar)
+ displayName = releaseTitle
+ version = releaseVersion
+ modLoaders.add(loaderLowercase)
+ }
+ }
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt
index 9906d57c02..3b37071f01 100644
--- a/buildSrc/src/main/kotlin/BuildConfig.kt
+++ b/buildSrc/src/main/kotlin/BuildConfig.kt
@@ -2,15 +2,20 @@ import org.gradle.api.Project
object BuildConfig {
val MINECRAFT_VERSION: String = "1.21.1"
- val NEOFORGE_VERSION: String = "21.1.143"
- val FABRIC_LOADER_VERSION: String = "0.16.9"
- val FABRIC_API_VERSION: String = "0.110.0+1.21.1"
+ val NEOFORGE_VERSION: String = "21.1.228"
+ val FABRIC_LOADER_VERSION: String = "0.19.2"
+ val FABRIC_API_VERSION: String = "0.116.11+1.21.1"
// This value can be set to null to disable Parchment.
val PARCHMENT_VERSION: String? = "2024.11.17"
// https://semver.org/
- var MOD_VERSION: String = "0.6.13"
+ val MOD_VERSION: String = "0.8.11"
+
+ val RELEASE_TAG: String = "mc$MINECRAFT_VERSION-$MOD_VERSION"
+
+ val CURSEFORGE_PROJECT_ID = "394468"
+ val MODRINTH_PROJECT_ID = "AANobbMI"
fun createVersionString(project: Project): String {
val builder = StringBuilder()
@@ -22,7 +27,7 @@ object BuildConfig {
builder.append(MOD_VERSION)
} else {
builder.append(MOD_VERSION.substringBefore('-'))
- builder.append("-snapshot")
+ builder.append("-SNAPSHOT")
}
builder.append("+mc").append(MINECRAFT_VERSION)
@@ -37,4 +42,21 @@ object BuildConfig {
return builder.toString()
}
-}
\ No newline at end of file
+
+ fun calculateGitHash(project: Project): String = try {
+ val output = project.providers.exec {
+ workingDir(project.projectDir)
+ commandLine("git", "rev-parse", "HEAD")
+ }
+ output.standardOutput.asText.get().trim()
+ } catch (_: Throwable) {
+ "unknown"
+ }
+
+ fun getChangelog(project: Project): String = project.rootProject.file("CHANGELOG.md").readText()
+ .split("----------")[1]
+ .trim()
+ .replace("[ReleaseTag]()", RELEASE_TAG)
+ .replace("[MCVersion]()", MINECRAFT_VERSION)
+ .replace("[SodiumVersion]()", MOD_VERSION)
+}
diff --git a/buildSrc/src/main/kotlin/multiloader-platform.gradle.kts b/buildSrc/src/main/kotlin/multiloader-platform.gradle.kts
index 006f9f3500..55b89b8cba 100644
--- a/buildSrc/src/main/kotlin/multiloader-platform.gradle.kts
+++ b/buildSrc/src/main/kotlin/multiloader-platform.gradle.kts
@@ -16,7 +16,7 @@ tasks {
inputs.property("version", version)
filesMatching(listOf("fabric.mod.json", "META-INF/neoforge.mods.toml")) {
- expand(mapOf("version" to version))
+ expand(mapOf("version" to inputs.properties["version"]))
}
}
@@ -31,13 +31,23 @@ tasks {
}
publishing {
- publications {
- create("maven") {
- groupId = project.group as String
- artifactId = project.name as String
- version = version
-
- from(components["java"])
+ // Each platform is responsible for their own "publications".
+
+ repositories {
+ val isReleaseBuild = project.hasProperty("build.release")
+ val caffeineMCMavenUsername: String? by project // reads from ORG_GRADLE_PROJECT_caffeineMCMavenUsername
+ val caffeineMCMavenPassword: String? by project // reads from ORG_GRADLE_PROJECT_caffeineMCMavenPassword
+
+ maven {
+ name = "CaffeineMC"
+ url = uri("https://maven.caffeinemc.net".let {
+ if (isReleaseBuild) "$it/releases" else "$it/snapshots"
+ })
+
+ credentials {
+ username = caffeineMCMavenUsername
+ password = caffeineMCMavenPassword
+ }
}
}
}
diff --git a/common/build.gradle.kts b/common/build.gradle.kts
index c56c417140..c57f91ebcc 100644
--- a/common/build.gradle.kts
+++ b/common/build.gradle.kts
@@ -2,7 +2,7 @@ plugins {
id("multiloader-base")
id("java-library")
- id("fabric-loom") version ("1.8.9")
+ id("net.fabricmc.fabric-loom-remap") version ("1.16.1")
}
base {
diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts
index d8c96b3940..58c79218ab 100644
--- a/fabric/build.gradle.kts
+++ b/fabric/build.gradle.kts
@@ -1,7 +1,7 @@
plugins {
id("multiloader-platform")
- id("fabric-loom") version ("1.8.9")
+ id("net.fabricmc.fabric-loom-remap") version ("1.16.1")
}
base {
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 2c3521197d7c4586c843d1d3e9090525f1898cde..d997cfc60f4cff0e7451d19d49a82fa986695d07 100644
GIT binary patch
delta 40693
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Ðt5p(LLtXn?pxm3OZHd|13r);5)1uCW40m{;j
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