Bug is also in latest beta (1.74pr20)
When sleeping for 0.2s towards 0.65s included, it adds another tick. Meaning a 0.2s sleep actually is 0.25, and so on.
Output from test program, first arg is sample count, second is time. (Yes, it is consistent with higher sample count)
Edit:
After decompiling the source, the problem seems to be in OSAPI.java
public void advance(double dt) {
Map var3 = this.m_timers;
synchronized(this.m_timers) {
this.m_clock += dt;
Iterator previousTime = this.m_timers.entrySet().iterator();
while(previousTime.hasNext()) {
Entry entry = (Entry)previousTime.next();
OSAPI.Timer previousDay = (OSAPI.Timer)entry.getValue();
previousDay.m_timeLeft -= dt;
if(previousDay.m_timeLeft <= 0.0D) {
this.queueLuaEvent("timer", new Object[]{entry.getKey()});
previousTime.remove();
}
}
}
The inaccuracy is caused by the use of doubles at the m_timeLeft -= dt;Digging deeper, said method is called from ServerComputer.java
public void update() {
super.update();
this.m_computer.advance(0.05D);
this.m_changedLastFrame = this.m_changed || this.m_computer.pollChanged();
this.m_computer.clearChanged();
this.m_changed = false;
++this.m_ticksSincePing;
}
Edit 2:
Proof that this is due to the use of doubles, and not tick alignment (or whatever other magical phenomenon you specify it under).
https://ideone.com/hqthf8
Incase Ideone doesn
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
/* test 1 */
double left1 = 0.65;
int foo1 = 0;
while (left1 > 0.0d) {
left1 -= 0.05d;
foo1++;
}
System.out.println(foo1);
/* test 2 */
double left2 = 0.7;
int foo2 = 0;
while (left2 > 0.0d) {
left2 -= 0.05d;
foo2++;
}
System.out.println(foo2);
}
}
Can this be changed to ticks represented in integers instead?