mirror of
https://github.com/TeamMidnightDust/CullLeaves.git
synced 2025-12-15 14:15:08 +01:00
CullLeaves 3.0.0 - Forge support & better Sodium compatibility
- Now utilizes the Architectury build system to provide support for Fabric, native Quilt and even Forge (No Architectury API needed!) - Update to MidnightLib 1.0.0 - Better Sodium/Rubidium support: - Fix resourcepacks utilizing leaf culling flickering when using Sodium (Fixes #15) - Integrate Leaf Culling toggle into Sodium options screen
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,6 +8,7 @@ out/
|
|||||||
output/
|
output/
|
||||||
bin/
|
bin/
|
||||||
libs/
|
libs/
|
||||||
|
.architectury-transformer/
|
||||||
|
|
||||||
.classpath
|
.classpath
|
||||||
.project
|
.project
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ dependencies {
|
|||||||
// Do NOT use other classes from fabric loader
|
// Do NOT use other classes from fabric loader
|
||||||
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
||||||
modCompileOnlyApi "maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric"
|
modCompileOnlyApi "maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric"
|
||||||
|
modCompileOnlyApi "maven.modrinth:sodium:${rootProject.sodium_version}"
|
||||||
|
|
||||||
// Remove the next line if you don't want to depend on the API
|
// Remove the next line if you don't want to depend on the API
|
||||||
modApi "dev.architectury:architectury:${rootProject.architectury_version}"
|
//modApi "dev.architectury:architectury:${rootProject.architectury_version}"
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
|
|||||||
@@ -5,4 +5,6 @@ import eu.midnightdust.lib.config.MidnightConfig;
|
|||||||
public class CullLeavesConfig extends MidnightConfig {
|
public class CullLeavesConfig extends MidnightConfig {
|
||||||
@Entry // Enable/Disable the mod. Requires Chunk Reload (F3 + A).
|
@Entry // Enable/Disable the mod. Requires Chunk Reload (F3 + A).
|
||||||
public static boolean enabled = true;
|
public static boolean enabled = true;
|
||||||
|
@Entry // Fixes resourcepacks utilizing leaf culling flickering when using Sodium
|
||||||
|
public static boolean sodiumBlockFaceCullingFix = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package eu.midnightdust.cullleaves.mixin;
|
||||||
|
|
||||||
|
import eu.midnightdust.cullleaves.config.CullLeavesConfig;
|
||||||
|
import me.jellysquid.mods.sodium.client.gl.device.RenderDevice;
|
||||||
|
import me.jellysquid.mods.sodium.client.gl.util.ElementRange;
|
||||||
|
import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFacing;
|
||||||
|
import me.jellysquid.mods.sodium.client.model.vertex.type.ChunkVertexType;
|
||||||
|
import me.jellysquid.mods.sodium.client.render.chunk.*;
|
||||||
|
import me.jellysquid.mods.sodium.client.render.chunk.passes.BlockRenderPass;
|
||||||
|
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.Redirect;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mixin(value = RegionChunkRenderer.class, remap = false)
|
||||||
|
public abstract class MixinRegionChunkRenderer extends ShaderChunkRenderer {
|
||||||
|
@Shadow @Final private boolean isBlockFaceCullingEnabled;
|
||||||
|
@Shadow protected abstract void addDrawCall(ElementRange part, long baseIndexPointer, int baseVertexIndex);
|
||||||
|
@Unique private boolean doFix = false;
|
||||||
|
|
||||||
|
public MixinRegionChunkRenderer(RenderDevice device, ChunkVertexType vertexType) {
|
||||||
|
super(device, vertexType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "buildDrawBatches", at = @At(value = "INVOKE", target = "Lme/jellysquid/mods/sodium/client/render/chunk/RenderSection;getBounds()Lme/jellysquid/mods/sodium/client/render/chunk/data/ChunkRenderBounds;", ordinal = 0))
|
||||||
|
public void cullleaves$shouldApplyTransparentBlockFaceCullingFix(List<RenderSection> sections, BlockRenderPass pass, ChunkCameraContext camera, CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
doFix = pass.getAlphaCutoff() != 0 && CullLeavesConfig.enabled && CullLeavesConfig.sodiumBlockFaceCullingFix && this.isBlockFaceCullingEnabled;
|
||||||
|
}
|
||||||
|
@Redirect(method = "buildDrawBatches", at = @At(value = "INVOKE", target = "Lme/jellysquid/mods/sodium/client/render/chunk/ChunkGraphicsState;getModelPart(Lme/jellysquid/mods/sodium/client/model/quad/properties/ModelQuadFacing;)Lme/jellysquid/mods/sodium/client/gl/util/ElementRange;", ordinal = 0))
|
||||||
|
public ElementRange cullleaves$fixTransparentBlockFaceCulling(ChunkGraphicsState state, ModelQuadFacing facing) {
|
||||||
|
if (doFix) {
|
||||||
|
long indexOffset = state.getIndexSegment().getOffset();
|
||||||
|
int baseVertex = state.getVertexSegment().getOffset() / this.vertexFormat.getStride();
|
||||||
|
for (ModelQuadFacing direction : ModelQuadFacing.DIRECTIONS) {
|
||||||
|
this.addDrawCall(state.getModelPart(direction), indexOffset, baseVertex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state.getModelPart(ModelQuadFacing.UNASSIGNED);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package eu.midnightdust.cullleaves.mixin;
|
||||||
|
|
||||||
|
import eu.midnightdust.cullleaves.config.CullLeavesConfig;
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.SodiumGameOptionPages;
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.options.OptionFlag;
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.options.OptionGroup;
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.options.OptionImpact;
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.options.OptionImpl;
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.options.control.TickBoxControl;
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.options.storage.SodiumOptionsStorage;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mixin(value = SodiumGameOptionPages.class, remap = false)
|
||||||
|
public class MixinSodiumGameOptionPages {
|
||||||
|
|
||||||
|
@Shadow @Final private static SodiumOptionsStorage sodiumOpts;
|
||||||
|
|
||||||
|
@ModifyVariable(method = "performance", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableList;copyOf(Ljava/util/Collection;)Lcom/google/common/collect/ImmutableList;"))
|
||||||
|
private static List<OptionGroup> cullleaves$addCullLeavesOption(List<OptionGroup> groups) {
|
||||||
|
groups.add(OptionGroup.createBuilder()
|
||||||
|
.add(OptionImpl.createBuilder(boolean.class, sodiumOpts)
|
||||||
|
.setName(Text.translatable("cullleaves.midnightconfig.enabled"))
|
||||||
|
.setTooltip(Text.translatable("cullleaves.midnightconfig.enabled.tooltip.sodium"))
|
||||||
|
.setControl(TickBoxControl::new)
|
||||||
|
.setBinding((opts, value) -> {
|
||||||
|
CullLeavesConfig.enabled = value;
|
||||||
|
CullLeavesConfig.write("cullleaves");
|
||||||
|
}, opts -> CullLeavesConfig.enabled)
|
||||||
|
.setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD)
|
||||||
|
.setImpact(OptionImpact.MEDIUM)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
return groups;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
{
|
{
|
||||||
"cullleaves.midnightconfig.title":"Cull Leaves Config",
|
"cullleaves.midnightconfig.title":"Cull Leaves Config",
|
||||||
"cullleaves.midnightconfig.enabled.tooltip":"After changing this setting you have to reload all chunks (F3 + A)",
|
"cullleaves.midnightconfig.enabled.tooltip":"Enables culling for leaves, providing a nice performance boost.\n§cAfter changing this setting you have to reload all chunks (F3 + A)",
|
||||||
"cullleaves.midnightconfig.enabled":"Enabled"
|
"cullleaves.midnightconfig.enabled.tooltip.sodium":"Enables culling for leaves, providing a nice performance boost",
|
||||||
|
"cullleaves.midnightconfig.enabled":"Enable Leaf Culling",
|
||||||
|
"cullleaves.midnightconfig.sodiumBlockFaceCullingFix.tooltip": "Fixes resourcepacks utilizing leaf culling flickering when using Sodium.\nYou probably want this to be enabled.",
|
||||||
|
"cullleaves.midnightconfig.sodiumBlockFaceCullingFix": "Fix Sodium Block Face Culling on Leaves"
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"cullleaves.midnightconfig.title":"Definições do Cull Leaves",
|
"cullleaves.midnightconfig.title":"Definições do Cull Leaves",
|
||||||
"cullleaves.midnightconfig.enabled.tooltip":"Recarregue os chunks (F3 + A) ao alterar essa opção",
|
"cullleaves.midnightconfig.enabled.tooltip":"Recarregue os chunks (F3 + A) ao alterar essa opção",
|
||||||
"cullleaves.midnightconfig.enabled":"Ativado"
|
"cullleaves.midnightconfig.enabled":"Ativado Cull Leaves"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"cullleaves.midnightconfig.title":"Настройки Cull Leaves",
|
"cullleaves.midnightconfig.title":"Настройки Cull Leaves",
|
||||||
"cullleaves.midnightconfig.enabled.tooltip":"После изменения этого параметра необходимо перезагрузить чанки (F3 + A)",
|
"cullleaves.midnightconfig.enabled.tooltip":"После изменения этого параметра необходимо перезагрузить чанки (F3 + A)",
|
||||||
"cullleaves.midnightconfig.enabled":"Включён"
|
"cullleaves.midnightconfig.enabled":"Включён Cull Leaves"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
"required": true,
|
"required": true,
|
||||||
"package": "eu.midnightdust.cullleaves.mixin",
|
"package": "eu.midnightdust.cullleaves.mixin",
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_17",
|
||||||
|
"minVersion": "0.8",
|
||||||
"client": [
|
"client": [
|
||||||
"MixinLeavesBlock"
|
"MixinLeavesBlock",
|
||||||
],
|
"MixinRegionChunkRenderer",
|
||||||
"mixins": [
|
"MixinSodiumGameOptionPages"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
The MIT License
|
The MIT License
|
||||||
Copyright © 2020 Motschen
|
Copyright © 2022 Motschen
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||||
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||||
6
common/src/main/resources/resourcepacks/smartleaves/pack.mcmeta
Executable file
6
common/src/main/resources/resourcepacks/smartleaves/pack.mcmeta
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"pack": {
|
||||||
|
"pack_format": 9,
|
||||||
|
"description": "§2Makes leaves look identical to OptiFine's smart leaves"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
@@ -10,7 +10,7 @@ dependencies {
|
|||||||
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
||||||
modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
|
modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
|
||||||
// Remove the next line if you don't want to depend on the API
|
// Remove the next line if you don't want to depend on the API
|
||||||
modApi "dev.architectury:architectury-fabric:${rootProject.architectury_version}"
|
//modApi "dev.architectury:architectury-fabric:${rootProject.architectury_version}"
|
||||||
|
|
||||||
compileClasspath(project(path: ":common", configuration: "namedElements")) { transitive false }
|
compileClasspath(project(path: ":common", configuration: "namedElements")) { transitive false }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"pack": {
|
|
||||||
"pack_format": 9,
|
|
||||||
"description": "§2Makes leaves look identical to optifine's smart leaves"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,6 +20,7 @@ configurations {
|
|||||||
compileClasspath.extendsFrom common
|
compileClasspath.extendsFrom common
|
||||||
runtimeClasspath.extendsFrom common
|
runtimeClasspath.extendsFrom common
|
||||||
developmentFabric.extendsFrom common
|
developmentFabric.extendsFrom common
|
||||||
|
archivesBaseName = rootProject.archives_base_name + "-fabric"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ configurations {
|
|||||||
compileClasspath.extendsFrom common
|
compileClasspath.extendsFrom common
|
||||||
runtimeClasspath.extendsFrom common
|
runtimeClasspath.extendsFrom common
|
||||||
developmentForge.extendsFrom common
|
developmentForge.extendsFrom common
|
||||||
|
archivesBaseName = rootProject.archives_base_name + "-forge"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package eu.midnightdust.cullleaves.forge;
|
||||||
|
|
||||||
|
import net.minecraft.resource.*;
|
||||||
|
import net.minecraft.resource.metadata.PackResourceMetadata;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.event.AddPackFindersEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.ModList;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.forgespi.locating.IModFile;
|
||||||
|
import net.minecraftforge.resource.PathPackResources;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber(modid = "cullleaves", bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
|
||||||
|
public class CullLeavesClientEvents {
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void addPackFinders(AddPackFindersEvent event) {
|
||||||
|
if (event.getPackType() == ResourceType.CLIENT_RESOURCES) {
|
||||||
|
registerResourcePack(event, new Identifier("cullleaves", "smartleaves"), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void registerResourcePack(AddPackFindersEvent event, Identifier id, boolean alwaysEnabled) {
|
||||||
|
event.addRepositorySource(((profileAdder, factory) -> {
|
||||||
|
IModFile file = ModList.get().getModFileById(id.getNamespace()).getFile();
|
||||||
|
try (PathPackResources pack = new PathPackResources(id.toString(), file.findResource("resourcepacks/"+id.getPath()))) {
|
||||||
|
profileAdder.accept(new ResourcePackProfile(id.toString(), alwaysEnabled, () -> pack, Text.of(id.getNamespace()+"/"+id.getPath()), pack.parseMetadata(PackResourceMetadata.READER).getDescription().copy().append(" §7(built-in)"), ResourcePackCompatibility.COMPATIBLE, ResourcePackProfile.InsertionPosition.TOP, false, ResourcePackSource.PACK_SOURCE_BUILTIN, false));
|
||||||
|
} catch (IOException | NullPointerException e) {e.printStackTrace();}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,14 +3,19 @@ package eu.midnightdust.cullleaves.forge;
|
|||||||
import eu.midnightdust.cullleaves.config.CullLeavesConfig;
|
import eu.midnightdust.cullleaves.config.CullLeavesConfig;
|
||||||
import eu.midnightdust.lib.config.MidnightConfig;
|
import eu.midnightdust.lib.config.MidnightConfig;
|
||||||
import net.minecraftforge.client.ConfigScreenHandler;
|
import net.minecraftforge.client.ConfigScreenHandler;
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import net.minecraftforge.fml.IExtensionPoint;
|
||||||
import net.minecraftforge.fml.ModLoadingContext;
|
import net.minecraftforge.fml.ModLoadingContext;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.network.NetworkConstants;
|
||||||
|
|
||||||
@Mod("cullleaves")
|
@Mod("cullleaves")
|
||||||
public class CullLeavesClientForge {
|
public class CullLeavesClientForge {
|
||||||
public CullLeavesClientForge() {
|
public CullLeavesClientForge() {
|
||||||
MidnightConfig.init("cullleaves", CullLeavesConfig.class);
|
MidnightConfig.init("cullleaves", CullLeavesConfig.class);
|
||||||
|
ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(() -> NetworkConstants.IGNORESERVERONLY, (remote, server) -> true));
|
||||||
ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, () ->
|
ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, () ->
|
||||||
new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> MidnightConfig.getScreen(parent, "cullleaves")));
|
new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> MidnightConfig.getScreen(parent, "cullleaves")));
|
||||||
|
MinecraftForge.EVENT_BUS.register(new CullLeavesClientEvents());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
modLoader = "javafml"
|
modLoader = "javafml"
|
||||||
loaderVersion = "[43,)"
|
loaderVersion = "[43,)"
|
||||||
#issueTrackerURL = ""
|
#issueTrackerURL = ""
|
||||||
license = "MIT"
|
license = "MIT License"
|
||||||
|
|
||||||
[[mods]]
|
[[mods]]
|
||||||
modId = "cullleaves"
|
modId = "cullleaves"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ maven_group=eu.midnightdust
|
|||||||
|
|
||||||
architectury_version=6.2.43
|
architectury_version=6.2.43
|
||||||
midnightlib_version=1.0.0
|
midnightlib_version=1.0.0
|
||||||
|
sodium_version=mc1.19.2-0.4.4
|
||||||
|
|
||||||
fabric_loader_version=0.14.9
|
fabric_loader_version=0.14.9
|
||||||
fabric_api_version=0.59.0+1.19.2
|
fabric_api_version=0.59.0+1.19.2
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ configurations {
|
|||||||
compileClasspath.extendsFrom common
|
compileClasspath.extendsFrom common
|
||||||
runtimeClasspath.extendsFrom common
|
runtimeClasspath.extendsFrom common
|
||||||
developmentQuilt.extendsFrom common
|
developmentQuilt.extendsFrom common
|
||||||
|
archivesBaseName = rootProject.archives_base_name + "-quilt"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"icon": "assets/cullleaves/icon.png",
|
"icon": "assets/cullleaves/icon.png",
|
||||||
"intermediate_mappings": "net.fabricmc:intermediary",
|
"intermediate_mappings": "net.fabricmc:intermediary",
|
||||||
"environment": "*",
|
"environment": "client",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"client_init": [
|
"client_init": [
|
||||||
"eu.midnightdust.cullleaves.quilt.CullLeavesClientQuilt"
|
"eu.midnightdust.cullleaves.quilt.CullLeavesClientQuilt"
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "Cull Leaves (Quilt)",
|
"name": "Cull Leaves (Quilt)",
|
||||||
|
"description": "Adds culling to leaf blocks, providing a huge performance boost over vanilla.",
|
||||||
"contributors": {
|
"contributors": {
|
||||||
"Motschen": "Author",
|
"Motschen": "Author",
|
||||||
"TeamMidnightDust": "Mascot"
|
"TeamMidnightDust": "Mascot"
|
||||||
|
|||||||
Reference in New Issue
Block a user