feat: fast forward

This commit is contained in:
2025-07-30 17:52:54 +02:00
parent 56a43d7a60
commit 2e556e0d45
12 changed files with 164 additions and 31 deletions

View File

@@ -5,7 +5,9 @@ namespace sim {
CommandApply::CommandApply(const game::World& a_World, WorldSnapshot& a_Snapshot) : m_World(a_World), m_Snapshot(a_Snapshot) {}
void CommandApply::Handle(const protocol::commands::EndCommand& a_End) {}
void CommandApply::Handle(const protocol::commands::EndCommand& a_End) {
(void) m_World;
}
void CommandApply::Handle(const protocol::commands::PlaceTowerCommand& a_PlaceTower) {
static game::TowerFactory factory;

View File

@@ -33,7 +33,7 @@ void GameHistory::FromPacket(td::protocol::pdata::LockSteps&& a_Steps) {
}
td::protocol::packets::LockStepsPacket GameHistory::ToPacket(HistorySizeType a_StartIndex) {
Array<protocol::LockStep, LOCKSTEP_BUFFER_SIZE> steps;
std::array<protocol::LockStep, LOCKSTEP_BUFFER_SIZE> steps;
for (int i = 0; i < LOCKSTEP_BUFFER_SIZE; i++) {
steps[i] = GetLockStep(a_StartIndex + i);
}

View File

@@ -5,18 +5,37 @@
namespace td {
namespace sim {
const protocol::LockStep RealTimeSimulation::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());
}
RealTimeSimulation::RealTimeSimulation(game::World& a_World, GameHistory&& a_History, std::uint64_t a_StepTime) :
RealTimeSimulation::RealTimeSimulation(game::World& a_World, const GameHistory& a_History, std::uint64_t a_StepTime) :
m_StepTime(a_StepTime),
m_World(a_World),
m_History(std::move(a_History)),
m_CurrentTime(0),
m_LastTime(GetTime()),
m_CurrentStep(0) {
m_CurrentStep(0),
m_LastSnapshot(std::make_shared<WorldSnapshot>()),
m_LastValidStep(0) {
m_History.reserve(a_History.size());
for (const auto& lockstep : a_History) {
m_History.emplace_back(lockstep);
}
Step();
}
RealTimeSimulation::RealTimeSimulation(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();
}
@@ -28,13 +47,47 @@ float RealTimeSimulation::Update() {
Step();
m_CurrentTime -= m_StepTime;
}
return (float) m_CurrentTime / (float) m_StepTime;
return (float)m_CurrentTime / (float)m_StepTime;
}
void RealTimeSimulation::Step() {
m_World.Tick(m_History[m_CurrentStep], FpFloat(m_StepTime) / FpFloat(1000));
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 RealTimeSimulation::HandlePacket(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 RealTimeSimulation::HandlePacket(const protocol::packets::PredictCommandPacket& a_Predict) {}
void RealTimeSimulation::FastForward(std::size_t a_Count) {
for (std::size_t i = 0; i < a_Count; i++) {
Step();
}
}
void RealTimeSimulation::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