Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement various vanilla performance tweaks, adapted from RLTweaker #434

Merged
merged 9 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ All changes are toggleable via config files.
* **Disable Wither Targeting AI:** Disables withers targeting animals
* **Easy Breeding:** Enables easy breeding of animals by tossing food on the ground
* **End Portal Parallax:** Re-implements parallax rendering of the end portal from 1.11 and older
* **Entity Radius Check**
* These tweaks are only effective if you have mod(s) that increase `World.MAX_ENTITY_RADIUS`! (Lycanites Mobs, Advanced Rocketry, Immersive Railroading, etc.)
* Reduces the search size of various AABB functions for specified entity types to improve performance
* Reduces size of collision checks for most vanilla and specified entity types to improve performance
* **Explosion Block Drop Chance:** Determines the numerator of the block drop formula on explosions
* **Falling Block Lifespan:** Determines how long falling blocks remain in ticks until they are dropped under normal circumstances
* **Fast Dye Blending:** Replaces color lookup for sheep to check a predefined table rather than querying the recipe registry
Expand Down Expand Up @@ -172,6 +176,7 @@ All changes are toggleable via config files.
* **No Golems:** Disables the manual creation of golems and withers
* **No Leftover Breath Bottles:** Disables dragon's breath from leaving off empty bottles when a stack is brewed with
* **No Night Vision Flash:** Disables the flashing effect when the night vision potion effect is about to run out
* **No Pathfinding Chunk Loading:** Disables mob pathfinding from loading new/unloaded chunks when building chunk caches to improve performance
* **No Potion Shift:** Disables the inventory shift when potion effects are active
* **No Portal Spawning:** Prevents zombie pigmen spawning from nether portals
* **No Redstone Lighting:** Disables lighting of active redstone, repeaters, and comparators to improve performance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import mod.acgaming.universaltweaks.tweaks.misc.swingthroughgrass.UTSwingThroughGrassLists;
import mod.acgaming.universaltweaks.tweaks.misc.toastcontrol.UTTutorialToast;
import mod.acgaming.universaltweaks.tweaks.performance.autosave.UTAutoSaveOFCompat;
import mod.acgaming.universaltweaks.tweaks.performance.entityradiuscheck.UTEntityRadiusCheck;
import mod.acgaming.universaltweaks.tweaks.world.stronghold.UTStronghold;
import mod.acgaming.universaltweaks.tweaks.world.stronghold.worldgen.SafeStrongholdWorldGenerator;
import mod.acgaming.universaltweaks.util.UTPacketHandler;
Expand Down Expand Up @@ -205,6 +206,7 @@ public void onServerStarted(FMLServerStartedEvent event)
public void onLoadComplete(FMLLoadCompleteEvent event)
{
if (Loader.isModLoaded("tconstruct") && UTConfigMods.TINKERS_CONSTRUCT.utTConOreDictCacheToggle) UTOreDictCache.onLoadComplete();
if (UTConfigTweaks.PERFORMANCE.ENTITY_RADIUS_CHECK.utEntityRadiusCheckCategoryToggle) UTEntityRadiusCheck.onLoadComplete();
if (UTConfigGeneral.DEBUG.utLoadingTimeToggle) LOGGER.info("The game loaded in approximately {} seconds", (System.currentTimeMillis() - UTLoadingPlugin.launchTime) / 1000F);
if (UTObsoleteModsHandler.showObsoleteMods && UTObsoleteModsHandler.obsoleteModsMessage().size() > 5 && !UTConfigGeneral.DEBUG.utBypassIncompatibilityToggle)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import mod.acgaming.universaltweaks.tweaks.misc.loadsound.UTLoadSound;
import mod.acgaming.universaltweaks.tweaks.misc.swingthroughgrass.UTSwingThroughGrassLists;
import mod.acgaming.universaltweaks.tweaks.performance.autosave.UTAutoSaveOFCompat;
import mod.acgaming.universaltweaks.tweaks.performance.entityradiuscheck.UTEntityRadiusCheck;

@Config(modid = UniversalTweaks.MODID, name = UniversalTweaks.NAME + " - Tweaks")
public class UTConfigTweaks
Expand Down Expand Up @@ -1651,6 +1652,10 @@ public static class ToastControlCategory

public static class PerformanceCategory
{
@Config.LangKey("cfg.universaltweaks.tweaks.performance.entityradiuscheck")
@Config.Name("Entity Radius Check")
public final EntityRadiusCheckCategory ENTITY_RADIUS_CHECK = new EntityRadiusCheckCategory();

@Config.RequiresMcRestart
@Config.Name("Auto Save Interval")
@Config.Comment("Determines the interval in ticks between world auto saves")
Expand Down Expand Up @@ -1715,6 +1720,11 @@ public static class PerformanceCategory
@Config.Comment("Silences texture map errors")
public boolean utTextureMapCheckToggle = false;

@Config.RequiresMcRestart
@Config.Name("No Pathfinding Chunk Loading")
@Config.Comment("Disables mob pathfinding from loading new/unloaded chunks when building chunk caches")
public boolean utPathfindingChunkCacheFixToggle = true;

@Config.RequiresMcRestart
@Config.Name("No Redstone Lighting")
@Config.Comment("Disables lighting of active redstone, repeaters, and comparators to improve performance")
Expand All @@ -1724,6 +1734,49 @@ public static class PerformanceCategory
@Config.Name("Uncap FPS")
@Config.Comment("Removes the hardcoded 30 FPS limit in screens like the main menu")
public boolean utUncapFPSToggle = true;

public static class EntityRadiusCheckCategory
{
@Config.RequiresMcRestart
@Config.Name("[1] Entity Radius Check Toggle")
@Config.Comment
({
"Toggles all tweaks in this category",
"IMPORTANT: These tweaks are only effective if you have mod(s) that increase World.MAX_ENTITY_RADIUS!",
"(Lycanites Mobs, Advanced Rocketry, Immersive Railroading, etc.)"
})
public boolean utEntityRadiusCheckCategoryToggle = true;

@Config.Name("[2] Reduce Search Size Toggle")
@Config.Comment("Reduces the search size of various AABB functions for specified entity types")
public boolean utReduceSearchSizeToggle = true;

@Config.Name("[3] Reduce Search Size Targets")
@Config.Comment
({
"The entity types to reduce the search size for",
"Syntax - modid:name"
})
public String[] utReduceSearchSizeTargets = new String[]
{
"minecraft:item",
"minecraft:player"
};

@Config.Name("[4] Less Collisions Toggle")
@Config.Comment("Reduces size of collision checks for most vanilla and specified entity types")
public boolean utLessCollisionsToggle = true;

@Config.Name("[5] Less Collisions Extra Targets")
@Config.Comment
({
"The extra entity types to reduce the size of collision checks for",
"Syntax - modid:name;radius",
"Vanilla ids aren't allowed because they are already included",
"Most types should be specified with the vanilla default radius: 2.0"
})
public String[] utLessCollisionsExtraTargets = new String[]{};
}
}

public static class WorldCategory
Expand Down Expand Up @@ -1822,6 +1875,11 @@ public static void onConfigChanged(ConfigChangedEvent.OnConfigChangedEvent event
if (MISC.ARMOR_CURVE.utArmorCurveToggle) UTArmorCurve.initExpressions();
if (MISC.SWING_THROUGH_GRASS.utSwingThroughGrassToggle) UTSwingThroughGrassLists.initLists();
if (MISC.INCURABLE_POTIONS.utIncurablePotionsToggle) UTIncurablePotions.initPotionList();
if (PERFORMANCE.ENTITY_RADIUS_CHECK.utEntityRadiusCheckCategoryToggle)
{
if (PERFORMANCE.ENTITY_RADIUS_CHECK.utReduceSearchSizeToggle) UTEntityRadiusCheck.initSearchTargets();
if (PERFORMANCE.ENTITY_RADIUS_CHECK.utLessCollisionsToggle) UTEntityRadiusCheck.initCollisionTargets();
}
if (ITEMS.utCustomRarities.length > 0) UTCustomRarity.initItemRarityMap();
if (ITEMS.utCustomUseDurations.length > 0) UTCustomUseDuration.initItemUseMaps();
if (ITEMS.PARRY.utParryToggle) UTParry.initProjectileList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import mod.acgaming.universaltweaks.config.UTConfigBugfixes;
import mod.acgaming.universaltweaks.config.UTConfigGeneral;
import mod.acgaming.universaltweaks.config.UTConfigTweaks;
import mod.acgaming.universaltweaks.util.UTReflectionUtil;
import zone.rong.mixinbooter.IEarlyMixinLoader;

@IFMLLoadingPlugin.Name("UniversalTweaksCore")
Expand All @@ -38,33 +39,10 @@ public class UTLoadingPlugin implements IFMLLoadingPlugin, IEarlyMixinLoader
Locale.setDefault(Locale.ENGLISH);
}

try
{
Class.forName("com.therandomlabs.randompatches.core.RPCore");
randomPatchesLoaded = true;
}
catch (ClassNotFoundException ignored) {}

try
{
Class.forName("meldexun.renderlib.RenderLib");
renderLibLoaded = true;
}
catch (ClassNotFoundException ignored) {}

try
{
Class.forName("org.spongepowered.mod.util.CompatibilityException");
spongeForgeLoaded = true;
}
catch (ClassNotFoundException ignored) {}

try
{
Class.forName("net.darkhax.surge.core.SurgeLoadingPlugin");
surgeLoaded = true;
}
catch (ClassNotFoundException ignored) {}
randomPatchesLoaded = UTReflectionUtil.isClassLoaded("com.therandomlabs.randompatches.core.RPCore");
renderLibLoaded = UTReflectionUtil.isClassLoaded("meldexun.renderlib.RenderLib");
spongeForgeLoaded = UTReflectionUtil.isClassLoaded("org.spongepowered.mod.util.CompatibilityException");
surgeLoaded = UTReflectionUtil.isClassLoaded("net.darkhax.surge.core.SurgeLoadingPlugin");
}

