Set up basic deterministic lockstep
This commit is contained in:
1 parent
28c6e83eda
commit
23fef6f349
26 files changed
+1172
-239
No files matched your search
@@ -1,15 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include "../external/nlohmann/json.hpp"
|
||||
#include <Eigen/Dense>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace FRG {
|
||||
|
||||
inline constexpr int kGameProtocolVersion = 1;
|
||||
inline constexpr int kGameProtocolVersion = 2;
|
||||
inline constexpr std::int64_t kSimulationTickMs = 100;
|
||||
inline constexpr std::uint32_t kDefaultInputDelayTicks = 2;
|
||||
|
||||
std::string makeStateMessage(const nlohmann::json& state);
|
||||
bool parseStateMessage(
|
||||
const std::string& message, nlohmann::json& state,
|
||||
std::string& error);
|
||||
struct InitialStateMessage {
|
||||
nlohmann::json state;
|
||||
std::string assignedPlayerId;
|
||||
std::uint64_t snapshotTick = 0;
|
||||
std::int64_t tickMs = kSimulationTickMs;
|
||||
std::uint32_t inputDelayTicks = kDefaultInputDelayTicks;
|
||||
std::string compatibilityFingerprint;
|
||||
};
|
||||
|
||||
struct DestinationInputMessage {
|
||||
std::uint64_t clientSequence = 0;
|
||||
Eigen::Vector3f target = Eigen::Vector3f::Zero();
|
||||
};
|
||||
|
||||
struct ScheduledDestinationCommand {
|
||||
std::uint64_t commandSequence = 0;
|
||||
std::string playerId;
|
||||
Eigen::Vector3f target = Eigen::Vector3f::Zero();
|
||||
};
|
||||
|
||||
struct TickMessage {
|
||||
std::uint64_t tickId = 0;
|
||||
std::vector<ScheduledDestinationCommand> commands;
|
||||
std::string stateHash;
|
||||
};
|
||||
|
||||
class LockstepTimeline {
|
||||
public:
|
||||
explicit LockstepTimeline(
|
||||
std::uint32_t inputDelayTicks = kDefaultInputDelayTicks)
|
||||
: inputDelayTicks_(inputDelayTicks) {}
|
||||
|
||||
std::uint64_t currentTick() const { return currentTick_; }
|
||||
std::uint64_t schedule(
|
||||
const std::string& playerId, const Eigen::Vector3f& target);
|
||||
TickMessage advance();
|
||||
|
||||
private:
|
||||
std::uint32_t inputDelayTicks_;
|
||||
std::uint64_t currentTick_ = 0;
|
||||
std::uint64_t nextCommandSequence_ = 1;
|
||||
std::map<std::uint64_t, std::vector<ScheduledDestinationCommand>> pending_;
|
||||
};
|
||||
|
||||
std::string makeInitialStateMessage(const InitialStateMessage& message);
|
||||
bool parseInitialStateMessage(
|
||||
const std::string& text, InitialStateMessage& message, std::string& error);
|
||||
std::string makeDestinationInputMessage(const DestinationInputMessage& message);
|
||||
bool parseDestinationInputMessage(
|
||||
const std::string& text, DestinationInputMessage& message, std::string& error);
|
||||
std::string makeTickMessage(const TickMessage& message);
|
||||
bool parseTickMessage(
|
||||
const std::string& text, TickMessage& message, std::string& error);
|
||||
std::string makeErrorMessage(const std::string& code, const std::string& detail);
|
||||
bool parseErrorMessage(
|
||||
const std::string& text, std::string& code, std::string& detail);
|
||||
|
||||
// Stable for the same executable/content build. Persistence-only wall-clock
|
||||
// fields are removed before hashing.
|
||||
std::string canonicalStateHash(nlohmann::json state);
|
||||
|
||||
} // namespace FRG
|
||||
Reference in new issue
Block a user