fix tick intervals in headless mode

This commit is contained in:
MihailRis 2026-05-02 15:36:49 +03:00
parent 843cc3769d
commit 0975fcd819
4 changed files with 56 additions and 41 deletions

View file

@ -130,11 +130,15 @@ void BlocksController::updateBlock(int x, int y, int z) {
} }
void BlocksController::update(float delta, uint padding) { void BlocksController::update(float delta, uint padding) {
if (randTickClock.update(delta)) { if (int parts = randTickClock.update(delta)) {
randomTick(randTickClock.getPart(), randTickClock.getParts(), padding); for (int i = 0; i < parts; i++) {
randomTick(randTickClock.convertPart(i), randTickClock.getParts(), padding);
}
} }
if (blocksTickClock.update(delta)) { if (int parts = blocksTickClock.update(delta)) {
onBlocksTick(blocksTickClock.getTickId(), blocksTickClock.getParts()); for (int i = 0; i < parts; i++) {
onBlocksTick(blocksTickClock.convertPart(i), blocksTickClock.getParts());
}
} }
if (worldTickClock.update(delta)) { if (worldTickClock.update(delta)) {
scripting::on_world_tick(worldTickClock.getTickRate()); scripting::on_world_tick(worldTickClock.getTickRate());

View file

@ -288,22 +288,24 @@ void Entities::preparePhysics(float delta) {
auto& hitboxes = physics.getHitboxesWriteable(); auto& hitboxes = physics.getHitboxesWriteable();
auto& solidHitboxes = physics.getSolidHitboxesWriteable(); auto& solidHitboxes = physics.getSolidHitboxesWriteable();
if (sensorsTickClock.update(delta)) { if (int parts = sensorsTickClock.update(delta)) {
auto part = sensorsTickClock.getPart(); for (int i = 0; i < parts; i++) {
auto parts = sensorsTickClock.getParts(); auto part = sensorsTickClock.convertPart(i);
auto allParts = sensorsTickClock.getParts();
auto& sensors = physics.getSensorsWriteable(); auto& sensors = physics.getSensorsWriteable();
sensors.clear(); sensors.clear();
auto view = registry->view<EntityId, Transform, Rigidbody>(); auto view = registry->view<EntityId, Transform, Rigidbody>();
for (auto [entity, eid, transform, rigidbody] : view.each()) { for (auto [entity, eid, transform, rigidbody] : view.each()) {
if (!rigidbody.enabled) { if (!rigidbody.enabled) {
continue; 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) { void Entities::update(float delta) {
if (updateTickClock.update(delta)) { if (int parts = updateTickClock.update(delta)) {
scripting::on_entities_update( for (int i = 0; i < parts; i++) {
updateTickClock.getTickRate(), scripting::on_entities_update(
updateTickClock.getParts(), updateTickClock.getTickRate(),
updateTickClock.getPart() updateTickClock.getParts(),
); updateTickClock.convertPart(i)
);
}
} }
updatePhysics(delta); updatePhysics(delta);
scripting::on_entities_physics_update(delta); scripting::on_entities_physics_update(delta);

View file

@ -8,30 +8,32 @@ Clock::Clock(int tickRate, int tickParts)
: tickRate(tickRate), tickParts(tickParts) { : tickRate(tickRate), tickParts(tickParts) {
} }
bool Clock::update(float delta) { int Clock::update(float delta) {
tickTimer += delta; tickTimer += delta;
float delay = 1.0f / static_cast<float>(tickRate); float delay = 1.0f / static_cast<float>(tickRate);
if (tickTimer > delay || tickPartsUndone) { if (tickTimer < delay / tickParts) {
if (tickPartsUndone) { return 0;
tickPartsUndone--;
} else {
tickTimer = std::fmod(tickTimer, delay);
tickPartsUndone = tickParts - 1;
}
++tickId;
return true;
} }
return false; int parts = tickTimer / (delay / tickParts);
if (parts) {
tickTimer -= parts * delay / tickParts;
tickTimer = std::min<float>(tickTimer, delay);
}
currentTickPart += parts;
if (currentTickPart >= tickParts) {
currentTickPart %= tickParts;
}
return parts;
}
int Clock::getPart() const {
return currentTickPart;
} }
int Clock::getParts() const { int Clock::getParts() const {
return tickParts; return tickParts;
} }
int Clock::getPart() const {
return tickParts - tickPartsUndone - 1;
}
int Clock::getTickRate() const { int Clock::getTickRate() const {
return tickRate; return tickRate;
} }
@ -39,3 +41,7 @@ int Clock::getTickRate() const {
int Clock::getTickId() const { int Clock::getTickId() const {
return tickId; return tickId;
} }
int Clock::convertPart(int index) const {
return (tickParts - currentTickPart) % tickParts + index;
}

View file

@ -7,15 +7,16 @@ namespace util {
float tickTimer = 0.0f; float tickTimer = 0.0f;
int tickId = 0; int tickId = 0;
int tickPartsUndone = 0; int currentTickPart = 0;
public: public:
Clock(int tickRate, int tickParts); Clock(int tickRate, int tickParts);
bool update(float delta); int update(float delta);
int getParts() const;
int getPart() const; int getPart() const;
int getParts() const;
int getTickRate() const; int getTickRate() const;
int getTickId() const; int getTickId() const;
int convertPart(int index) const;
}; };
} }