repoverse / unify /engine /net /rollback.cpp
SNAPKITTYWEST's picture
October 2026 main drop: mirror from GitHub
3ce1a40 verified
Raw History Blame Contribute Delete
1.85 kB
#include "rollback.h"
#include "../runtime/engine.h"
namespace unify {
void RollbackBuffer::advance(Engine& engine) {
uint64_t tick = engine.sim_clock().tick;
if (tick % interval_ == 0) snaps_.push_back({tick, engine.save_state(false)});
engine.tick();
log_.push_back(engine.input().frame());
// Bound history: drop snapshots (and the input they cover) older than the window.
while (!snaps_.empty() && tick - snaps_.front().tick > max_ticks_ && snaps_.size() > 1) snaps_.pop_front();
while (!log_.empty() && !snaps_.empty() && log_.front().tick < snaps_.front().tick) log_.pop_front();
}
bool RollbackBuffer::rewind_and_resimulate(Engine& engine, uint64_t tick, std::string& error) {
uint64_t now = engine.sim_clock().tick;
const Snap* base = nullptr;
for (const Snap& s : snaps_) if (s.tick <= tick) base = &s;
if (!base) { error = "tick is older than the rollback window"; return false; }
if (!engine.load_state(base->state, error)) return false;
for (const InputFrame& f : log_) {
if (f.tick < base->tick) continue;
if (f.tick >= now) break;
if (f.tick % interval_ == 0) { // refresh snapshots along the corrected timeline
for (Snap& s : snaps_) if (s.tick == f.tick) s.state = engine.save_state(false);
}
engine.replay_tick(f);
resimulated_++;
}
return engine.sim_clock().tick == now || (error = "resimulation ended at the wrong tick", false);
}
bool RollbackBuffer::correct(Engine& engine, uint64_t tick, const InputFrame& frame, std::string& error) {
for (InputFrame& f : log_) {
if (f.tick != tick) continue;
f = frame;
f.tick = tick;
return rewind_and_resimulate(engine, tick, error);
}
error = "no recorded input for that tick";
return false;
}
} // namespace unify