Godot: get_system_time_msecs() doesn't update when assigned to Vector2 (very strange)

Created on 14 Apr 2020  路  4Comments  路  Source: godotengine/godot

Godot version: 3.2.1-1

OS/device including version: Linux Arch 5.5.13-arch2-1 x86_64

Issue description: Vector doesn't update when using variable assigned to OS.get_system_time_msecs() as value.

Steps to reproduce:

Simply putting a print(Vector2(OS.get_system_time_msecs(), 1) somewhere in _process suffices. Or, create a Node2D somewhere and add following script to it:

extends Node2D

var t = 0
func _process(delta):
  t += delta
  if t < .5:
    return
  t -= 1
  var ticks = OS.get_ticks_msec()
  var time = OS.get_system_time_msecs()
  print("----")
  print("ticks update correctly: %s" % ticks)
  print("ticks Vector updates correctly: %s" %  Vector2(ticks, 1))
  print("system time updates correctly: %s" % time)
  print("system time Vector hangs: %s" %  Vector2(time, 1))

The first three lines will update correctly with time passing but the last line hangs up on a value and doesn't update.

Minimal reproduction project:

IssueProject.zip

Workaround:

using Array [time, 1] instead of Vector2.

archived bug core

Most helpful comment

I don't think this is a bug.
Vector2 still uses 32-bit single-precision float - so it looks like a floating point overflow to me because OS.get_system_time_msecs returns a real large 64 bit integer.

See https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/gdscript_basics.html#built-in-types under float.

Issue #6900 may be related to the limit.

All 4 comments

Just a quick thought on my part.
Could maybe be some kind of optimization gone wrong?
However I'm not that deep in the foundation of godot to know what exactly could be the cause.

PS: I tried the project and could reproduce it.
Godot version: 3.2.1.stable.mono.official
OS: Windows 10 pro
OS Version: 1903
OS Build: 18362.175

A problem with optimization was my first thought, too. Still I don't have any clue what could be wrong. The used code should be:

os_unix.cpp

uint64_t OS_Unix::get_system_time_msecs() const {
    struct timeval tv_now;
    gettimeofday(&tv_now, nullptr);
    return uint64_t(tv_now.tv_sec) * 1000 + uint64_t(tv_now.tv_usec) / 1000;
}

os_windows.cpp

uint64_t OS_Windows::get_system_time_msecs() const {

    const uint64_t WINDOWS_TICK = 10000;
    const uint64_t MSEC_TO_UNIX_EPOCH = 11644473600000LL;

    SYSTEMTIME st;
    GetSystemTime(&st);
    FILETIME ft;
    SystemTimeToFileTime(&st, &ft);
    uint64_t ret;
    ret = ft.dwHighDateTime;
    ret <<= 32;
    ret |= ft.dwLowDateTime;

    return (uint64_t)(ret / WINDOWS_TICK - MSEC_TO_UNIX_EPOCH);
}

gdnative/vector2.cpp

void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y) {

    Vector2 *dest = (Vector2 *)r_dest;
    *dest = Vector2(p_x, p_y);
}

core/math/vector2.h

_FORCE_INLINE_ Vector2(real_t p_x, real_t p_y) {
    x = p_x;
    y = p_y;
}

If I will start compiling the godot engine some time, I'd try removing the _FORCE_INLINE_ tag and putting the constructor to vector2.cpp to see if it helps.

I don't think this is a bug.
Vector2 still uses 32-bit single-precision float - so it looks like a floating point overflow to me because OS.get_system_time_msecs returns a real large 64 bit integer.

See https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/gdscript_basics.html#built-in-types under float.

Issue #6900 may be related to the limit.

So true. Every now and then this happens to me, no matter which programming language, but in most cases because of the 64-bit millisecond time. Thanks @MrRevington !

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RebelliousX picture RebelliousX  路  3Comments

mefihl picture mefihl  路  3Comments

Spooner picture Spooner  路  3Comments

gonzo191 picture gonzo191  路  3Comments

bojidar-bg picture bojidar-bg  路  3Comments