@Override
Expand Down Expand Up @@ -246,7 +224,10 @@ public List<String> getMixinConfigs()
configs.add("mixins.tweaks.performance.autosave.json");
configs.add("mixins.tweaks.performance.craftingcache.json");
configs.add("mixins.tweaks.performance.dyeblending.json");
configs.add("mixins.tweaks.performance.entityradiuscheck.lesscollisions.json");
configs.add("mixins.tweaks.performance.entityradiuscheck.reducesearchsize.json");
configs.add("mixins.tweaks.performance.oredictionarycheck.json");
configs.add("mixins.tweaks.performance.pathfinding.json");
configs.add("mixins.tweaks.performance.prefixcheck.json");
configs.add("mixins.tweaks.performance.redstone.json");
configs.add("mixins.tweaks.performance.texturemapcheck.json");
Expand Down Expand Up @@ -535,8 +516,14 @@ public boolean shouldMixinConfigQueue(String mixinConfig)
return UTConfigTweaks.PERFORMANCE.utCraftingCacheToggle;
case "mixins.tweaks.performance.dyeblending.json":
return UTConfigTweaks.PERFORMANCE.utDyeBlendingToggle;
case "mixins.tweaks.performance.entityradiuscheck.lesscollisions.json":
return UTConfigTweaks.PERFORMANCE.ENTITY_RADIUS_CHECK.utEntityRadiusCheckCategoryToggle && UTConfigTweaks.PERFORMANCE.ENTITY_RADIUS_CHECK.utLessCollisionsToggle;
case "mixins.tweaks.performance.entityradiuscheck.reducesearchsize.json":
return UTConfigTweaks.PERFORMANCE.ENTITY_RADIUS_CHECK.utEntityRadiusCheckCategoryToggle && UTConfigTweaks.PERFORMANCE.ENTITY_RADIUS_CHECK.utReduceSearchSizeToggle;
case "mixins.tweaks.performance.oredictionarycheck.json":
return UTConfigTweaks.PERFORMANCE.utOreDictionaryCheckToggle;
case "mixins.tweaks.performance.pathfinding.json":
return UTConfigTweaks.PERFORMANCE.utPathfindingChunkCacheFixToggle;
case "mixins.tweaks.performance.prefixcheck.json":
return UTConfigTweaks.PERFORMANCE.utPrefixCheckToggle;
case "mixins.tweaks.performance.redstone.json":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import mod.acgaming.universaltweaks.UniversalTweaks;
import mod.acgaming.universaltweaks.config.UTConfigTweaks;
import mod.acgaming.universaltweaks.core.UTLoadingPlugin;
import mod.acgaming.universaltweaks.util.UTReflectionUtil;

