Skip to content

Commit 130b5b3

Browse files
author
yitzy299
committed
Change render distance calculations, add status command
Closes #10
1 parent 47525b6 commit 130b5b3

8 files changed

Lines changed: 130 additions & 16 deletions

File tree

README.md

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,38 @@ A Minecraft mod for managing tick-related things
55
## Config
66

77
```toml
8-
splitTickDistance = true
8+
# Required options
9+
splitTickDistance = false
10+
# Required if relevant config option above is enabled
911
tickDistance = 8
10-
itemDespawnTicks = 6000
1112

1213
[dynamic]
1314
dynamicTickDistance = false
1415
minTickDistance = 4
1516
dynamicRenderDistance = false
16-
minRenderDistance = 6
17-
maxRenderDistance = 10
17+
minRenderDistance = 4
18+
maxRenderDistance = 12
19+
# This value controls the MSPT used to target
20+
targetMSPT = 50.0
21+
22+
# Optional
23+
24+
itemDespawnTicks = 6000
25+
26+
# Example config for world specific
27+
# Uncomment to use
28+
#[the_nether]
29+
#splitTickDistance = true
30+
#tickDistance = 8
31+
#itemDespawnTicks = 6000
32+
33+
#[the_nether.dynamic]
34+
# dynamicTickDistance = false
35+
# minTickDistance = 4
36+
# dynamicRenderDistance = false
37+
# minRenderDistance = 4
38+
# maxRenderDistance = 12
39+
1840
```
1941

2042
#### Quick overview of each config option
@@ -36,6 +58,18 @@ maxRenderDistance = 10
3658

3759
`maxRenderDistance` controls the maximum render distance when `dynamicRenderDistance` is enabled
3860

61+
`targetMSPT` is the MSPT that the server will reduce the render distance to try and achieve, when dynamic render distance is enabled
62+
63+
64+
## Commands
65+
66+
### Status Command
67+
68+
`/ticktools status`
69+
70+
Shows the current tick and render distances of all loaded worlds in the following format:
71+
72+
`World identifier: Render/Tick`
3973

4074
## Discuss
4175

src/main/java/com/github/quiltservertools/ticktools/TickTools.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.github.quiltservertools.ticktools;
22

3+
import com.github.quiltservertools.ticktools.command.TickToolsCommand;
34
import net.fabricmc.api.DedicatedServerModInitializer;
5+
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
46
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
57
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
68
import net.fabricmc.fabric.api.networking.v1.PacketSender;
@@ -25,6 +27,7 @@ public void onInitializeServer() {
2527
ServerWorldEvents.LOAD.register(this::onWorldLoad);
2628
ServerWorldEvents.UNLOAD.register(this::onWorldUnload);
2729
ServerPlayConnectionEvents.JOIN.register(this::onPlayerConnect);
30+
CommandRegistrationCallback.EVENT.register(TickToolsCommand::registerCommands);
2831
}
2932

