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

The explanation and usage of "tick delta" in the docs are completely incorrect #173

Open
Octol1ttle opened this issue Aug 26, 2024 · 0 comments
Labels
correction Something isn't right on a page needs-discussion Further discussion is needed

Comments

@Octol1ttle
Copy link
Contributor

Tick delta is a term used quite often in the rendering pages, The Basic Rendering Concepts page refers to it as "which is the time that has passed since the last frame". Rendering in the Hud further elaborates on this by explaining it as "the time since the last frame, in seconds."

As obvious from the issue title, both of these explanations are wrong. Unfortunately, not everyone is aware of this. Browsing the mod-dev channels in the Fabricord, it is quite easy to find examples of people sharing this wrong explanation, and other people encountering issues in their code when they use it as explained in the docs or by others.

Let's look at the game code to determine what "tick delta" actually is:

public int beginRenderTick(long timeMillis) {
		this.lastFrameDuration = (float)(timeMillis - this.prevTimeMillis) / this.targetMillisPerTick.apply(this.tickTime);
		this.prevTimeMillis = timeMillis;
		this.tickDelta = this.tickDelta + this.lastFrameDuration;
		int i = (int)this.tickDelta;
		this.tickDelta -= (float)i;
		return i;
	}

This is Yarn mappings. Unfortunately, the lastFrameDuration field name is also incorrect, I'll PR a fix some time later.
Looking at this, we see that tickDelta gets incremented with lastFrameDuration (which is the time between frames, converted to game ticks, depending on the server's selected tick rate), and then i is subtracted from it. i is calculated by casting the tickDelta to an integer, which drops the decimal part. So converting 319.64 would result in 319, 59.03 would result in 59.

Two things are obvious here:

  1. the calculation of tickDelta on the current frame is dependent on the value from the previous frame
  2. tickDelta is never less than 0 or more than 1

With this mind, we can come to the conclusion that tickDelta is the "progress" between the last game tick and the next game tick. For example, if we assume the game runs at 60 FPS, this is what tickDelta would be on different frames:

  • Frame 1: game tick, tickDelta is 1.0
  • Frame 2: no game tick, tickDelta is 0.33
  • Frame 3: no game tick, tickDelta is 0.67
  • Frame 4: game tick, tickDelta is 1.0

We can prove this further by looking at usages of tickDelta. tickDelta is often used in combination with MathHelper#lerp, which would never work correctly if tickDelta was actually time since last frame.

I hope this is sufficient evidence that the explanation needs to be corrected. The implementation of RenderTickCounter#getTickDelta can be looked at if this is not enough proof

@its-miroma its-miroma added correction Something isn't right on a page needs-discussion Further discussion is needed labels Oct 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
correction Something isn't right on a page needs-discussion Further discussion is needed
Projects
None yet
Development

No branches or pull requests

2 participants