Unreal Engine 4--How version compatibility works and some things that can be optimized

Source: Internet
Author: User
Tags comments data structures visibility

This blog explains how version recognition, switching works, and some optimizations are introduced in UE4.

This blog is translated from Robert Throughton's Ue4:package Versioning ... How It Works ... and an optimization, portal.

The translation of this blog has been approved by the original author.

This post was translated from 中文版. You can find the original 中文版 language version here:http://coconutlizard.co.uk/blog/ue4/ue4-package-versioning Version iterations of the UE4

Unreal engine has a good performance in ensuring that the editor and cooked content can be common across several different engine versions. And to make it easy for programmers to change data structures between these different versions, Unreal engine also provides some mechanisms. This blog will analyze the relevant content between versions through Getlinkerue4version () and its associated functions.

First, we need to understand the different versions of the engine: Ue4version: This number increases whenever epic makes some changes on top of the original code.
This version number can only be changed by epic. Ue4licenseeversion: This number will also increase when the code changes. But this is a "safe" version number, which means that you (the developer) can make code changes on top of that.
This number can be changed by the developer (licensees). Customversion: This version number can be used to iterate between different engineers without causing conflicts. How to use version iterations of UE4

Generally speaking, we usually use the getlinkerue4version () function and getlinkerlicenseeue4version () to handle problems between different versions.

Next I'll give an example of epic using the Getlinkerue4version () function to fix some of the content:

During this time, someone added a blueprint variable to set the visibility. But the pain is that they made a mistake and lost the third ' I ' in a visibility.

Later, someone discovered the problem, so they added the following function to the Uwidgetblueprint::P ostload () function to fix the error:

    if (Getlinkerue4version () < ver_ue4_rename_widget_visibility)
    {
        static const FName visiblity (TEXT (" Visiblity "));
        static const FName Visibility (TEXT ("Visibility"));

        for (fdelegateeditorbinding& binding:bindings)
        {
            if (binding.propertyname = = visiblity)
            {
                Bindi Ng. propertyname = Visibility;}}
    }

They then added a macro to the ObjectVersion.h header file for this change:

    Rename visiblity on widgets to Visibility
    ver_ue4_rename_widget_visibility,

Therefore, the entire workflow is as follows: When an older version of a misspelled package is loaded, the package will have a smaller version number than ver_ue4_rename_widget_visibility. At this point, the code above will be activated to correct the spelling errors. If the package is saved, it will use the correct spelling and set the version number to the latest version number.

This practice is used in many places, such as adding/removing some new variables in the class. Add some patches that we want to change. version number corresponds to a macro

In the header file ObjectVersion.h, we document how epic handles version iterations, first eunrealengineobjectue4version:

Enum eunrealengineobjectue4version
{
    ver_ue4_oldest_loadable_package = 214,

    //Removed restriction on blueprint-exposed variables from being read-only
    ver_ue4_blueprint_vars_not_read_only,
    //Added manually serialized element to Ustaticmesh (precalculated nav collision)
    ver_ue4_static_mesh_store_nav_collision,
    // Changed property name for atmospheric fog
    ver_ue4_atmospheric_fog_decay_name_change,
...

    -----<new versions can be added before this line>-------------------------------------------------
    //- This needs to is the last line (see note below)
    Ver_ue4_automatic_version_plus_one,
    ver_ue4_automatic_version = Ver_ue4_automatic_version_plus_one-1
};

Similarly, there are eunrealengineobjectlicenseeue4version, also in the same header file:

Enum eunrealengineobjectlicenseeue4version
{
    ver_lic_none = 0,//-This needs to is the last line
    (see note b Elow)
    ver_lic_automatic_version_plus_one,
    ver_lic_automatic_version = Ver_lic_automatic_version_plus_one -1
};

Eunrealengineobjectlicenseeue4version like the following: As mentioned above, licensees** can only * * Iterating in the Eunrealengineobjectlicenseeue4version list can only be added at the bottom of the list. When using code management tools such as perforce, it is important to note that this package is easy to play because it is handled after the package is saved. In this case, the simplest solution is to not allow check in when the version number is changed

Why should we only use ue4licenseeversion? Consider the following situation: a project using UE4.11 start we iterate over the ue4version, add some of the features we think are cool, we merge the UE4.12, and we find that we have a conflict--epic also in 4.12 iterations of this piece of functionality ... In this case, we can only:
Inserting Epic's new version number to the end of the list and setting our own iteration version number to the same-that means we can use our own content, but some of the new features epic offers should not be used. Move our version number to the end-but there's a big problem with the functionality you've done previously.

The above problems are likely to be fatal, we have also made such mistakes in UE3, we spent a good time to Re-patch. So I remind you again-just use ue4licenseeversion. when the issue occurs with the version number

In this long development career, I have experienced a lot of crashes due to version number conflict, I hope these questions can give readers some inspiration.

To understand what the problem is, we first need to understand how the version number works. Now if we had a package that used a long time ago version number 256来 for storage, and now the version number is 259. When the package is loaded, it needs to be iterated over 257, 258, and 2,593 versions.

