From 5545895d77f9a8f38bf936ba19a253abf36d92e7 Mon Sep 17 00:00:00 2001 From: jellysquid3 Date: Sat, 20 Mar 2021 18:04:12 -0500 Subject: [PATCH 01/13] change: Tag build artifacts more thoroughly The mod's version string now includes extra information about the sources used to build the mod. If available, it will include the checked out revision in Git and whether or not the source tree was dirty. If no information about the build can be determined, the identifier "unknown" will be used. This is being done because too many players, against our recommendation, are downloading CI artifacts or compiling the mod themselves for daily use, and are unable to provide any information about where the build came from when they inevitably ask for technical support. Not having this information available to us makes it impossible to diagnose issues over time and creates significant burden. In the future, this information will be presented in the F3 screen. --- .github/workflows/gradle.yml | 2 +- .github/workflows/publish.yml | 4 +- build.gradle | 70 ++++++++++++++++++----------------- 3 files changed, 39 insertions(+), 37 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 4869220e4e..1273a9eaff 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -12,7 +12,7 @@ jobs: uses: actions/setup-java@v1 with: java-version: 8 - - name: Build with Gradle + - name: Build artifacts run: ./gradlew build - name: Upload build artifacts uses: actions/upload-artifact@v1 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b8ab528dc5..f51c04056d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,10 +15,8 @@ jobs: uses: actions/setup-java@v1 with: java-version: 8 - - name: Upload assets to CurseForge + - name: Build artifacts run: ./gradlew build - env: - BUILD_RELEASE: ${{ github.event.prerelease == false }} - name: Upload assets to GitHub uses: AButler/upload-release-assets@v2.0 with: diff --git a/build.gradle b/build.gradle index d8d8458238..8a87a421a7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,25 +1,15 @@ plugins { - id 'fabric-loom' version '0.5.28' + id 'fabric-loom' version '0.6-SNAPSHOT' + id 'org.ajoberstar.grgit' version '4.1.0' } sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 archivesBaseName = "${project.archives_base_name}-mc${project.minecraft_version}" -version = project.mod_version +version = "${project.mod_version}+${getVersionMetadata()}" group = project.maven_group -def build_release = System.getenv("BUILD_RELEASE") == "true" -def build_id = System.getenv("BUILD_ID") - -if (!build_release) { - version += "-SNAPSHOT" -} - -if (build_id != null) { - version += "+build.${build_id}" -} - minecraft { refmapName = "mixins.sodium.refmap.json" accessWidener = file("src/main/resources/sodium.accesswidener") @@ -32,20 +22,6 @@ dependencies { modCompile "net.fabricmc:fabric-loader:${project.loader_version}" } -processResources { - inputs.property "version", project.version - - from(sourceSets.main.resources.srcDirs) { - include "fabric.mod.json" - - expand "version": project.version - } - - from(sourceSets.main.resources.srcDirs) { - exclude "fabric.mod.json" - } -} - if (project.use_third_party_mods) { repositories { maven { url = "https://jitpack.io" } @@ -60,6 +36,14 @@ if (project.use_third_party_mods) { } } +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + // ensure that the encoding is set to UTF-8, no matter what the system default is // this fixes some edge cases with special characters not displaying correctly // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html @@ -67,14 +51,34 @@ tasks.withType(JavaCompile) { options.encoding = "UTF-8" } -// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task -// if it is present. -// If you remove this task, sources will not be generated. -task sourcesJar(type: Jar, dependsOn: classes) { - classifier = "sources" - from sourceSets.main.allSource +java { + withSourcesJar() } jar { from "LICENSE.txt" +} + +def getVersionMetadata() { + def build_id = System.getenv("GITHUB_RUN_NUMBER") + + // CI builds only + if (build_id != null) { + return "build.${build_id}" + } + + if (grgit == null) { + def head = grgit.head() + def id = head.abbreviatedId + + // Flag the build if the build tree is not clean + if (!grgit.status().clean) { + id += "-dirty" + } + + return "rev.${id}" + } + + // No tracking information could be found about the build + return "unknown" } \ No newline at end of file From 72478fffc628408e59defeb8e7f70895565f5149 Mon Sep 17 00:00:00 2001 From: jellysquid3 Date: Sat, 20 Mar 2021 18:15:19 -0500 Subject: [PATCH 02/13] fix: Remove debug-hack in build.gradle revision checking --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8a87a421a7..7c6f19ae3a 100644 --- a/build.gradle +++ b/build.gradle @@ -67,7 +67,7 @@ def getVersionMetadata() { return "build.${build_id}" } - if (grgit == null) { + if (grgit != null) { def head = grgit.head() def id = head.abbreviatedId From 78cf0276c552d516d5416a5932833d63223249b9 Mon Sep 17 00:00:00 2001 From: Yao Chung Hu <30311066+FlashyReese@users.noreply.github.com> Date: Sat, 20 Mar 2021 17:16:50 -0600 Subject: [PATCH 03/13] fix: Validate chunk section Y axis upon retrieving ChunkRenderContainer (#589) --- .../mods/sodium/client/render/chunk/ChunkRenderColumn.java | 3 +++ .../mods/sodium/client/render/chunk/ChunkRenderManager.java | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderColumn.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderColumn.java index caed6fb8ff..3663a0ef52 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderColumn.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderColumn.java @@ -30,6 +30,9 @@ public void setRender(int y, ChunkRenderContainer render) { } public ChunkRenderContainer getRender(int y) { + if (y < 0 || y >= this.renders.length) { + return null; + } return this.renders[y]; } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderManager.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderManager.java index 594b4d3f64..166945d38b 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderManager.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderManager.java @@ -471,10 +471,6 @@ public int getTotalSections() { } public void scheduleRebuild(int x, int y, int z, boolean important) { - if (y < 0 || y >= 16) { - return; - } - ChunkRenderContainer render = this.getRender(x, y, z); if (render != null) { From 382f97a57509486390cea6ac98315be68949067f Mon Sep 17 00:00:00 2001 From: jellysquid3 Date: Sat, 20 Mar 2021 18:37:47 -0500 Subject: [PATCH 04/13] change: Fail builds using JDK 9 or newer The vast majority of support tickets come from players compiling the mod JDK 9+ and trying to run it on the runtime the Minecraft launcher provides (typically JRE 8). --- build.gradle | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7c6f19ae3a..8f8d76115a 100644 --- a/build.gradle +++ b/build.gradle @@ -81,4 +81,21 @@ def getVersionMetadata() { // No tracking information could be found about the build return "unknown" -} \ No newline at end of file +} + +// Fails the build if JDK 1.8 is not being used +tasks.register('enforceJdkVersion') { + doLast { + def jdkVersion = JavaVersion.current() + + if (jdkVersion != JavaVersion.VERSION_1_8) { + throw new IllegalStateException("This project must be built with JDK 1.8 (Java 8), but JDK ${jdkVersion} was found...") + } + } +} + +// Users who know what they are doing can specify -PskipJdkVersionCheck on the command +// line to bypass this check +if (!project.hasProperty('skipJdkVersionCheck')) { + compileJava.dependsOn(enforceJdkVersion) +} From a4a6e48a07f336ae6e9c9e98a266a5d53140c35d Mon Sep 17 00:00:00 2001 From: jellysquid3 Date: Sat, 20 Mar 2021 21:05:09 -0500 Subject: [PATCH 05/13] change: Use Gradle toolchains to automatically pull in JDK 8 This is a better solution than failing when JDK 9+ is used, and means that people do not have to swap around their JAVA_HOME. For users of SDKMAN and other similar package managers, Gradle can automatically pick up local toolchain installations and re-use them. --- build.gradle | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/build.gradle b/build.gradle index 8f8d76115a..58ea02d7ea 100644 --- a/build.gradle +++ b/build.gradle @@ -3,9 +3,6 @@ plugins { id 'org.ajoberstar.grgit' version '4.1.0' } -sourceCompatibility = JavaVersion.VERSION_1_8 -targetCompatibility = JavaVersion.VERSION_1_8 - archivesBaseName = "${project.archives_base_name}-mc${project.minecraft_version}" version = "${project.mod_version}+${getVersionMetadata()}" group = project.maven_group @@ -53,6 +50,11 @@ tasks.withType(JavaCompile) { java { withSourcesJar() + + toolchain { + languageVersion = JavaLanguageVersion.of(8) + vendor = JvmVendorSpec.ADOPTOPENJDK + } } jar { @@ -82,20 +84,3 @@ def getVersionMetadata() { // No tracking information could be found about the build return "unknown" } - -// Fails the build if JDK 1.8 is not being used -tasks.register('enforceJdkVersion') { - doLast { - def jdkVersion = JavaVersion.current() - - if (jdkVersion != JavaVersion.VERSION_1_8) { - throw new IllegalStateException("This project must be built with JDK 1.8 (Java 8), but JDK ${jdkVersion} was found...") - } - } -} - -// Users who know what they are doing can specify -PskipJdkVersionCheck on the command -// line to bypass this check -if (!project.hasProperty('skipJdkVersionCheck')) { - compileJava.dependsOn(enforceJdkVersion) -} From 4b3964aef35ede56ef080fd6f35a1b577bd0e3f3 Mon Sep 17 00:00:00 2001 From: jellysquid3 Date: Sun, 21 Mar 2021 11:09:48 -0500 Subject: [PATCH 06/13] change: Update README.md --- README.md | 112 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 76 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index bb3e72fb73..1828d4ef1a 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ ![GitHub license](https://img.shields.io/github/license/jellysquid3/sodium-fabric.svg) ![GitHub issues](https://img.shields.io/github/issues/jellysquid3/sodium-fabric.svg) ![GitHub tag](https://img.shields.io/github/tag/jellysquid3/sodium-fabric.svg) -[![Discord chat](https://img.shields.io/badge/chat%20on-discord-7289DA)](https://jellysquid.me/discord) -[![CurseForge downloads](http://cf.way2muchnoise.eu/full_394468_downloads.svg)](https://www.curseforge.com/minecraft/mc-mods/sodium) Sodium is a free and open-source optimization mod for the Minecraft client that improves frame rates, reduces micro-stutter, and fixes graphical issues in Minecraft. @@ -13,56 +11,98 @@ micro-stutter, and fixes graphical issues in Minecraft. :warning: Sodium has had a lot of time to shape up lately, but the mod is still alpha software. You may run into small graphical issues or crashes while using it. Additionally, the [Fabric Rendering API](https://fabricmc.net/wiki/documentation:rendering) is not yet supported, which may cause crashes -or prevent other mods from rendering correctly. Please be aware of these issues before using it in your game. +and other issues with a number of mods. -### Downloads +## Installation -You can find downloads for Sodium on either the [official CurseForge page](https://www.curseforge.com/minecraft/mc-mods/sodium) -or through the [GitHub releases page](https://github.com/jellysquid3/sodium-fabric/releases). Usually, builds will be -made available on GitHub slightly sooner than other locations. +### Stable releases -### Community +#### Manual Installation (recommended) -If you'd like to get help with the mod, check out the latest developments, or be notified when there's a new release, -the Discord community might be for you! You can join the official server for my mods by clicking -[here](https://jellysquid.me/discord). +The latest releases of Sodium are published to our [official Modrinth page](https://modrinth.com/mod/sodium) and [GitHub releases page](https://github.com/jellysquid3/sodium-fabric/releases). Usually, builds will be +made available on GitHub slightly sooner than other locations. -### Building from source +You will need Fabric Loader 0.10.x or newer installed in your game in order to load Sodium. If you haven't installed Fabric +mods before, you can find a variety of community guides for doing so [here](https://fabricmc.net/wiki/install). -If you're hacking on the code or would like to compile a custom build of Sodium from the latest sources, you'll want -to start here. +#### CurseForge -#### Prerequisites +If you are using the new CurseForge client, you can continue to find downloads through our +[official CurseForge page](https://www.curseforge.com/minecraft/mc-mods/sodium). Please note +that the CurseForge launcher does not natively support Fabric modding, so you will also need to install +[Jumploader](https://www.curseforge.com/minecraft/mc-mods/jumploader) in order to create a Fabric environment. As such, +we generally do not recommend this option, and are looking to phase out support for it in the near future. -You will need to install JDK 8 (or newer, see below) in order to build Sodium. You can either install this through -a package manager such as [Chocolatey](https://chocolatey.org/) on Windows or [SDKMAN!](https://sdkman.io/) on other -platforms. If you'd prefer to not use a package manager, you can always grab the installers or packages directly from -[AdoptOpenJDK](https://adoptopenjdk.net/). -On Windows, the Oracle JDK/JRE builds should be avoided where possible due to their poor quality. Always prefer using -the open-source builds from AdoptOpenJDK when possible. +### Bleeding-edge builds -#### Compiling +If you are a player who is looking to get your hands on the latest **bleeding-edge builds for testing**, consider +taking a look at the builds produced through our [GitHub Actions workflow](actions/workflows/gradle.yml). This +workflow automatically runs every time a change is pushed to the repository, and as such, they will reflect the latest +state of development. -Navigate to the directory you've cloned this repository and launch a build with Gradle using `gradlew build` (Windows) -or `./gradlew build` (macOS/Linux). If you are not using the Gradle wrapper, simply replace `gradlew` with `gradle` -or the path to it. +Bleeding edge builds will often include unfinished code that hasn't been extensively tested. That code may introduce +incomplete features, bugs, crashes, and all other kinds of weird issues. You **should not use these bleeding edge builds** +unless you know what you are doing and are comfortable with software debugging. If you report issues using these builds, +we will expect that this is the case. Caveat emptor. -The initial setup may take a few minutes. After Gradle has finished building everything, you can find the resulting -artifacts in `build/libs`. +### Reporting Issues -### Tuning for optimal performance +You can report bugs and crashes by opening an issue on our [issue tracker](https://github.com/jellysquid3/sodium-fabric/issues). +Before opening a new issue, please check using the search tool that your issue has not already been created, and that if +there is a suitable template for the issue you are opening, that it is filled out entirely. Issues which are duplicates +or do not contain the necessary information to triage and debug may be closed. -_This section is entirely optional and is only aimed at users who are interested in squeezing out every drop from their -game. Sodium will work without issue in the default configuration of almost all launchers._ +Please note that while the issue tracker is open to feature and mod compatibility requests, development +is primarily focused on improving hardware compatibility and performance, along with finishing any unimplemented features +necessary for parity with the vanilla renderer. -Generally speaking, newer versions of Java will provide better performance not only when playing Minecraft, but when -using Sodium as well. The default configuration your game launcher provides will usually be some old version of Java 8 -that has been selected to maximize hardware compatibility instead of performance. +### Community +[![Discord chat](https://img.shields.io/badge/chat%20on-discord-7289DA)](https://jellysquid.me/discord) -For most users, these compatibility issues are not relevant, and it should be relatively easy to upgrade the game's Java -runtime and apply the required patches. For more information on upgrading and tuning the Java runtime, see the -guide [here](https://gist.github.com/jellysquid3/8a7b21e57f47f5711eb5697e282e502e). +We have an [official Discord community](https://jellysquid.me/discord) for all of our projects. By joining, you can: +- Get installation help and technical support with all of our mods +- Be notified of the latest developments as they happen +- Get involved and collaborate with the rest of our team +- ... and just hang out with the rest of our community. + +### Building from sources + +#### Requirements + +- JRE 8 or newer (for running Gradle) +- JDK 8 (optional) + - If you neither have JDK 8 available on your shell's path or installed through a supported package manager (such as +[SDKMAN](https://sdkman.io)), Gradle will automatically download a suitable toolchain from the [AdoptOpenJDK project](https://adoptopenjdk.net/) +and use it to compile the project. For more information on what package managers are supported and how you can +customize this behavior on a system-wide level, please see [Gradle's Toolchain user guide](https://docs.gradle.org/current/userguide/toolchains.html). +- Gradle 6.x (optional) + - The [Gradle wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html#sec:using_wrapper) is provided in + this repository can be used instead of installing a suitable version of Gradle yourself. However, if you are building + many projects, you may prefer to install it yourself through a suitable package manager as to save disk space and to + avoid many different Gradle daemons sitting around in memory. + +#### Building with Gradle + +Sodium uses a typical Gradle project structure and can be built by simply running the default `build` task. + +**Tip:** If this is a one-off build, and you would prefer the Gradle daemon does not stick around in memory afterwards +(often consuming upwards of 1 GiB), then you can use the [`--no-daemon` argument](https://docs.gradle.org/current/userguide/gradle_daemon.html#sec:disabling_the_daemon) +to ensure that the daemon is torn down after the build is complete. However, subsequent Gradle builds will +[start more slowly](https://docs.gradle.org/current/userguide/gradle_daemon.html#sec:why_the_daemon) if the Gradle +daemon is not sitting warm and loaded in memory. + +After Gradle finishes building the project, the resulting build artifacts (your usual mod binaries, and +their sources) can be found in `build/libs`. + +Build artifacts classified with `dev` are outputs containing the sources and compiled classes +before they are remapped into stable intermediary names. If you are working in a developer environment and would +like to add the mod to your game, you should prefer to use the `modRuntime` or `modCompile` configurations provided by +Loom instead of these outputs. + +Please note that support is not provided for setting up build environments or compiling the mod. We ask that +users who are looking to get their hands dirty with the code have a basic understanding of compiling Java/Gradle +projects. ### License From b268c2e43368a1fb32ab5686daf2ceff77a4c27a Mon Sep 17 00:00:00 2001 From: jellysquid3 Date: Sun, 21 Mar 2021 11:20:00 -0500 Subject: [PATCH 07/13] change: Update Gradle minimum version to 6.7 --- README.md | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 58702 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 2 ++ gradlew.bat | 25 +++++++---------------- 5 files changed, 11 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 1828d4ef1a..0fd6e373a0 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ We have an [official Discord community](https://jellysquid.me/discord) for all o [SDKMAN](https://sdkman.io)), Gradle will automatically download a suitable toolchain from the [AdoptOpenJDK project](https://adoptopenjdk.net/) and use it to compile the project. For more information on what package managers are supported and how you can customize this behavior on a system-wide level, please see [Gradle's Toolchain user guide](https://docs.gradle.org/current/userguide/toolchains.html). -- Gradle 6.x (optional) +- Gradle 6.7 or newer (optional) - The [Gradle wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html#sec:using_wrapper) is provided in this repository can be used instead of installing a suitable version of Gradle yourself. However, if you are building many projects, you may prefer to install it yourself through a suitable package manager as to save disk space and to diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index cc4fdc293d0e50b0ad9b65c16e7ddd1db2f6025b..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f 100644 GIT binary patch delta 18978 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 delta 18570 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 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -51,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -61,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell From e113c4c8abed22457525e36372fcba795c3254b8 Mon Sep 17 00:00:00 2001 From: jellysquid3 Date: Sun, 21 Mar 2021 11:42:39 -0500 Subject: [PATCH 08/13] change: Rename GitHub actions --- .github/workflows/gradle.yml | 2 +- .github/workflows/publish.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 1273a9eaff..1d3984626f 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -1,4 +1,4 @@ -name: Java CI with Gradle +name: gradle-ci on: [ push, pull_request ] diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f51c04056d..d2f74f34f4 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,4 +1,4 @@ -name: Publish Release +name: release-artifacts on: release: From 8b945931e9191b9fc8e7aafd9742cea6bf0ddb1a Mon Sep 17 00:00:00 2001 From: ImperatorStorm <30777770+ImperatorStorm@users.noreply.github.com> Date: Mon, 22 Mar 2021 09:17:47 -0700 Subject: [PATCH 09/13] change: Do not require AdoptOpenJDK-vendored JDKs for building Gradle will still download an AOJ build if none suitable are available. --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 58ea02d7ea..dd20ddfbf7 100644 --- a/build.gradle +++ b/build.gradle @@ -53,7 +53,6 @@ java { toolchain { languageVersion = JavaLanguageVersion.of(8) - vendor = JvmVendorSpec.ADOPTOPENJDK } } From 86fa8b1b6e770ffa2b89a52621e829e52191126b Mon Sep 17 00:00:00 2001 From: jellysquid3 Date: Sun, 21 Mar 2021 12:36:06 -0500 Subject: [PATCH 10/13] change: Further improve download/installation section of README --- .github/ISSUE_TEMPLATE/bug_report.md | 64 ++++++++++++---- .github/ISSUE_TEMPLATE/crash-report.md | 46 ++++++++++-- README.md | 100 +++++++++++++++---------- 3 files changed, 148 insertions(+), 62 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 1e70622e2b..5051c36413 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,27 +7,61 @@ assignees: '' --- +### Read me before you open an issue! ### + +#### Instructions + +This is a template for the issue you are about to open! It will help you provide the information necessary +to complete your **bug report**. Before you open an issue, ensure you've completed every step on the checklist below. + +- Have you used the search tool to find similar issues? Make sure you are not opening a duplicate. +- Are you using the latest version of the mod? If not, try updating to see if it resolves your issue. + +All good? Please read through the sections below, and fill out any lines starting with an arrow. Then, remove +everything above this dashed line (including the line itself.) + +------------------------ + +### Version Information + +> Replace this text with the exact version of the mod you are using. Every part of the version is important! If you +> do not know what version you are using, look at the file name in your "mods" folder. +> +> Example: mc1.16.4-0.1.1+rev.4b3964a + ### Expected Behavior -Replace this text with what you expected to happen. -_Example: The Piston should extend._ + +> Replace this text with what you expected to happen. +> +> Example: The Piston should extend. ### Actual Behavior -Replace this text with what actually happened. -_Example: The Piston does not extend._ -### Reproduction Steps -Provide information on how to reproduce this game crash. You can either fill in the example below or do something else -- just make sure your instructions are minimal and clear! If applicable, please provide a world file as a compressed ZIP which contains a minimally reproducible example of the issue. +> Replace this text with what actually happened. +> +> Example: The Piston does not extend. -1. Place a Redstone Lamp beside a Redstone Repeater -2. Use a Lever to activate the Redstone Repeater -3. Nothing happens +### Reproduction Steps -### Attachments -Add any relevant screenshots or videos to this issue as you feel necessary to explain the issue. +> Provide information on how to reproduce this game crash. You can either fill this section in like the example below +> or do something else -- just make sure your instructions are minimal and clear, as other people will need to be able +> to replicate your issue. +> +> Example: +> 1. Place a Redstone Lamp in front of a Redstone Repeater +> 2. Use a Lever to activate the Redstone Repeater +> 3. Nothing happens ### System Information -You can obtain this information from the in-game debug screen or through using [DxDiag](https://support.microsoft.com/en-us/help/4028644/windows-open-and-run-dxdiagexe) on Windows. -- Java Version: [fill me in] -- CPU: [fill me in] -- GPU: [fill me in] +> You can obtain this information from the right-side of the in-game debug screen (F3) or through using DxDiag +> (https://support.microsoft.com/en-us/help/4028644/windows-open-and-run-dxdiagexe) on Windows. +> +> - Java Version: [fill me in] +> - CPU: [fill me in] +> - GPU: [fill me in] + +### Other Information + +> Provide a list of any other mods you are using, along with their respective versions. If you have any screenshots, +> videos, or other information that you feel is necessary to explain the issue, feel free to attach them here. diff --git a/.github/ISSUE_TEMPLATE/crash-report.md b/.github/ISSUE_TEMPLATE/crash-report.md index effc53bd92..173e96d888 100644 --- a/.github/ISSUE_TEMPLATE/crash-report.md +++ b/.github/ISSUE_TEMPLATE/crash-report.md @@ -7,15 +7,49 @@ assignees: '' --- +### Read me before you open an issue! ### + +#### Instructions + +This is a template for the issue you are about to open! It will help you provide the information necessary +to complete your **crash report**. Before you open an issue, ensure you've completed every step on the checklist below. + +- Have you used the search tool to find similar issues? Make sure you are not opening a duplicate. +- Are you using the latest version of the mod? If not, try updating to see if it resolves your issue. + +All good? Please read through the sections below, and fill out any lines starting with an arrow. Then, remove +everything above this dashed line (including the line itself.) + +------------------------ + +### Version + +> Replace this text with the exact version of the mod you are using. Every part of the version is important! If you +> do not know what version you are using, look at the file name in your "mods" folder. +> +> Example: mc1.16.4-0.1.1+rev.4b3964a +> ### Reproduction Steps -Provide information on how to reproduce this game crash. This step is critical for ensuring that your crash can be debugged by other developers. You can either fill in the example below or do something else -- just make sure your instructions are minimal and clear. If applicable, provide a Minecraft save containing a minimal example on how to reproduce this crash as a compressed ZIP file. -1. Place a Redstone Lamp beside a Redstone Repeater -2. Use a Lever to activate the Redstone Repeater -3. The game crashes +> Provide information on how to reproduce this game crash. You can either fill this section in like the example below +> or do something else -- just make sure your instructions are minimal and clear, as other people will need to be able +> to replicate your issue. +> +> Example: +> 1. Place a Redstone Lamp in front of a Redstone Repeater +> 2. Use a Lever to activate the Redstone Repeater +> 3. Nothing happens ### Crash Report File -Please upload your crash report as a file to [GitHub Gist](https://gist.github.com/) and replace this text with a link to the uploaded report. + +> Upload your crash report file as an attachment to this issue (drag-and-drop) or to a service such as GitHub +> Gist (paste a link) and replace this section. This information is critical in resolving your issue! +> +> Tip: Messages like "Exit code 0" from your launcher are not what you're looking for. If your launcher does not +> provide a button to view the most recent crash report, check your game's "crash-reports" folder for the most recent +> crash report file. ### Additional Information -Provide any additional information or context which may be relevant to the issue. If you have none to add, you can remove this section. + +> Provide any additional information or context which may be relevant to the issue. If you have none to add, +> you can remove this section. diff --git a/README.md b/README.md index 0fd6e373a0..f9cb993be4 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ ![Project icon](https://git-assets.jellysquid.me/hotlink-ok/sodium/icon-rounded-128px.png) # Sodium (for Fabric) -![GitHub license](https://img.shields.io/github/license/jellysquid3/sodium-fabric.svg) -![GitHub issues](https://img.shields.io/github/issues/jellysquid3/sodium-fabric.svg) -![GitHub tag](https://img.shields.io/github/tag/jellysquid3/sodium-fabric.svg) +![GitHub license](https://img.shields.io/github/license/CaffeineMC/sodium-fabric.svg) +![GitHub issues](https://img.shields.io/github/issues/CaffeineMC/sodium-fabric.svg) +![GitHub tag](https://img.shields.io/github/tag/CaffeineMC/sodium-fabric.svg) Sodium is a free and open-source optimization mod for the Minecraft client that improves frame rates, reduces micro-stutter, and fixes graphical issues in Minecraft. @@ -13,52 +13,67 @@ graphical issues or crashes while using it. Additionally, the [Fabric Rendering API](https://fabricmc.net/wiki/documentation:rendering) is not yet supported, which may cause crashes and other issues with a number of mods. +--- + ## Installation -### Stable releases +### Manual installation (recommended) -#### Manual Installation (recommended) +You will need Fabric Loader 0.10.x or newer installed in your game in order to load Sodium. If you haven't installed +Fabric mods before, you can find a variety of community guides for doing so [here](https://fabricmc.net/wiki/install). -The latest releases of Sodium are published to our [official Modrinth page](https://modrinth.com/mod/sodium) and [GitHub releases page](https://github.com/jellysquid3/sodium-fabric/releases). Usually, builds will be -made available on GitHub slightly sooner than other locations. +#### Stable releases -You will need Fabric Loader 0.10.x or newer installed in your game in order to load Sodium. If you haven't installed Fabric -mods before, you can find a variety of community guides for doing so [here](https://fabricmc.net/wiki/install). +![GitHub release](https://img.shields.io/github/release/CaffeineMC/sodium-fabric.svg) -#### CurseForge +The latest releases of Sodium are published to our [Modrinth](https://modrinth.com/mods/sodium) and +[GitHub release](https://github.com/CaffeineMC/sodium-fabric/releases) pages. Releases are considered by our team to be +**suitable for general use**, but they are not guaranteed to be free of bugs and other issues. -If you are using the new CurseForge client, you can continue to find downloads through our -[official CurseForge page](https://www.curseforge.com/minecraft/mc-mods/sodium). Please note -that the CurseForge launcher does not natively support Fabric modding, so you will also need to install -[Jumploader](https://www.curseforge.com/minecraft/mc-mods/jumploader) in order to create a Fabric environment. As such, -we generally do not recommend this option, and are looking to phase out support for it in the near future. +Usually, releases will be made available on GitHub slightly sooner than other locations. +#### Bleeding-edge builds (unstable) -### Bleeding-edge builds +[![GitHub build status](https://img.shields.io/github/workflow/status/CaffeineMC/sodium-fabric/gradle-ci/1.16.x/dev)](https://github.com/CaffeineMC/sodium-fabric/actions/workflows/gradle.yml) -If you are a player who is looking to get your hands on the latest **bleeding-edge builds for testing**, consider -taking a look at the builds produced through our [GitHub Actions workflow](actions/workflows/gradle.yml). This -workflow automatically runs every time a change is pushed to the repository, and as such, they will reflect the latest -state of development. +If you are a player who is looking to get your hands on the latest **bleeding-edge changes for testing**, consider +taking a look at the automated builds produced through our [GitHub Actions workflow](https://github.com/CaffeineMC/sodium-fabric/actions/workflows/gradle.yml?query=event%3Apush). +This workflow automatically runs every time a change is pushed to the repository, and as such, the builds it produces +will generally reflect the latest snapshot of development. Bleeding edge builds will often include unfinished code that hasn't been extensively tested. That code may introduce incomplete features, bugs, crashes, and all other kinds of weird issues. You **should not use these bleeding edge builds** unless you know what you are doing and are comfortable with software debugging. If you report issues using these builds, we will expect that this is the case. Caveat emptor. +### CurseForge + +[![CurseForge downloads](http://cf.way2muchnoise.eu/full_394468_downloads.svg)](https://www.curseforge.com/minecraft/mc-mods/sodium) + +If you are using the CurseForge client, you can continue to find downloads through our +[CurseForge page](https://www.curseforge.com/minecraft/mc-mods/sodium). Unless you are using the CurseForge +client, you should prefer the downloads linked on our Modrinth or GitHub release pages above. + +The CurseForge client does not natively support Fabric modding, so you will need to install +[Jumploader](https://www.curseforge.com/minecraft/mc-mods/jumploader) in order to set up your Fabric environment. Due to +the extra complexity and startup overhead this workaround adds, we generally do not recommend using this method unless +you have an existing setup with it. + +--- + ### Reporting Issues -You can report bugs and crashes by opening an issue on our [issue tracker](https://github.com/jellysquid3/sodium-fabric/issues). -Before opening a new issue, please check using the search tool that your issue has not already been created, and that if -there is a suitable template for the issue you are opening, that it is filled out entirely. Issues which are duplicates -or do not contain the necessary information to triage and debug may be closed. +You can report bugs and crashes by opening an issue on our [issue tracker](https://github.com/CaffeineMC/sodium-fabric/issues). +Before opening a new issue, use the search tool to make sure that your issue has not already been reported and ensure +that you have completely filled out the issue template. Issues which are duplicates or do not contain the necessary +information to triage and debug may be closed. -Please note that while the issue tracker is open to feature and mod compatibility requests, development -is primarily focused on improving hardware compatibility and performance, along with finishing any unimplemented features -necessary for parity with the vanilla renderer. +Please note that while the issue tracker is open to feature requests, development is primarily focused on +improving hardware compatibility, performance, and finishing any unimplemented features necessary for parity with +the vanilla renderer. ### Community -[![Discord chat](https://img.shields.io/badge/chat%20on-discord-7289DA)](https://jellysquid.me/discord) +[![Discord chat](https://img.shields.io/badge/chat%20on-discord-7289DA?logo=discord&logoColor=white)](https://jellysquid.me/discord) We have an [official Discord community](https://jellysquid.me/discord) for all of our projects. By joining, you can: - Get installation help and technical support with all of our mods @@ -66,8 +81,14 @@ We have an [official Discord community](https://jellysquid.me/discord) for all o - Get involved and collaborate with the rest of our team - ... and just hang out with the rest of our community. +--- + ### Building from sources +Support is not provided for setting up build environments or compiling the mod. We ask that +users who are looking to get their hands dirty with the code have a basic understanding of compiling Java/Gradle +projects. The basic overview is provided here for those familiar. + #### Requirements - JRE 8 or newer (for running Gradle) @@ -84,27 +105,24 @@ customize this behavior on a system-wide level, please see [Gradle's Toolchain u #### Building with Gradle -Sodium uses a typical Gradle project structure and can be built by simply running the default `build` task. +Sodium uses a typical Gradle project structure and can be built by simply running the default `build` task. After Gradle +finishes building the project, you can find the build artifacts (typical mod binaries, and their sources) in +`build/libs`. -**Tip:** If this is a one-off build, and you would prefer the Gradle daemon does not stick around in memory afterwards -(often consuming upwards of 1 GiB), then you can use the [`--no-daemon` argument](https://docs.gradle.org/current/userguide/gradle_daemon.html#sec:disabling_the_daemon) -to ensure that the daemon is torn down after the build is complete. However, subsequent Gradle builds will +**Tip:** If this is a one-off build, and you would prefer the Gradle daemon does not stick around in memory afterwards, +try adding the [`--no-daemon` flag](https://docs.gradle.org/current/userguide/gradle_daemon.html#sec:disabling_the_daemon) +to ensure that the daemon is torn down after the build is complete. However, subsequent builds of the project will [start more slowly](https://docs.gradle.org/current/userguide/gradle_daemon.html#sec:why_the_daemon) if the Gradle -daemon is not sitting warm and loaded in memory. +daemon is not available to be re-used. -After Gradle finishes building the project, the resulting build artifacts (your usual mod binaries, and -their sources) can be found in `build/libs`. -Build artifacts classified with `dev` are outputs containing the sources and compiled classes +Build artifacts ending in `dev` are outputs containing the sources and compiled classes before they are remapped into stable intermediary names. If you are working in a developer environment and would like to add the mod to your game, you should prefer to use the `modRuntime` or `modCompile` configurations provided by Loom instead of these outputs. -Please note that support is not provided for setting up build environments or compiling the mod. We ask that -users who are looking to get their hands dirty with the code have a basic understanding of compiling Java/Gradle -projects. - +--- ### License Sodium is licensed under GNU LGPLv3, a free and open-source license. For more information, please see the -[license file](https://github.com/jellysquid3/sodium-fabric/blob/1.16.x/dev/LICENSE.txt). +[license file](https://github.com/CaffeineMC/sodium-fabric/blob/1.16.x/dev/LICENSE.txt). From 7b22520355a3b50c08efae7991f406e3d923ee4d Mon Sep 17 00:00:00 2001 From: Jonas Herzig Date: Sat, 27 Mar 2021 20:52:24 +0100 Subject: [PATCH 11/13] fix: `capacity` not updated after `ChunkDrawParamsVector.growBuffer` (#610) In `pushChunkDrawParams` the need to grow the buffer is determined by comparing the write offset to the `capacity` field. But after the buffer had been grown, the `capacity` field had been left unchanged, thereby triggering another grow on each call to `pushChunkDrawParams`, quickly running out of memory. --- .../render/chunk/multidraw/ChunkDrawParamsVector.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/multidraw/ChunkDrawParamsVector.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/multidraw/ChunkDrawParamsVector.java index c3e2fd0e49..c66bc15436 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/multidraw/ChunkDrawParamsVector.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/multidraw/ChunkDrawParamsVector.java @@ -102,6 +102,13 @@ public void pushChunkDrawParams(float x, float y, float z) { this.writeOffset += STRIDE; } + @Override + protected void growBuffer() { + super.growBuffer(); + + this.onBufferChanged(); + } + @Override public void reset() { this.writeOffset = 0; From 0931c43e8cf8a9404bd01a52a58bb32205bb355d Mon Sep 17 00:00:00 2001 From: Jonas Herzig Date: Sat, 27 Mar 2021 21:06:09 +0100 Subject: [PATCH 12/13] fix: Use default value when block state palette entry is missing (#608) This mirrors vanilla behavior (see `PalettedContainer.get(index)`). Fixes #565 --- .../me/jellysquid/mods/sodium/client/world/WorldSlice.java | 3 +++ src/main/resources/sodium.accesswidener | 1 + 2 files changed, 4 insertions(+) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/world/WorldSlice.java b/src/main/java/me/jellysquid/mods/sodium/client/world/WorldSlice.java index da26ba7bde..ee6303aa21 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/world/WorldSlice.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/world/WorldSlice.java @@ -261,6 +261,9 @@ private void populateBlockArrays(int sectionIdx, ChunkSectionPos pos, Chunk chun state = prevPaletteState; } else { state = palette.getByIndex(paletteId); + if (state == null) { + state = container.defaultValue; + } prevPaletteState = state; prevPaletteId = paletteId; diff --git a/src/main/resources/sodium.accesswidener b/src/main/resources/sodium.accesswidener index 863b69e4c7..cc56818ac5 100644 --- a/src/main/resources/sodium.accesswidener +++ b/src/main/resources/sodium.accesswidener @@ -9,3 +9,4 @@ accessible method net/minecraft/client/render/Frustum isVisible (DDDDDD)Z accessible field net/minecraft/world/chunk/PalettedContainer data Lnet/minecraft/util/collection/PackedIntegerArray; accessible field net/minecraft/world/chunk/PalettedContainer palette Lnet/minecraft/world/chunk/Palette; +accessible field net/minecraft/world/chunk/PalettedContainer defaultValue Ljava/lang/Object; From abfa386b01ae6d248f35a174c2059465787fc76e Mon Sep 17 00:00:00 2001 From: Jonas Herzig Date: Sat, 27 Mar 2021 21:08:09 +0100 Subject: [PATCH 13/13] fix: Buffer overflow in `UnsafeChunkDrawCallVector` (#611) The `writeEnd` variable used to be set relative to the write pointer, not relative start of the buffer. This resulted in a `writeEnd` value which was far too large, allowing the buffer to overflow beyond its allocated space and into random memory, corrupting everything in its way with all the unpredictable doom one would expect from that. --- .../client/render/chunk/multidraw/ChunkDrawParamsVector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/multidraw/ChunkDrawParamsVector.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/multidraw/ChunkDrawParamsVector.java index c66bc15436..89795aba76 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/multidraw/ChunkDrawParamsVector.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/multidraw/ChunkDrawParamsVector.java @@ -72,7 +72,7 @@ public void reset() { private void updatePointers(long offset) { this.writeBase = MemoryUtil.memAddress(this.buffer); - this.writeEnd = this.writePointer + this.buffer.capacity(); + this.writeEnd = this.writeBase + this.buffer.capacity(); this.writePointer = this.writeBase + offset; }