Conflict resolution
The five built-in policies, why the losing copy is preserved first, and how a game supplies its own rules.
What a conflict is#
- Both sides changed since their common ancestor, or
- the remote version has diverged from the generation this device last saw.
A conflict is not an error. It is a decision the game has opinions about, so the framework makes it explicit.
The five policies#
| Policy | Behaviour |
|---|---|
KeepNewest (default) | The higher generation/revision wins. Deterministic and explainable. |
KeepLocal / KeepRemote | The named side wins. For games with an explicit rule. |
KeepBoth | Both are preserved; neither is destroyed. |
Manual | Nothing is written; the conflict is reported for the game to resolve. |
Configured in Configuration → Cloud → ConflictPolicy.
The losing copy is written first#
With PreserveConflictCopies on (the default), the losing copy goes to its own *_conflict_<rev> slot through the same verified AdoptAsync path as any other transfer, so the copy is confirmed on disk before the winner replaces anything.
That is the difference between resolving a conflict and making one worse: an automatic decision becomes reversible, and the player can be offered the other version later.
Supplying your own rules#
public sealed class MyResolver : ICloudConflictResolver
{
public CloudConflictResolution Resolve(CloudConflict conflict)
{
class="tok-com"> // If local has the higher playtime line, keep it; otherwise keep both and let the player choose.
return CloudConflictResolution.KeepBoth(class="tok-str">"Resolved by playtime at the title screen.");
}
}BuiltInCloudConflictResolvers exposes the five policies as objects, so a game can compose built-in behaviour rather than reimplement it.
What was verified#
Conflict behaviour is verified against FakeCloudTransport and HTTP-shaped doubles, including refused preconditions, throttling and corrupt payloads. No real third-party service was reachable in this environment, so no real provider has been exercised. Not verified
Next#
- Synchronisation — the call that surfaces a conflict.
- Offline-first — conflicts that arrive from a queued upload.
- Adapter roadmap — providers that do not exist yet.
Something wrong on this page? Every page here describes behaviour that is checked in the repository. If a page and the package disagree, the package wins.
Report a documentation problem · Frequently asked questions · Troubleshooting