Set up basic deterministic lockstep

This commit is contained in:
Vladislav Khorev committed 2026-11-05 23:02:53 +06:00
1 parent 28c6e83eda
commit 23fef6f349
26 files changed
+1172 -239

No files matched your search

+19 -5
View File
@@ -20,6 +20,10 @@ void RemoteGameServerHost::initializeCampaign(
CampaignRegistry::instance().find(campaignId);
if (!campaign)
throw std::runtime_error("Unknown remote campaign '" + campaignId + "'");
client_.expectCompatibility(
campaign->networkCompatibility.empty()
? "lockstep-v2:" + campaignId
: campaign->networkCompatibility);
client_.replica_.startCampaign(*campaign, zipFile, true, false);
}
@@ -38,6 +42,15 @@ void RemoteGameServerHost::resetCampaign(
bool RemoteGameServerHost::prepareLocation(const LocationConfig& config)
{
auto existing = client_.replica_.state_.locations.find(config.id);
if (existing != client_.replica_.state_.locations.end() &&
existing->second.definition) {
// The location was prepared before initial_state. Loading the
// authoritative snapshot overlays mutable state while retaining this
// definition; preparing it again would reset the assigned player's
// position to LocationConfig::playerPosition.
return false;
}
return client_.replica_.prepareLocation(config);
}
@@ -92,11 +105,12 @@ void RemoteGameServerHost::bindRuntimeLocation(
void RemoteGameServerHost::update(std::int64_t deltaMs)
{
client_.update(deltaMs);
const auto state = client_.snapshot();
if (!state || state->currentLocationId.empty()) return;
auto runtime = runtimeLocations_.find(state->currentLocationId);
if (runtime == runtimeLocations_.end() || !runtime->second) return;
runtime->second->update(deltaMs, LocationSimulationEvents{});
for (auto& completed : client_.takeCompletedSimulationTicks()) {
if (completed.locationId.empty()) continue;
auto runtime = runtimeLocations_.find(completed.locationId);
if (runtime == runtimeLocations_.end() || !runtime->second) continue;
runtime->second->update(kSimulationTickMs, completed.events);
}
}
void RemoteGameServerHost::save(nlohmann::json&)