Skip to content

Maintaining Backward Compatibility for Your Game’s Backend

Why is backward compatibility important? Backward compatibility is essential to ensure your game keeps working long after launch. If you are working on updates or integrations, you’ll run into “breaking changes,” a common discussion topic in game integration. This article will be your technical deep dive into this topic and help you understand what is required to address related issues. 

What Are Breaking Changes?

“Breaking changes” in game services can be classified into two categories.

1. SDK Code Compilation Incompatibility

The category of incompatibility is introduced by a new SDK version having changes that require integrators to update their client code to compile. Example: an updated class name for the request/response payloads.

This is usually caused by continuous code-level improvement and refactoring at the SDK level. The breaking changes are known beforehand, so a proper semantic version could be used to indicate the potentially breaking changes. The impact on game developers involves additional integration work required to upgrade to the latest major version (if new features within the new major version are needed). Sometimes this creates surprises, but they can generally be avoided.

The good news is that the existing older SDK versions will continue to function normally, so games shipped with those versions will be safe and will not need special attention.

2. Remote API Incompatibility

This category of incompatibility is introduced by a new version of backend services, causing different behavior for existing remote API clients (including the old SDK version). 

This second category is generally more problematic and frequently overlooked and needs to be understood by developers. At AccelByte, remote API compatibility is taken very seriously, as it is costly for game developers to patch shipped games

The following rules generally apply to all AGS Services:

  1. Significant version changes are implemented as new endpoints or micro-services so that existing APIs will never break. There are some exceptions to this rule. For example, if security concerns are found in existing APIs, the recommendation is usually to deprecate or change the behavior.
  2. Minor and Patch versions are always backward compatible until that micro-service is officially sunset.

Common Validation Solution

Regression testing is commonly used in our industry to ensure backward compatibility, where currently valid request payloads are tested against the new service version. Regression tests will fail if the request or response fails to achieve backward compatibility (e.g., a previously optional request field is now required, or a required response field is removed in the new version, etc.) 

However, developing regression tests for ALL combinations of request parameters is time-consuming and not cost-effective as running all these test cases takes a long time.

 AccelByte’s Validation Solution

At  AccelByte, we use OpenAPI Spec to define our remote APIs. This gives us an easy way to detect breaking changes by comparing the spec with the last committed version. Here we include in our CI/CD pipeline to compare the latest OpenAPI Spec with the previously committed version in Git. With this approach, most breaking changes can be discovered and stopped from being released.

However, this type of validation tool based on reading schema changes alone, despite being automated and robust in replacing most needs for regression test cases, still needs to be revised and can only partially replace regression. One of the reasons is about optional fields in response payloads.

General Misunderstanding About Optional Fields

Optional fields are not required to be present all the time. In the request payload, the meaning of optional fields is straightforward. The server will accept requests with or without an optional field. When it is absent, that usually means that some default value will kick in.

In the response payload, a response field claimed to be optional means depending on request payloads (combination of request fields and/or values), the response may or may not contain that field. In the context of backward compatibility, it has a deeper implication. Because if backward compatibility needs to be maintained, the response must be consistent.

An identical request sent to a new server version must return a response containing at least all the fields previously returned by the old version. That is because the caller may depend on those fields for proper processing. Having a field in a response payload declaring as optional does not mean that future server versions can take that field away unconditionally if backward compatibility needs to be guaranteed.

Unfortunately, schema-checking tools cannot easily catch this type of compatibility. The best way to support backward compatibility for optional response fields is to keep track of the conditions where those fields are returned and ensure that they will be returned in future versions with the same request using regression testing.

The following table summarizes the allowed changes in request and response payloads for ensuring backward compatibility in a minor version upgrade (assuming the parser ignores unknown fields). 

Table summarizing request and response payloads for ensuring backward compatibility in a minor version upgradeRemote API backward compatibility is crucial to ensure shipped games continue to work after launch. A combination of techniques is used at AccelByte to ensure this promise is fulfilled, and your game continues to succeed long after launch. 

Interested in finding out more? Request a demo.

Find a Backend Solution for Your Game!

Reach out to the AccelByte team to learn more.