The RuntimeTests plugin defines a gameplay tag TickTestMessageTag (EngineRuntimeTests.cpp line 437) that, due to the `#if WITH_AUTOMATION_WORKER` macro on line 127, is only included in non-shipping build configurations. This means that client and server builds with different build configurations will have a different number of gameplay tags defined, which affects the number of gameplay tags in the global `NetworkGameplayTagNodeIndex` array and thus causes replicated gameplay tags to potentially resolve to incorrect values when the client and server are not using the same build configuration. Specifically, reproduction of this issue occurs when gameplay tags that are registered after TickTestMessageTag are replicated between a shipping client build and development server build (or vice versa).
Is this a known issue? Further, should we assume that dev/shipping clients and servers are intended to be intercompatible at the engine level for a given changelist, or is that not necessarily true? During development we generally run development server builds with a mix of dev/shipping clients depending on whether we need to use cheats during playtesting, so compatibility across build configurations is something we have been relying on.
Thanks!
Alex
Steps to Reproduce
- Enable the RuntimeTests plugin
- In gameplay code, create a new gameplay tag
- It appears that the global gameplay tag table is sorted alphabetically, so this tag should come after “AsyncMessages.Internal.test.TickEvent” alphabetically
- Make a replicated property that replicates this tag between the client and server
- Build a shipping server and development client (or vice versa)
- Connect the client to the server and observe that the replicated tag value is incorrect
Attached to this ticket are the header/source files of an example component that replicates this functionality.
Hello Alex,
I would say it is unclear if Shipping and Development cooked clients/servers should be compatible. They are definitely not compatible for our internal Epic games due to anticheat so we do not normally test this setup. As you mention it will work most of the time, but you could have other issues with automated tests and cheats that are stripped out of only one executable. We recently added support for putting UClasses inside WITH_TESTS, and as people start to use that more it could cause other issues like this.
In this particular case it should be possible to fix the issue by moving TickTestMessageTag to the top of the source file outside the WITH_AUTOMATION_WORKER checks, did you try that? I tried that on Lyra but something still seems to be breaking compatibility as the controls are broken on a shipping client.
Also, if you are trying to use this kind of diverse setup you may want to try out the new dynamic tag replication feature added to 5.6 (although, it appears to be missing from the release notes for some reason). If you enable this in the Gameplay Tags Settings, clients and servers are allowed to have different tags. It does mean tags are a bit slower to replicate though
Thanks for the reply, Ben. We’ve disabled the plugin for the time being but I’ll go ahead and move the tag declaration out of the WITH_AUTOMATION_WORKER macro to try and fix the issue.
I saw the dynamic replication feature when debugging this, I’ll consider using it in the future though it is nice to have the speedier replication and, at least in our case, we don’t have any hard constraints against mixing dev/shipping clients and servers so I think we’ll stick to this as long as we can.
Thanks!
Alex
If you have a solution that works for you, then we can consider this resolved. Removing any test plugins is a good idea if you are trying to keep compatibility. One thing we do with internal games is have certain plugins enabled on the main development branch and then disabled on release branches.
I couldn’t figure out why Lyra Dev/Shipping were incompatible (as you realized it is very hard to debug Shipping issues). If you have any follow up questions let me know!
This solution works, you can consider this resolved. Thanks for the help!