Skip to content

Commit da2429c

Browse files
authored
[TickSync] Fix tickrate 0 in main menu not working (#236)
- More documentation to MixinTimer - Removed powerpoint links in TickSync documentation
2 parents de88a57 + 61b608a commit da2429c

File tree

4 files changed

+100
-39
lines changed

4 files changed

+100
-39
lines changed

src/main/java/com/minecrafttas/tasmod/mixin/MixinTimer.java

Lines changed: 93 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,59 +15,122 @@
1515

1616
@Mixin(Timer.class)
1717
/**
18-
* Rewrites updateTimer to make it possible to interpolate ticks.
18+
* <p>Rewrites updateTimer, to add a tickratechanger and apply ticksync.
19+
* <p>Dynamically speeds up or slows down the tickrate depending on the time between {@link TickSyncClient TickSync} packages.
1920
* @author Pancake
2021
*
2122
*/
2223
public class MixinTimer {
2324

25+
/**
26+
* <p>How many ticks elapsed since the {@link Timer#updateTimer()} method was called.
27+
* <p>Used in Minecraft#runGameLoop to call {@link Minecraft#runTick()} in the for loop
28+
*/
2429
@Shadow
2530
private int elapsedTicks;
26-
@Shadow
27-
private float renderPartialTicks;
31+
/**
32+
* How many "frames" elapsed since the {@link Timer#updateTimer()} method was called
33+
*/
2834
@Shadow
2935
private float elapsedPartialTicks;
36+
/**
37+
* Value between 0-1 of how many frames have elapsed inbetween ticks
38+
*/
3039
@Shadow
31-
private long lastSyncSysClock;
40+
private float renderPartialTicks;
41+
/**
42+
* The last time the {@link Timer#updateTimer()} method was called
43+
*/
3244
@Shadow
33-
private float tickLength;
45+
private long lastSyncSysClock;
3446

47+
// ==========================================================
48+
49+
/**
50+
* System time the last time a tick has run and ticksync has triggered
51+
*/
3552
@Unique
36-
private long millisLastTick;
37-
@Unique
38-
private long lastGameLoop;
53+
private long timeSinceLastTick;
54+
/**
55+
* The tick length in the last tick
56+
*/
3957
@Unique
40-
private float lastTickDuration;
58+
private float lastTickLength;
4159

60+
/**
61+
* <p>Overwrites {@link Timer#updateTimer()} in a way,<br>
62+
* so that the tickrate matches the tickrate of the server.
63+
*
64+
* <p>It does this by removing {@link Timer#tickLength} from the equasion.<br>
65+
* Takes the time between incoming packets from {@link TickSyncClient#onClientPacket(com.minecrafttas.mctcommon.networking.interfaces.PacketID, java.nio.ByteBuffer, String) TickSyncClient.onClientPacket()}
66+
* and calculates the tickrate dynamically.
67+
*
68+
* <p>If no packet is present, it stops the client.<br>
69+
* This can happen when:
70+
* <ol>
71+
* <li>The packet did not reach it's destination</li>
72+
* <li>The tickrate on the server is 0</li>
73+
* <li>The server is lagging and unable to send packets</li>
74+
* <li>Another player is taking too long to send a packet</li>
75+
* </ol>
76+
*
77+
* @param ci
78+
*/
4279
@Inject(method = "updateTimer", at = @At("HEAD"), cancellable = true)
4380
public void inject_tick(CallbackInfo ci) {
44-
if (TASmodClient.client != null && !TASmodClient.client.isClosed()) {
45-
lastSyncSysClock = Minecraft.getSystemTime(); // update the tick tracker so that after returning to scheduling the client won't catch up all ticks (max 10)
46-
this.elapsedTicks = 0; // do not do any ticks
47-
long newGameLoop = Minecraft.getSystemTime();
81+
/*
82+
* Run overriden updateTimer method
83+
*
84+
* Only runs when there is a connection to the custom networking server and the player is in a world
85+
*/
86+
if (TASmodClient.client != null && !TASmodClient.client.isClosed() && Minecraft.getMinecraft().world != null) {
87+
88+
long currentTime = Minecraft.getSystemTime(); // The current system time as of calling this method
89+
/*
90+
* The length of the tick in milliseconds.
91+
* Set to 50 in vanilla, but in this instance,
92+
* it is set to the duration of when Ticksync.shouldTick was true
93+
*/
94+
float tickLength = lastTickLength;
95+
96+
this.elapsedTicks = 0; // Prevent the client from ticking
97+
98+
/*
99+
* Ticksync block.
100+
* Allows the client to run for 1 tick if TickSyncClient.shouldTick is true
101+
*/
48102
if (TickSyncClient.shouldTick.compareAndSet(true, false)) {
49-
this.elapsedTicks++;
50-
this.lastTickDuration = newGameLoop - this.millisLastTick;
103+
104+
this.elapsedTicks++; // Allow the client to tick once
105+
tickLength = currentTime - timeSinceLastTick; // Check the time between ticks
51106
if (TASmodClient.tickratechanger.advanceTick) {
52-
lastTickDuration = TASmodClient.tickratechanger.millisecondsPerTick; // Keep the lastTick duration steady during tickadvance, since it grows larger the longer you wait in tickrate 0
107+
tickLength = TASmodClient.tickratechanger.millisecondsPerTick; // Keep the lastTick duration steady during tickadvance, since it grows larger the longer you wait in tickrate 0
53108
}
54-
this.millisLastTick = newGameLoop; // Update millisLastTick
55-
this.renderPartialTicks = 0; // Reset after the tick
109+
timeSinceLastTick = currentTime;
110+
this.renderPartialTicks = 0; // Reset render partial ticks after a new tick
56111
}
57-
// Interpolating
58-
this.elapsedPartialTicks = (newGameLoop - this.lastGameLoop) / this.lastTickDuration;
59-
float newPartialTicks = this.renderPartialTicks;
60-
newPartialTicks += this.elapsedPartialTicks;
61-
newPartialTicks -= (int) this.renderPartialTicks;
62-
if (newPartialTicks > this.renderPartialTicks) {
63-
this.renderPartialTicks = newPartialTicks;
112+
113+
/*
114+
* Vanilla calculation from updateTimer,
115+
* with added interpolation calculation
116+
*/
117+
this.elapsedPartialTicks = (currentTime - this.lastSyncSysClock) / tickLength; // Use the calculated tickLength instead of the vanill tickLength
118+
float newRenderPartialTicks = this.renderPartialTicks;
119+
newRenderPartialTicks += this.elapsedPartialTicks;
120+
newRenderPartialTicks -= (int) this.renderPartialTicks;
121+
122+
if (newRenderPartialTicks > this.renderPartialTicks) { // Fixes stuttering when the renderPartialTicks stay the same during tickrate 0
123+
this.renderPartialTicks = newRenderPartialTicks;
64124
}
65-
this.lastGameLoop = newGameLoop;
125+
126+
this.lastSyncSysClock = currentTime; // Update vanilla variable
127+
lastTickLength = tickLength; // Update last tick length
66128
ci.cancel();
67-
} else {
68-
this.millisLastTick = Minecraft.getSystemTime();
69-
this.lastGameLoop = Minecraft.getSystemTime();
70-
TickSyncClient.shouldTick.set(true); // The client should always tick if it once thrown out of the vanilla scheduling part, to make the server tick, etc.
129+
}
130+
// Run vanilla updateTimer
131+
else {
132+
this.timeSinceLastTick = Minecraft.getSystemTime();
133+
TickSyncClient.shouldTick.set(true); // Client should always tick, when in the main menu
71134
}
72135
}
73136
}

src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public class PlaybackControllerClient implements
103103
EventVirtualInput.EventVirtualCameraAngleTick,
104104

105105
EventVirtualInput.EventVirtualMouseSubtick
106-
//@formatter:on
106+
//@formatter:on
107107
{
108108
private Logger logger = TASmod.LOGGER;
109109

src/main/java/com/minecrafttas/tasmod/ticksync/TickSyncClient.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,10 @@
1515
import net.minecraft.client.Minecraft;
1616

1717
/**
18-
* This class manages tick sync
19-
* German: https://1drv.ms/p/s!Av_ysXerhm5CphLvLvguvL5QYe1A?e=MHPldP
20-
* English: https://1drv.ms/p/s!Av_ysXerhm5Cpha7Qq2tiVebd4DY?e=pzxOva
21-
*
18+
* <p>Synchronizes the client tickrate with the server tickrate
19+
*
2220
* @author Pancake
21+
* @see TickSyncServer
2322
*/
2423
public class TickSyncClient implements ClientPacketHandler, EventClientTickPost {
2524

src/main/java/com/minecrafttas/tasmod/ticksync/TickSyncServer.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@
1919
import net.minecraft.server.MinecraftServer;
2020

2121
/**
22-
* This class manages tick sync
23-
* German: https://1drv.ms/p/s!Av_ysXerhm5CphLvLvguvL5QYe1A?e=MHPldP
24-
* English: https://1drv.ms/p/s!Av_ysXerhm5Cpha7Qq2tiVebd4DY?e=pzxOva
25-
*
22+
* <p>Synchronizes the server tickrate with all clients
23+
*
2624
* @author Pancake
25+
* @see TickSyncClient
2726
*/
2827
public class TickSyncServer implements ServerPacketHandler, EventServerTickPost, EventClientCompleteAuthentication {
2928

0 commit comments

Comments
 (0)