Skip to content

Commit f7f8794

Browse files
committed
feat: tps clock
1 parent e93d412 commit f7f8794

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.module.hud
19+
20+
import com.lambda.module.HudModule
21+
import com.lambda.module.tag.ModuleTag
22+
import com.lambda.util.TpsClock.normalizedTickRate
23+
import com.lambda.util.math.MathUtils.format
24+
25+
object TPS : HudModule(
26+
name = "TPS",
27+
description = "Display the server's tick rate",
28+
defaultTags = setOf(ModuleTag.CLIENT, ModuleTag.NETWORK),
29+
) {
30+
private val format by setting("Tick format", TickFormat.Tick)
31+
32+
private val text: String get() = "${format.string}: ${format.output().format(2)}"
33+
34+
// TODO: Replace by LambdaAtlas height cache
35+
36+
override val height: Double get() = 20.0
37+
override val width: Double get() = 50.0
38+
39+
init {
40+
onRender {
41+
font.build(text, position)
42+
}
43+
}
44+
45+
private enum class TickFormat(val output: () -> Double, val string: String) {
46+
Tick({ normalizedTickRate * 20 }, "TPS"),
47+
Milliseconds({ normalizedTickRate * 50 }, "MSPS"),
48+
Normalized({ normalizedTickRate }, "TPSN"),
49+
Percentage({ normalizedTickRate * 100 }, "TPS%")
50+
}
51+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.util
19+
20+
import com.lambda.event.events.ConnectionEvent
21+
import com.lambda.event.events.PacketEvent
22+
import com.lambda.event.listener.SafeListener.Companion.listen
23+
import com.lambda.util.collections.LimitedDecayQueue
24+
import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket
25+
26+
object TpsClock {
27+
private val tickHistory = LimitedDecayQueue<Double>(120, 5000)
28+
private var lastUpdate = 0L
29+
30+
/**
31+
* Returns the average tick rate normalized between 0 and 1
32+
*/
33+
val normalizedTickRate: Double
34+
get() {
35+
val average = tickHistory.average()
36+
return if (average.isNaN()) 1.0 else average
37+
}
38+
39+
/**
40+
* Returns the average tick rate normalized multiplied by 20
41+
*/
42+
val tickRate: Double get() = normalizedTickRate * 20
43+
44+
init {
45+
listen<PacketEvent.Receive.Pre>(priority = 10000) {
46+
if (it.packet !is WorldTimeUpdateS2CPacket) return@listen
47+
48+
49+
if (lastUpdate != 0L) {
50+
val timeElapsed = (System.nanoTime() - lastUpdate) / 1E9
51+
tickHistory.add((1 / timeElapsed).coerceIn(0.0, 1.0))
52+
}
53+
54+
lastUpdate = System.nanoTime()
55+
}
56+
57+
listen<ConnectionEvent.Connect.Post> {
58+
tickHistory.clear()
59+
lastUpdate = 0
60+
}
61+
}
62+
}

common/src/main/kotlin/com/lambda/util/math/MathUtils.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,7 @@ object MathUtils {
8282

8383
fun Int.nextPowerOf2() = 2f.pow(ceil(log2(toFloat()))).toInt()
8484

85+
fun Double.format(scale: Int) = "%.${scale}f".format(this)
86+
8587
inline val Int.sq: Int get() = this * this
8688
}

0 commit comments

Comments
 (0)