Handling saves in multiplayer games requires careful consideration of authority and synchronization. Here's how it's typically managed:
First, establish which instance of the game has authority over each object:
class GameObject {
int OwnerId; // Player with authority
Vector2 Position;
bool IsDirty; // Track if object needs saving
public:
bool HasAuthority(int PlayerId) const {
return PlayerId == OwnerId;
}
void UpdatePosition(const Vector2& NewPos,
int RequestingPlayer) {
if (HasAuthority(RequestingPlayer)) {
Position = NewPos;
IsDirty = true;
BroadcastUpdate(); // Tell other players
}
}
};
When multiple players can modify an object, implement conflict resolution:
struct Modification {
int PlayerId;
int ObjectId;
// Use server time for consistency
int Timestamp;
Vector2 NewPosition;
};
class ConflictResolver {
public:
void HandleModification(
const Modification& Mod
) {
auto& Object = GetObject(Mod.ObjectId);
if (Mod.Timestamp > Object.LastModified) {
// Accept newer modification
Object.Position = Mod.NewPosition;
Object.LastModified = Mod.Timestamp;
}
}
};
In most cases, the authoritative server handles saving:
class GameServer {
std::unordered_map<int, GameObject> Objects;
void SaveGameState() {
GameState State;
for (const auto& [Id, Object] : Objects) {
if (Object.IsDirty) {
State.ModifiedObjects.push_back(Object);
}
}
if (!State.ModifiedObjects.empty()) {
WriteToDatabase(State);
}
}
};
This approach ensures consistency and prevents cheating, while maintaining responsive gameplay.
Answers to questions are automatically generated and may not have been reviewed.
Learn techniques for managing game data, including save systems, configuration, and networked multiplayer.