3033
private void onServerStart(MinecraftServer server) {

src/main/java/com/github/quiltservertools/ticktools/TickToolsConfig.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public static class Dynamic {
2828
public int minTickDistance = 4;
2929
public int minRenderDistance = 8;
3030
public int maxRenderDistance = 12;
31-
public int targetMSPT = 50;
31+
public double targetMSPT = 50;
3232

3333
public int getMinTickDistanceBlocks() {
3434
return minTickDistance * 16;
@@ -106,6 +106,9 @@ private void readDynamicTable(Toml dynamicTable) {
106106
dynamic.minRenderDistance = dynamicTable.getLong("minRenderDistance").intValue();
107107
dynamic.maxRenderDistance = dynamicTable.getLong("maxRenderDistance").intValue();
108108
}
109+
if (dynamicTable.contains("targetMSPT")) {
110+
dynamic.targetMSPT = dynamicTable.getDouble("targetMSPT");
111+
}
109112
}
110113
}
111114

src/main/java/com/github/quiltservertools/ticktools/TickToolsManager.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
import net.minecraft.network.packet.s2c.play.ChunkLoadDistanceS2CPacket;
66
import net.minecraft.server.world.ServerWorld;
77
import net.minecraft.util.Identifier;
8-
import net.minecraft.util.math.BlockPos;
98
import net.minecraft.util.math.ChunkPos;
109
import net.minecraft.util.math.MathHelper;
11-
import net.minecraft.util.registry.Registry;
1210

1311
import java.util.Map;
1412
import java.util.UUID;
@@ -66,7 +64,7 @@ public void updateRenderDistance(ServerWorld world) {
6664
var config = worldSpecific().get(world.getRegistryKey().getValue());
6765
if (config == null) config = this.config();
6866
if (config.dynamic.renderDistance) {
69-
int distance = getEffectiveRenderDistance(world);
67+
int distance = getEffectiveRenderDistance(world, true);
7068
if (((MixinThreadedAnvilChunkStorage) world.getChunkManager().threadedAnvilChunkStorage).getWatchDistance() != distance) {
7169
world.getChunkManager().applyViewDistance(distance - 1);
7270
world.getServer().getPlayerManager().sendToAll(new ChunkLoadDistanceS2CPacket(distance - 1));
@@ -95,7 +93,7 @@ else if (performanceLevel == 1)
9593
return config.tickDistance;
9694
}
9795

98-
public int getEffectiveRenderDistance(ServerWorld world) {
96+
public int getEffectiveRenderDistance(ServerWorld world, boolean messages) {
9997
var config = worldSpecific().get(world.getRegistryKey().getValue());
10098
if (config == null) config = this.config();
10199

@@ -107,14 +105,20 @@ public int getEffectiveRenderDistance(ServerWorld world) {
107105

108106
if (avgTickTime > config.dynamic.targetMSPT && currentDistance - 1 > config.dynamic.minTickDistance) {
109107
currentDistance--;
110-
TickTools.LOGGER.info(String.format("Avg MSPT: %.2f above %d. Decreasing view distance in %s to %d",
111-
avgTickTime, config.dynamic.targetMSPT, world.getRegistryKey().getValue(), currentDistance - 1
112-
));
108+
if (messages) {
109+
TickTools.LOGGER.info(String.format("Avg MSPT: %.2f above %d. Decreasing view distance in %s to %d",
110+
// We cast target MSPT to int to make it look better
111+
// In reality this value is a double, like in the config
112+
avgTickTime, (int) config.dynamic.targetMSPT, world.getRegistryKey().getValue(), currentDistance - 1
113+
));
114+
}
113115
} else if (avgTickTime < config.dynamic.targetMSPT && currentDistance - 1 < config.dynamic.maxRenderDistance) {
114116
currentDistance++;
115-
TickTools.LOGGER.info(String.format("Avg MSPT: %.2f below %d. Increasing view distance in %s to to %d",
116-
avgTickTime, config.dynamic.targetMSPT, world.getRegistryKey().getValue(), currentDistance - 1
117-
));
117+
if (messages) {
118+
TickTools.LOGGER.info(String.format("Avg MSPT: %.2f below %d. Increasing view distance in %s to to %d",
119+
avgTickTime, (int) config.dynamic.targetMSPT, world.getRegistryKey().getValue(), currentDistance - 1
120+
));
121+
}
118122
}
119123

120124
return currentDistance;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.github.quiltservertools.ticktools.command;
2+
3+
import com.mojang.brigadier.tree.LiteralCommandNode;
4+
import net.minecraft.server.command.ServerCommandSource;
5+
6+
public interface BuildableCommand {
7+
LiteralCommandNode<ServerCommandSource> build();
8+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.github.quiltservertools.ticktools.command;
2+
3+
import com.github.quiltservertools.ticktools.TickToolsManager;
4+
import com.mojang.brigadier.context.CommandContext;
5+
import com.mojang.brigadier.tree.LiteralCommandNode;
6+
import net.minecraft.server.command.CommandManager;
7+
import net.minecraft.server.command.ServerCommandSource;
8+
import net.minecraft.text.LiteralText;
9+
import net.minecraft.util.registry.Registry;
10+
import net.minecraft.util.registry.RegistryKey;
11+
12+
import java.util.Objects;
13+
14+
public class StatusCommand implements BuildableCommand {
15+
@Override
16+
public LiteralCommandNode<ServerCommandSource> build() {
17+
return CommandManager.literal("status")
18+
.executes(ctx -> {
19+
prepareMessage(ctx);
20+
return 1;
21+
})
22+
.build();
23+
}
24+
25+
private void prepareMessage(CommandContext<ServerCommandSource> context) {
26+
var source = context.getSource();
27+
source.sendFeedback(new LiteralText("--- TickTools Status ---\n").formatted(TickToolsCommand.HEADING), false);
28+
source.sendFeedback(new LiteralText("Default distances: ").formatted(TickToolsCommand.PRIMARY)
29+
.append(new LiteralText("" + TickToolsManager.getInstance().getEffectiveRenderDistance(context.getSource().getServer().getOverworld(), false)
30+
+ "/" + TickToolsManager.getInstance().getEffectiveTickDistance(context.getSource().getServer().getOverworld()) + "\n")
31+
.formatted(TickToolsCommand.SECONDARY)), false);
32+
TickToolsManager.getInstance().worldSpecific().forEach(((identifier, tickToolsConfig) -> {
33+
var key = new LiteralText(identifier.toString() + ":").formatted(TickToolsCommand.PRIMARY);
34+
var worldKey = Objects.requireNonNull(context.getSource().getServer().getWorld(RegistryKey.of(Registry.WORLD_KEY, identifier)));
35+
var render = TickToolsManager.getInstance().getEffectiveRenderDistance(worldKey, false);
36+
var tick = TickToolsManager.getInstance().getEffectiveTickDistance(worldKey);
37+
var value = new LiteralText("" + render + "/" + tick + "\n").formatted(TickToolsCommand.SECONDARY);
38+
source.sendFeedback(key.append(value), false);
39+
}));
40+
}
41+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.github.quiltservertools.ticktools.command;
2+
3+
import com.mojang.brigadier.CommandDispatcher;
4+
import me.lucko.fabric.api.permissions.v0.Permissions;
5+
import net.minecraft.server.command.CommandManager;
6+
import net.minecraft.server.command.ServerCommandSource;
7+
import net.minecraft.util.Formatting;
8+
9+
public class TickToolsCommand {
10+
11+
public static final Formatting PRIMARY = Formatting.GRAY;
12+
public static final Formatting SECONDARY = Formatting.BLUE;
13+
public static final Formatting HEADING = Formatting.AQUA;
14+
15+
public static void registerCommands(CommandDispatcher<ServerCommandSource> dispatcher, boolean dedicated) {
16+
var node = CommandManager.literal("ticktools").requires(Permissions.require("ticktools.root", 3)).build();
17+
node.addChild(new StatusCommand().build());
18+
dispatcher.getRoot().addChild(node);
19+
}
20+
}

src/main/resources/default_config.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ minTickDistance = 4
99
dynamicRenderDistance = false
1010
minRenderDistance = 4
1111
maxRenderDistance = 12
12-
targetMSPT = 50
12+
# This value controls the MSPT used to target
13+
targetMSPT = 50.0
1314

1415
# Optional
1516

0 commit comments

Comments
 (0)