begin serversimulation

This commit is contained in:
2025-08-03 18:20:21 +02:00
parent c0a560a16e
commit 731c742346
6 changed files with 58 additions and 25 deletions

View File

@@ -0,0 +1,95 @@
#include <td/simulation/ClientSimulation.h>
#include <chrono>
namespace td {
namespace sim {
const protocol::LockStep ClientSimulation::EMPTY_LOCKSTEP;
std::uint64_t GetTime() {
return static_cast<std::uint64_t>(
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock().now().time_since_epoch()).count());
}
ClientSimulation::ClientSimulation(game::World& a_World, GameHistory&& a_History, std::uint64_t a_StepTime) :
m_StepTime(a_StepTime),
m_World(a_World),
m_CurrentTime(0),
m_LastTime(GetTime()),
m_CurrentStep(0),
m_LastSnapshot(std::make_shared<WorldSnapshot>()),
m_LastValidStep(0) {
m_History.reserve(a_History.size());
for (auto&& lockstep : a_History) {
m_History.emplace_back(std::move(lockstep));
}
Step();
}
ClientSimulation::ClientSimulation(game::World& a_World, std::uint64_t a_StepTime) :
m_StepTime(a_StepTime),
m_World(a_World),
m_History(std::numeric_limits<std::uint16_t>::max()),
m_CurrentTime(0),
m_LastTime(GetTime()),
m_CurrentStep(0),
m_LastSnapshot(std::make_shared<WorldSnapshot>()),
m_LastValidStep(0) {
Step();
}
float ClientSimulation::Update() {
// TODO: handle freezes (m_CurrentTime > 2 * m_StepTime)
m_CurrentTime += GetTime() - m_LastTime;
m_LastTime = GetTime();
if (m_CurrentTime > m_StepTime) {
Step();
m_CurrentTime -= m_StepTime;
}
return (float)m_CurrentTime / (float)m_StepTime;
}
void ClientSimulation::Step() {
const auto& step = m_History[m_CurrentStep];
if (step.has_value()) {
m_LastSnapshot = m_World.Tick(step.value(), FpFloat(m_StepTime) / FpFloat(1000));
m_LastValidStep = m_CurrentStep;
} else {
m_World.Tick(EMPTY_LOCKSTEP, FpFloat(m_StepTime) / FpFloat(1000));
}
m_CurrentStep++;
}
void ClientSimulation::Handle(const protocol::packets::LockStepsPacket& a_LockSteps) {
const auto& steps = a_LockSteps->m_LockSteps;
for (std::size_t i = 0; i < LOCKSTEP_BUFFER_SIZE; i++) {
m_History[a_LockSteps->m_FirstFrameNumber + i] = steps[i];
}
FastReplay();
}
void ClientSimulation::Handle(const protocol::packets::PredictCommandPacket& a_Predict) {
}
void ClientSimulation::FastForward(std::size_t a_Count) {
for (std::size_t i = 0; i < a_Count; i++) {
Step();
}
}
void ClientSimulation::FastReplay() {
if (m_LastValidStep >= m_CurrentStep)
return;
m_World.ResetSnapshots(m_LastSnapshot, m_LastSnapshot);
const std::size_t stepCount = m_CurrentStep - m_LastValidStep;
m_CurrentStep = m_LastValidStep;
FastForward(stepCount);
}
} // namespace sim
} // namespace td