Here are some of the things I've summed up that are most likely to cause a problem with the version number: Merge other iterations, but there's no logic to commit version control. Other programmers of the team have not yet merge other iterative logic.
In the local test, there is no problem. For other developers, they started complaining about the crash.
Other developers have updated the logic of the iteration. In other developers ' versions, this iteration has a different version number. But you've put your iterations at the end of the list and the system is now in disarray. When the package is loaded, the engine thinks your own iterations are loaded (but not actually). You integrate a new version iteration from Epic and added a new macro definition to the version list.
However, in Epic's ObjectVersion.h header file, before you integrate the place, Epic made some new changes. After you have a full integration, add the additional macro definitions added by Epic.
Crashes/bugs began to appear because some patches are now in a disorderly order. It seems that the only "right" way to do this is to add what you integrate after.
But this will still happen, as long as the official content provided by Epic is saved elsewhere, the package may still be problematic. Some of the optimizations we have found

When the content of the project is finished by Cook, the version number of all packages will be set to the maximum in the contents of the saved folder. So I have this idea of optimization.

Even if the game is loading content that has been cooked, the engine will not default it to be up to date. This allows you to change the version number of some packages without having to cook all the things again. However, it is expensive to frequently check whether the content needs to be updated. This is not necessary, especially for shipping packages. So we make some assumptions: the shipping package works only under the cooked content. Only content that is completely cooked to the latest version will be available in the shipping package.

If these assumptions are true, then we can optimize and tell the compiler that we don't need to run the patching code.

That is, we need to tell the compiler to let it have every check for example: if (Getlinkerue4version () < Ver_ ... The same kind of code will fail, and each check for example: if (getlinkerue4version () >= ver_ ... Code like that will succeed. So the simplest way to do this is to have each get-version () type function return the current latest version number.

So we work in the header file to make sure that the compiler can set it inline.

So...... Here's how we do it:

We are at the beginning of the UObjectBaseUtility.h header file:
#define ASSUME_UE4VERSIONS_ARE_LATEST (ue_build_shipping &&! With_editoronly_data)

It is important to note that our setup in the project is that the shipping package can only be run in the run cooked builds and you need to make adjustments for different projects.

Before Getlinkerue4version (), you should add the following code:

#if assume_ue4versions_are_latest
  forceinline int32 getlinkerue4version () const {return ver_latest_engine_ue4;}
  forceinline int32 getlinkerlicenseeue4version () const {return ver_latest_engine_licenseeue4;}
  Forceinline int32 getlinkercustomversion (fguid customversionkey) const  {return max_int32;}
#else//Assume_ue4versions_are_latest
  /**
   * Returns The UE4 version of the linker for this object.

After Getlinkercustomversion (), add the following code:

      Int32 getlinkercustomversion (Fguid customversionkey) const;
    #endif//Assume_ue4versions_are_latest

Now that we're going to rewrite the CPP code for the version control function, we need to start with the ObjectBaseUtility.cpp file and add the following code after the include statement:

    #include "CoreUObjectPrivate.h"
    #if! Assume_ue4versions_are_latest

At the end of the file, add:

#endif//! Assume_ue4versions_are_latest

These are all, and now the compiler should be able to completely remove the patching code, which makes the whole code a lot simpler. other comments (for epic)

I have seen too many licensees will be directly in the eunrealengineobjectue4version to add their own macro definition ... Just try to avoid it. If it was me, I would add a few comments to the following:

     -----<new versions can be added before this line>-------------------------------------------------
     //- This needs to is the last line (see note below)
     Ver_ue4_automatic_version_plus_one,
     ver_ue4_automatic_version = V Er_ue4_automatic_version_plus_one-1
    };

Switch

     Licensees should not ADD CODE here!
     Please use eunrealengineobjectlicenseeue4version instead!
     ADDING CODE here'll make the future integrations hard!
     -----<new versions can be added before this line>-------------------------------------------------
     ver_ Ue4_automatic_version_plus_one,
     ver_ue4_automatic_version = ver_ue4_automatic_version_plus_one-1
    };

In addition, the following code can also be changed to get it from:

    Enum eunrealengineobjectlicenseeue4version
    {
      ver_lic_none = 0,
      //-This needs below)
      Ver_lic_automatic_version_plus_one,
      ver_lic_automatic_version = Ver_lic_automatic_version_plus_ ONE-1
    };

Switch

    Enum eunrealengineobjectlicenseeue4version
    {
      ver_lic_none = 0,
      //-----<new versions can be added before This line>-------------------------------------------------
      ver_lic_automatic_version_plus_one,
      ver_ Lic_automatic_version = Ver_lic_automatic_version_plus_one-1
    };

There's also the ability to try out names like version control that can be renamed from Eunrealengineobjectue4version to Eunrealengineobjectpleasepleaseonlyforepicchangesue4version. 。 Be sure to let the user know the harm of directly changing this piece. I've even seen a very experienced developer who has stumbled here.

< end of the full >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.