public class UTAutoSaveOFCompat
{
Expand All @@ -20,9 +21,9 @@ public class UTAutoSaveOFCompat
public static void updateOFConfig()
{
if (!UTLoadingPlugin.isClient) return;
if (!UTReflectionUtil.isClassLoaded("optifine.OptiFineTweaker")) return;
try
{
Class.forName("optifine.OptiFineTweaker");
UniversalTweaks.LOGGER.info("OptiFine detected, updating config file...");

Path ofConfigPath = Paths.get(rootFolder + File.separator + "optionsof.txt");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package mod.acgaming.universaltweaks.tweaks.performance.entityradiuscheck;

import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.function.Predicate;

import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.boss.EntityDragon;
import net.minecraft.entity.boss.EntityWither;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityItemFrame;
import net.minecraft.entity.item.EntityPainting;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.entity.passive.AbstractHorse;
import net.minecraft.entity.passive.EntityWolf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.EntityEntry;
import net.minecraftforge.registries.RegistryManager;

import com.google.common.collect.ImmutableSet;
import it.unimi.dsi.fastutil.objects.Reference2DoubleMap;
import it.unimi.dsi.fastutil.objects.Reference2DoubleMaps;
import it.unimi.dsi.fastutil.objects.Reference2DoubleOpenHashMap;
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
import mod.acgaming.universaltweaks.UniversalTweaks;
import mod.acgaming.universaltweaks.config.UTConfigTweaks;

public class UTEntityRadiusCheck
{
public static Set<Class<? extends Entity>> searchTargets = Collections.emptySet();
public static Reference2DoubleMap<Class<? extends Entity>> collisionTargets = Reference2DoubleMaps.emptyMap();

public static void onLoadComplete()
{
if (UTConfigTweaks.PERFORMANCE.ENTITY_RADIUS_CHECK.utReduceSearchSizeToggle) initSearchTargets();
if (UTConfigTweaks.PERFORMANCE.ENTITY_RADIUS_CHECK.utLessCollisionsToggle) initCollisionTargets();
}

public static void initSearchTargets()
{
final ResourceLocation playerId = new ResourceLocation("player");
Set<Class<? extends Entity>> out = new ReferenceOpenHashSet<>();
// Read config for classes
for (String entityId : UTConfigTweaks.PERFORMANCE.ENTITY_RADIUS_CHECK.utReduceSearchSizeTargets)
{
Class<? extends Entity> entityClazz = getEntityType(entityId, playerId, false);
if (entityClazz == null)
{
UniversalTweaks.LOGGER.warn("UTEntityRadiusCheck ::: Invalid entity id " + entityId + "in \"[3] Reduce Search Size Targets\"! Skipping this entry.");
continue;
}
out.add(entityClazz);
}
if (!out.isEmpty()) searchTargets = out;
}

public static void initCollisionTargets()
{
final ResourceLocation ignored = new ResourceLocation("");
// To avoid auto-unboxing later
collisionTargets = new Reference2DoubleOpenHashMap<>();
Set<?> vanillaEntities = (Set<?>) RegistryManager.VANILLA.getRegistry(new ResourceLocation("entities")).getValuesCollection();
Predicate<Class<? extends Entity>> vanillaPredicate = buildVanillaPredicate();
// Add vanilla entity types
for (Object entry : vanillaEntities)
{
Class<? extends Entity> clazz = ((EntityEntry) entry).getEntityClass();
if (vanillaPredicate.test(clazz))
{
collisionTargets.put(clazz, 2.0D);
}
}
// Add config's entity types
for (String entry : UTConfigTweaks.PERFORMANCE.ENTITY_RADIUS_CHECK.utLessCollisionsExtraTargets)
{
// Parsing
int separator = entry.indexOf(";");
if (separator == -1)
{
UniversalTweaks.LOGGER.warn("UTEntityRadiusCheck ::: Unexpected format " + entry + "in \"[5] Less Collisions Extra Targets\"! Skipping this entry.");
continue;
}
String entityId = entry.substring(0, separator);
double radius;
try
{
radius = Double.parseDouble(entry.substring(separator + 1));
}
catch (NumberFormatException ex)
{
UniversalTweaks.LOGGER.warn("UTEntityRadiusCheck ::: Unexpected format " + entry + "in \"[5] Less Collisions Extra Targets\"! Skipping this entry.");
continue;
}
// Verifying
Class<? extends Entity> entityClazz = getEntityType(entityId, ignored, true);
if (entityClazz == null)
{
UniversalTweaks.LOGGER.warn("UTEntityRadiusCheck ::: Invalid entity id " + entityId + "in \"[5] Less Collisions Extra Targets\"! Skipping this entry.");
continue;
}
if (radius <= 0.0D)
{
UniversalTweaks.LOGGER.warn("UTEntityRadiusCheck ::: Invalid radius " + radius + "in \"[5] Less Collisions Extra Targets\"! Skipping this entry.");
continue;
}
collisionTargets.put(entityClazz, radius);
}
}

private static @Nullable Class<? extends Entity> getEntityType(String entityId, ResourceLocation playerId, boolean nonVanillaOnly)
{
ResourceLocation entityLoc = new ResourceLocation(entityId);
if (nonVanillaOnly && entityLoc.getNamespace().equals("minecraft")) return null;
// Special case of player
if (entityId.equals(playerId.toString()))
{
return EntityPlayer.class;
}
return EntityList.getClass(entityLoc);
}

private static Predicate<Class<? extends Entity>> buildVanillaPredicate()
{
// Conditions taken from RLTweaker's JsonConfigLessCollisions.
// (1) No combat allies or offensive tools
// (2) No mountables, except for pigs.
// (3) No projectiles of any kind
// (4) Caution with entities that may become the owner of explosions
Predicate<Class<? extends Entity>> livingPredicate = new Predicate<Class<? extends Entity>>()
{
@Override
public boolean test(Class<? extends Entity> entityClazz)
{
return EntityLivingBase.class.isAssignableFrom(entityClazz) &&
!(entityClazz == EntityWolf.class || // (1)
AbstractHorse.class.isAssignableFrom(entityClazz) || // (2)
entityClazz == EntityPlayer.class ||
entityClazz == EntityDragon.class || // (4)
entityClazz == EntityWither.class // (4)
);
}
};
Predicate<Class<? extends Entity>> miscPredicate = new Predicate<Class<? extends Entity>>()
{
@Override
public boolean test(Class<? extends Entity> entityClazz)
{
Collection<Class<? extends Entity>> allowed = ImmutableSet.of(
EntityItem.class,
EntityItemFrame.class,
EntityPainting.class,
EntityXPOrb.class
);
return allowed.contains(entityClazz);
}
};
return livingPredicate.or(miscPredicate);
}
}
Loading
Loading