From 0975fcd8193025c171acf0644babfb570e53c468 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 2 May 2026 15:36:49 +0300 Subject: [PATCH] fix tick intervals in headless mode --- src/logic/BlocksController.cpp | 12 ++++++---- src/objects/Entities.cpp | 42 +++++++++++++++++++--------------- src/util/Clock.cpp | 36 +++++++++++++++++------------ src/util/Clock.hpp | 7 +++--- 4 files changed, 56 insertions(+), 41 deletions(-) diff --git a/src/logic/BlocksController.cpp b/src/logic/BlocksController.cpp index 3c0d0412e..58594f6ee 100644 --- a/src/logic/BlocksController.cpp +++ b/src/logic/BlocksController.cpp @@ -130,11 +130,15 @@ void BlocksController::updateBlock(int x, int y, int z) { } void BlocksController::update(float delta, uint padding) { - if (randTickClock.update(delta)) { - randomTick(randTickClock.getPart(), randTickClock.getParts(), padding); + if (int parts = randTickClock.update(delta)) { + for (int i = 0; i < parts; i++) { + randomTick(randTickClock.convertPart(i), randTickClock.getParts(), padding); + } } - if (blocksTickClock.update(delta)) { - onBlocksTick(blocksTickClock.getTickId(), blocksTickClock.getParts()); + if (int parts = blocksTickClock.update(delta)) { + for (int i = 0; i < parts; i++) { + onBlocksTick(blocksTickClock.convertPart(i), blocksTickClock.getParts()); + } } if (worldTickClock.update(delta)) { scripting::on_world_tick(worldTickClock.getTickRate()); diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 7d2db5b84..61b312a24 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -288,22 +288,24 @@ void Entities::preparePhysics(float delta) { auto& hitboxes = physics.getHitboxesWriteable(); auto& solidHitboxes = physics.getSolidHitboxesWriteable(); - if (sensorsTickClock.update(delta)) { - auto part = sensorsTickClock.getPart(); - auto parts = sensorsTickClock.getParts(); + if (int parts = sensorsTickClock.update(delta)) { + for (int i = 0; i < parts; i++) { + auto part = sensorsTickClock.convertPart(i); + auto allParts = sensorsTickClock.getParts(); - auto& sensors = physics.getSensorsWriteable(); - sensors.clear(); + auto& sensors = physics.getSensorsWriteable(); + sensors.clear(); - auto view = registry->view(); - for (auto [entity, eid, transform, rigidbody] : view.each()) { - if (!rigidbody.enabled) { - continue; + auto view = registry->view(); + for (auto [entity, eid, transform, rigidbody] : view.each()) { + if (!rigidbody.enabled) { + continue; + } + if ((eid.uid + part) % allParts != 0) { + continue; + } + updateSensors(rigidbody, transform, sensors); } - if ((eid.uid + part) % parts != 0) { - continue; - } - updateSensors(rigidbody, transform, sensors); } } @@ -364,12 +366,14 @@ void Entities::updatePhysics(float delta) { } void Entities::update(float delta) { - if (updateTickClock.update(delta)) { - scripting::on_entities_update( - updateTickClock.getTickRate(), - updateTickClock.getParts(), - updateTickClock.getPart() - ); + if (int parts = updateTickClock.update(delta)) { + for (int i = 0; i < parts; i++) { + scripting::on_entities_update( + updateTickClock.getTickRate(), + updateTickClock.getParts(), + updateTickClock.convertPart(i) + ); + } } updatePhysics(delta); scripting::on_entities_physics_update(delta); diff --git a/src/util/Clock.cpp b/src/util/Clock.cpp index 0d4f74021..cc210b997 100644 --- a/src/util/Clock.cpp +++ b/src/util/Clock.cpp @@ -8,30 +8,32 @@ Clock::Clock(int tickRate, int tickParts) : tickRate(tickRate), tickParts(tickParts) { } -bool Clock::update(float delta) { +int Clock::update(float delta) { tickTimer += delta; float delay = 1.0f / static_cast(tickRate); - if (tickTimer > delay || tickPartsUndone) { - if (tickPartsUndone) { - tickPartsUndone--; - } else { - tickTimer = std::fmod(tickTimer, delay); - tickPartsUndone = tickParts - 1; - } - ++tickId; - return true; + if (tickTimer < delay / tickParts) { + return 0; } - return false; + int parts = tickTimer / (delay / tickParts); + if (parts) { + tickTimer -= parts * delay / tickParts; + tickTimer = std::min(tickTimer, delay); + } + currentTickPart += parts; + if (currentTickPart >= tickParts) { + currentTickPart %= tickParts; + } + return parts; +} + +int Clock::getPart() const { + return currentTickPart; } int Clock::getParts() const { return tickParts; } -int Clock::getPart() const { - return tickParts - tickPartsUndone - 1; -} - int Clock::getTickRate() const { return tickRate; } @@ -39,3 +41,7 @@ int Clock::getTickRate() const { int Clock::getTickId() const { return tickId; } + +int Clock::convertPart(int index) const { + return (tickParts - currentTickPart) % tickParts + index; +} diff --git a/src/util/Clock.hpp b/src/util/Clock.hpp index 37c5f4ebf..a2c529d0f 100644 --- a/src/util/Clock.hpp +++ b/src/util/Clock.hpp @@ -7,15 +7,16 @@ namespace util { float tickTimer = 0.0f; int tickId = 0; - int tickPartsUndone = 0; + int currentTickPart = 0; public: Clock(int tickRate, int tickParts); - bool update(float delta); + int update(float delta); - int getParts() const; int getPart() const; + int getParts() const; int getTickRate() const; int getTickId() const; + int convertPart(int index) const; }; }