Better handling of FFlags in PlayerModule

The PlayerModule contains a lot of conditional logic based on the values of FFlags. This makes maintaining a forked version of the PlayerModule difficult, as FFlags seem to be removed entirely from the engine when they stop being used by the main version of the PlayerModule.

These FFlags occasionally have significant effects on the game - most noticeable when the forked PlayerModule has been modified to make use of a particular feature.

For example, I made modifications to the “VRBlur” part that relied on the “UserFlagEnableVRUpdate2” FFlag being enabled up until a recent PlayerModule update. When this FFlag was removed that part of my game stopped working correctly and I was forced to go and fix it.

But even if we don’t make changes to the PlayerModule itself, some game systems can end up being programmed making certain assumptions about the behaviour of the PlayerModule, and flag changes can affect this. (Although note that in my experience these assumptions are usually not game-breaking, and instead are about smaller details for polishing the game.)

Based on this, my opinion is that forking the PlayerModule should also freeze the value of the FFlags. Or at least it should be really easy to get a version of the PlayerModule that won’t have the rug pulled out from under its feet with future updates to the engine.

My own solution to this problem, and perhaps one that can be adapted officially, is making all the FFlag values defined as constant values in a module. For example:

local FFlags = {
   UserFlagEnableVRUpdate2 = false;
   UserHideControlsWhenMenuOpen = true;

-- (Optional) Logic to check the live version of these flags
-- and notify the developer if any of them have changed.

return FFlags

Then I modify the PlayerModule’s code so that whenever it wants to check a flag it indexes this module with the flag name. This solution prevents unwanted changes to the PlayerModule’s behaviour while still maintaining a simple method for the developer to turn flags on/off.

This solution can also be modified in a straightforward way to let the developer toggle between using the constant or the live flags (e.g. using a bool variable - the live flag values could be used by default, but if a developer wanted all the flags to be frozen they could flip the variable.)