diff --git a/README.md b/README.md
index cf8a08978f2427e1e6e466187ab3adbf7a338e66..32d490badfe0760ce97ff095fa9e463b0c462d41 100644
--- a/README.md
+++ b/README.md
@@ -71,10 +71,10 @@ auto count = 0;
 
 frame.add_run([&]() {
 
-    sleep(1.0);
+    sleep(seconds(1));
     count++;
 
-    log()->debug("{} - running {} sec", count, frame.get_running_time());
+    log()->debug("{} - running {} sec", count, to_sec(frame.get_running_time()));
 
     if (count == 3)
         frame.shut_down();
diff --git a/ext/Vulkan-Headers b/ext/Vulkan-Headers
index 6be1d00866a6d3bf8a1839b902d1de9e7065a4b8..5bc459e2921304c32568b73edaac8d6df5f98b84 160000
--- a/ext/Vulkan-Headers
+++ b/ext/Vulkan-Headers
@@ -1 +1 @@
-Subproject commit 6be1d00866a6d3bf8a1839b902d1de9e7065a4b8
+Subproject commit 5bc459e2921304c32568b73edaac8d6df5f98b84
diff --git a/ext/assimp b/ext/assimp
index 3bfd06483e53df4656607c726db271f5191e4a25..aa4c9fb5fa2f6ce0d040fdd5aaa25eea13bf4d39 160000
--- a/ext/assimp
+++ b/ext/assimp
@@ -1 +1 @@
-Subproject commit 3bfd06483e53df4656607c726db271f5191e4a25
+Subproject commit aa4c9fb5fa2f6ce0d040fdd5aaa25eea13bf4d39
diff --git a/ext/glfw b/ext/glfw
index 1e20218b3da47691ab5589592f41ce50856f7273..28d850770022afc8b73d88a871fa07e8d35766b3 160000
--- a/ext/glfw
+++ b/ext/glfw
@@ -1 +1 @@
-Subproject commit 1e20218b3da47691ab5589592f41ce50856f7273
+Subproject commit 28d850770022afc8b73d88a871fa07e8d35766b3
diff --git a/ext/imgui b/ext/imgui
index 4e56de757c76c9d713d4f05a0f6adf82d1aac068..792a8631aafd3df8d45563e3af60e39feb20b31d 160000
--- a/ext/imgui
+++ b/ext/imgui
@@ -1 +1 @@
-Subproject commit 4e56de757c76c9d713d4f05a0f6adf82d1aac068
+Subproject commit 792a8631aafd3df8d45563e3af60e39feb20b31d
diff --git a/ext/stb b/ext/stb
index 052dce117ed989848a950308bd99eef55525dfb1..f67165c2bb2af3060ecae7d20d6f731173485ad0 160000
--- a/ext/stb
+++ b/ext/stb
@@ -1 +1 @@
-Subproject commit 052dce117ed989848a950308bd99eef55525dfb1
+Subproject commit f67165c2bb2af3060ecae7d20d6f731173485ad0
diff --git a/ext/tinyobjloader b/ext/tinyobjloader
index 6ce9d4398b75584ecdb712520a2a8c9018aff1c1..5a36f8d99a3e0849f941fc531360cefe801b3402 160000
--- a/ext/tinyobjloader
+++ b/ext/tinyobjloader
@@ -1 +1 @@
-Subproject commit 6ce9d4398b75584ecdb712520a2a8c9018aff1c1
+Subproject commit 5a36f8d99a3e0849f941fc531360cefe801b3402
diff --git a/liblava/core/time.hpp b/liblava/core/time.hpp
index eaaef8dfc19a1e1d2cf1d2e0142897980d5e5d68..abcf9fd5ff4903cccf887249360a6fe9f4f0657e 100644
--- a/liblava/core/time.hpp
+++ b/liblava/core/time.hpp
@@ -12,82 +12,44 @@
 
 namespace lava {
 
-inline time ms_in_seconds(ui32 ms) { return ms / 1000.f; }
+using seconds = std::chrono::seconds;
+using milliseconds = std::chrono::milliseconds;
 
-inline ui32 seconds_in_ms(time sec) { return to_ui32(sec * 1000.f); }
+using clock = std::chrono::high_resolution_clock;
+using time_point = clock::time_point;
+using duration = clock::duration;
 
-struct time_info {
-
-    ui32 hours = 0;
-    ui32 minutes = 0;
-    ui32 seconds = 0;
-    ui32 ms = 0;
-};
-
-inline time to_time(ui32 hours = 0, ui32 minutes = 0, ui32 seconds = 0, ui32 ms = 0) {
-
-    return hours * 3600 + minutes * 60 + seconds + ms / 1000.;
-}
-
-inline time to_time(time_info info) {
-
-    return to_time(info.hours, info.minutes, info.seconds, info.ms);
-}
-
-inline time_info to_time(time time) {
-
-    time_info info;
-    info.hours = to_ui32(time / 3600);
-    auto temp = time - info.hours * 3600;
-    info.minutes = to_ui32(temp / 60);
-    temp = temp - info.minutes * 60;
-    info.seconds = to_ui32(temp);
-    temp = temp - info.seconds;
-    info.ms = to_ui32(temp * 1000);
-    return info;
-}
-
-using time_point = std::chrono::high_resolution_clock::time_point;
-using duration = std::chrono::high_resolution_clock::duration;
-
-inline float to_float_seconds(duration d) {
-
-    return std::chrono::duration_cast<std::chrono::duration<float>>(d).count();
-}
+inline r64 to_sec(milliseconds ms) { return ms.count() / 1000.0; }
+inline milliseconds to_ms(r64 sec) { return milliseconds(to_i32(sec * 1000.0)); }
 
 struct timer {
 
-    timer() : time_point(clock::now()) {}
+    timer() : start_time(clock::now()) {}
 
-    void reset() { time_point = clock::now(); }
+    void reset() { start_time = clock::now(); }
 
-    time elapsed() const {
+    milliseconds elapsed() const {
 
-        return std::chrono::duration_cast<second>(clock::now() - time_point).count();
+        return std::chrono::duration_cast<std::chrono::milliseconds>(clock::now() - start_time);
     }
 
 private:
-    using clock = std::chrono::high_resolution_clock;
-    using second = std::chrono::duration<time, std::ratio<1>>;
-
-    std::chrono::time_point<clock> time_point;
+    time_point start_time;
 };
 
 struct run_time {
 
-    time seconds = 0.;
-    time clock = 0.016;
+    milliseconds current;
+    milliseconds clock{ 16 };
 
-    time system = 0.;
-    time delta = 0.;
+    milliseconds system;
+    milliseconds delta;
 
     bool use_fix_delta = false;
-    time fix_delta = 0.02;
+    milliseconds fix_delta{ 20 };
 
     r32 speed = 1.f;
     bool paused = false;
-
-    time get_speed_delta() const { return delta * speed; }
 };
 
 #pragma warning(push)
diff --git a/liblava/core/types.hpp b/liblava/core/types.hpp
index 48db4097373f6abcfb5eada8c0c2a0c926e42b1f..7747ba46e41a1871976aea6c23ce3e135605d981 100644
--- a/liblava/core/types.hpp
+++ b/liblava/core/types.hpp
@@ -65,8 +65,6 @@ using size_t = std::size_t;
 using uchar = unsigned char;
 using r32 = float;
 using r64 = double;
-
-using time = r64;
 using real = r64;
 
 using type = ui32;
diff --git a/liblava/frame/frame.cpp b/liblava/frame/frame.cpp
index dddffd0ff7da9974bbfb82819c69a627502b2cb6..b945add68c4a117e6f69d7c4b04feac897a6a500 100644
--- a/liblava/frame/frame.cpp
+++ b/liblava/frame/frame.cpp
@@ -20,9 +20,11 @@ void hide_console(lava::name program) {
     std::cout << "starting " << program;
 
     const auto dot_count = 3;
+    const auto sleep_ms = lava::to_i32(1.0 / dot_count * 1000.f);
+
     for (auto i = 0u; i < dot_count; ++i) {
 
-        lava::sleep(1.0 / dot_count);
+        lava::sleep(lava::milliseconds(sleep_ms));
         std::cout << ".";
     }
 
@@ -51,7 +53,7 @@ void log_command_line(argh::parser& cmd_line) {
     }
 }
 
-lava::time lava::now() { return glfwGetTime(); }
+lava::milliseconds lava::now() { return to_ms(glfwGetTime()); }
 
 namespace lava {
 
@@ -223,7 +225,7 @@ bool frame::run() {
     trigger_run_end();
 
     running = false;
-    start_time = 0.0;
+    start_time = {};
 
     return true;
 }
@@ -294,17 +296,22 @@ void frame::trigger_run_end() {
 
 } // lava
 
-void lava::handle_events(bool wait_for_events) {
+void lava::handle_events(bool wait) {
 
-    if (wait_for_events)
+    if (wait)
         glfwWaitEvents();
     else
         glfwPollEvents();
 }
 
-void lava::handle_events(time timeout) {
+void lava::handle_events(milliseconds timeout) {
+
+    glfwWaitEventsTimeout(to_sec(timeout));
+}
+
+void lava::handle_events(seconds timeout) {
 
-    glfwWaitEventsTimeout(timeout);
+    glfwWaitEventsTimeout(to_r64(timeout.count()));
 }
 
 void lava::post_empty_event() {
diff --git a/liblava/frame/frame.hpp b/liblava/frame/frame.hpp
index 1bfdb2324456f2e0b40706ca6270ce4f85d1b548..9e2cd2e328fb34d22f86e3889bf5038948af7c65 100644
--- a/liblava/frame/frame.hpp
+++ b/liblava/frame/frame.hpp
@@ -32,7 +32,7 @@ enum error {
     aborted         = -3,
 };
 
-time now();
+milliseconds now();
 
 struct frame : no_copy_no_move {
 
@@ -60,7 +60,7 @@ struct frame : no_copy_no_move {
 
     bool remove(id::ref id);
 
-    time get_running_time() const { return now() - start_time; }
+    milliseconds get_running_time() const { return now() - start_time; }
 
     argh::parser& get_cmd_line() { return cmd_line; }
 
@@ -90,7 +90,7 @@ private:
 
     bool running = false;
     bool wait_for_events = false;
-    time start_time = 0.0;
+    milliseconds start_time;
 
     using run_func_map = std::map<id, run_func>;
     run_func_map run_map;
@@ -99,9 +99,10 @@ private:
     run_end_func_map run_end_map;
 };
 
-void handle_events(bool wait_for_events = false);
+void handle_events(bool wait = false);
 
-void handle_events(time timeout);
+void handle_events(milliseconds timeout);
+void handle_events(seconds timeout);
 
 void post_empty_event();
 
diff --git a/liblava/tool/forward_shading.cpp b/liblava/tool/forward_shading.cpp
index f6c7a69224d84574f2bb45f7a6393dc269343793..458e7d76348d1140395de58701f8288da3079100 100644
--- a/liblava/tool/forward_shading.cpp
+++ b/liblava/tool/forward_shading.cpp
@@ -1,5 +1,5 @@
 // file      : liblava/tool/forward_shading.cpp
-// copyright : Copyright (c) 2018-present, Lava Block O�
+// copyright : Copyright (c) 2018-present, Lava Block OÜ
 // license   : MIT; see accompanying LICENSE file
 
 #include <liblava/tool/forward_shading.hpp>
diff --git a/liblava/tool/forward_shading.hpp b/liblava/tool/forward_shading.hpp
index e048e5789759f1a8bdc6bfdf1c552586b998d464..12f2ae4b775676d26c7deb53e8595b29550154b6 100644
--- a/liblava/tool/forward_shading.hpp
+++ b/liblava/tool/forward_shading.hpp
@@ -1,5 +1,5 @@
 // file      : liblava/tool/forward_shading.hpp
-// copyright : Copyright (c) 2018-present, Lava Block O�
+// copyright : Copyright (c) 2018-present, Lava Block OÜ
 // license   : MIT; see accompanying LICENSE file
 
 #pragma once
diff --git a/liblava/tool/gui.cpp b/liblava/tool/gui.cpp
index e842ac055ecfb3708911787842e9eb97a0f41372..9c1b545cc630bf1720360e4326aebdc22c56cae2 100644
--- a/liblava/tool/gui.cpp
+++ b/liblava/tool/gui.cpp
@@ -1,5 +1,5 @@
 // file      : liblava/tool/gui.cpp
-// copyright : Copyright (c) 2018-present, Lava Block O�
+// copyright : Copyright (c) 2018-present, Lava Block OÜ
 // license   : MIT; see accompanying LICENSE file
 
 #include <liblava/tool/gui.hpp>
diff --git a/liblava/tool/gui.hpp b/liblava/tool/gui.hpp
index 1fe65e73121a447b2ac4a4ead458582e966875c1..63718af670249d738b8a42020c2abe79881968dc 100644
--- a/liblava/tool/gui.hpp
+++ b/liblava/tool/gui.hpp
@@ -1,5 +1,5 @@
 // file      : liblava/tool/gui.hpp
-// copyright : Copyright (c) 2018-present, Lava Block O�
+// copyright : Copyright (c) 2018-present, Lava Block OÜ
 // license   : MIT; see accompanying LICENSE file
 
 #pragma once
@@ -85,7 +85,7 @@ private:
     GLFWwindow* window = nullptr;
 
     bool mouse_just_pressed[5] = { false, false, false, false, false };
-    time current_time = 0.0;
+    r64 current_time = 0.0;
 
     std::vector<GLFWcursor*> mouse_cursors;
 
diff --git a/liblava/util/telegram.hpp b/liblava/util/telegram.hpp
index a93b2686eb1f2e77017bd0e8a01bad2affec0073..6f3f98c26abac8da49e0ded90e905db75555d80d 100644
--- a/liblava/util/telegram.hpp
+++ b/liblava/util/telegram.hpp
@@ -12,18 +12,18 @@
 
 namespace lava {
 
-constexpr time const telegram_min_delay = 0.25;
+constexpr milliseconds const telegram_min_delay{ 250 };
 
 struct telegram {
 
     using ref = telegram const&;
 
-    explicit telegram(id::ref sender, id::ref receiver, type msg, time dispatch_time = 0.0, std::any info = {}) 
+    explicit telegram(id::ref sender, id::ref receiver, type msg, milliseconds dispatch_time = {}, std::any info = {})
                         : sender(sender), receiver(receiver), msg(msg), dispatch_time(dispatch_time), info(std::move(info)) {}
 
     bool operator==(ref rhs) const {
 
-        return (fabs(dispatch_time - rhs.dispatch_time) < telegram_min_delay) &&
+        return ((dispatch_time - rhs.dispatch_time) < telegram_min_delay) &&
                     (sender == rhs.sender) && (receiver == rhs.receiver) && (msg == rhs.msg);
     }
 
@@ -40,7 +40,7 @@ struct telegram {
 
     type msg = no_type;
 
-    time dispatch_time = 0.0;
+    milliseconds dispatch_time;
     std::any info;
 };
 
@@ -50,17 +50,17 @@ struct dispatcher {
 
     void teardown() { pool.teardown(); }
 
-    void update(time current) {
+    void update(milliseconds current) {
 
         current_time = current;
         dispatch_delayed_messages(current_time);
     }
 
-    void add_message(id::ref receiver, id::ref sender, type message, time delay = 0.0, std::any const& info = {}) {
+    void add_message(id::ref receiver, id::ref sender, type message, milliseconds delay = {}, std::any const& info = {}) {
 
         telegram msg(sender, receiver, message, current_time, info);
 
-        if (delay <= 0.0) {
+        if (delay == milliseconds{}) {
 
             discharge(msg); // now
             return;
@@ -82,16 +82,16 @@ private:
         });
     }
 
-    void dispatch_delayed_messages(time time) {
+    void dispatch_delayed_messages(milliseconds time) {
 
-        while (!messages.empty() && (messages.begin()->dispatch_time < time) && (messages.begin()->dispatch_time > 0.0)) {
+        while (!messages.empty() && (messages.begin()->dispatch_time < time) && (messages.begin()->dispatch_time > milliseconds{})) {
 
             discharge(*messages.begin());
             messages.erase(messages.begin());
         }
     }
 
-    time current_time = 0.0;
+    milliseconds current_time;
 
     thread_pool pool;
     std::set<telegram> messages;
diff --git a/liblava/util/thread.hpp b/liblava/util/thread.hpp
index a63a58cbb621de30a60a8795a6872727cbec8512..264747dac15659368d36db4d253e9c445d08f20a 100644
--- a/liblava/util/thread.hpp
+++ b/liblava/util/thread.hpp
@@ -14,9 +14,14 @@
 
 namespace lava {
 
-inline void sleep(time seconds) {
+inline void sleep(milliseconds time) {
 
-    std::this_thread::sleep_for(std::chrono::milliseconds(seconds_in_ms(seconds)));
+    std::this_thread::sleep_for(time);
+}
+
+inline void sleep(seconds time) {
+
+    std::this_thread::sleep_for(time);
 }
 
 struct thread_pool {
diff --git a/tests/tests.cpp b/tests/tests.cpp
index 17d3085d12c6b41be97f3e2547ad3c63ae99ef08..670adf4fd68f706375478bb071ccb9ccb8bd7c3e 100644
--- a/tests/tests.cpp
+++ b/tests/tests.cpp
@@ -23,10 +23,10 @@ LAVA_TEST(2, "run loop")
 
     frame.add_run([&]() {
 
-        sleep(1.0);
+        sleep(seconds(1));
         count++;
 
-        log()->debug("{} - running {} sec", count, frame.get_running_time());
+        log()->debug("{} - running {} sec", count, to_sec(frame.get_running_time()));
 
         if (count == 3)
             frame.shut_down();
@@ -333,7 +333,7 @@ LAVA_TEST(6, "gamepad listener")
 
     frame.add_run([&]() {
 
-        sleep(1.0);
+        sleep(seconds(1));
 
         return true;
     });