Download

Attention: Platform Changes Ahead!

Platform Extensions (and how they may impact you)

Background

Unreal has a rich history of multi-platform support. We have had various methods of separating out the platform code from the rest of the engine but even our latest method of platform separation is not “trivial” to keep platform code nicely segregated:
[ul]
[li]Perforce permissions are incredibly complex[/li][li]There are references (not API calls) to every platform hardcoded in the engine[/li][li]Adding a new platform touches many parts of the engine[/li][li]Protecting an unreleased platform from disclosure is complicated[/li][/ul]
To this end, we are introducing Platform Extensions. A Platform Extension is similar to a plugin that can be “dropped in” next to the Engine to create a new platform. This means that we can avoid platform references in the Engine code, Epic samples, project files, shaders… you get the idea.

Most existing platforms will not be be converted to a Platform Extension. In the future, we plan to have a Stadia Platform Extension, and we are considering possibly converting Xbox and PS4 as well. Win32/64, iOS, Linux etc will remain integrated as they are today, albeit with some notable changes (below).

Who is affected?

In order to enable Platform files to be discoverable across multiple locations, big changes have been made to UBT. Implementing Platform Extensions has also required changes in general engine code. The following is a list of developers who are very likely to be impacted:
[ul]
[li]Developers who modify Engine code[/li][li]Platform developers (any platform)[/li][li]Developers who author/modify their project’s Build.cs and Target.cs files[/li][li]Developers modifying ini hierarchy[/li][li]Developers using the platform tables in PlatformInfo.cpp[/li][li]Rendering programmers[/li][/ul]

When does this change take place?

These changes are checked into //UE4/Dev-Build/ and have merged to //UE4/Main/ main as of CL 6631504.
The first release branch these changes are expected to land in will be 4.23.

Note:

*This article covers fundamental changes to how platform files are handled throughout UE4’s codebase. Occurrences of **[Platform] *herein should be treated as an appropriate platform name (ie ‘Android’, ‘PS4’ or 'Windows’). For example, the [FONT=courier new]Platforms/[Platform]/ folder mentioned below would be [FONT=courier new]Platforms/PS4/ for the PS4 platform.

New directory structure

The most important part of the change is how the directories are laid out. The platform extensions live in[FONT=courier new] [UE4Root]/Platforms/[Platform]/… This makes provisioning Perforce permissions much easier, keeps all restricted platform code in one place and generally is much more tidy.

A project can also have[FONT=courier new] [ProjectRoot]/Platforms/… , but it is optional. You may leave platform specific code and other files in their original location, but Epic projects will have their files in the new structure. (If you are distributing your project, you may want to refactor the files to keep NDAd platforms separated).

The old directory structure, whereby platform files are distributed all throughout the codebase according to the feature they implement, will remain mostly intact, except for the changes mentioned below.

Sample Platform Extension

For a very basic example of a Platform Extension, we have created a sample platform named ‘XXX’ located in the [FONT=courier new]/Platforms/XXX/ directory which shows how this new approach works in practice.

Rules for Platform Extensions

Given these changes, the following assertions apply to all Platform Extensions:
All files for the Platform must live inside [FONT=courier new][Engine|Project]/Platforms/[Platform]/ , including Developer modules, .Build.cs subclasses, Plugins, .inis, etc.

  • [FONT=courier new]PLATFORM_[Platform] is not defined for Engine modules!
  • A module must set [FONT=courier new]bAllowConfidentialPlatformDefines to true in order to have it set
  • Any [FONT=courier new]ShaderPlatforms are defined in DataDrivenPlatformInfo.ini
  • [FONT=courier new]PlatformInfo objects are defined in DataDrivenPlatformInfo.ini
  • The [FONT=courier new]UnrealTargetPlatform for the platform is not referenced from outside the platform-specific .cs files

Workflow Impact

UnrealBuildTool

**Impacted Audience: **Anyone working in Build.cs and Target.cs files

Description:

UnrealTargetPlatform was previously an enum with all platforms listed. To remove the hardcoded platform names, UnrealTargetPlatform has been changed to a class with static members named the same as the enum values. Additionally, it is a partial class, so a Platform Extension can extend the class to add a member with the platform’s name.

In general, it should act the same as enum (you can compare them, assign them, etc). However, since they are static members, they are not a constant value, so they cannot be used in a switch statement. All existing uses in the engine have been converted to if statements instead. In addition, the SupportedPlatforms attribute on a Target subclass now uses strings that match the platform name instead of the UnrealTargetPlatform.

This is likely to be the single biggest impact on you as a developer, unless you have also made engine/platform code changes.

HAL Header Filename Standardization

Impacted Audience: All Platform programmers (additional notes for Windows, TVOS, PS4, XboxOne, and Android developers)

Description:

Platform references have been removed from the Hardware Abstraction Layer (HAL) “uber” headers, such as PlatformTime.h (used below as an example). [FONT=courier new]Platform-specific versions of these header files are now referenced in the following manner:

[FONT=courier new]#include COMPILED_PLATFORM_HEADER(PlatformTime.h)

The [FONT=courier new]COMPILED_PLATFORM_HEADER macro expands to add the current being compiled as a prefix. As such, all platform header file names must be standardized to the form [FONT=courier new][Platform]PlatformTime.h

PS4, XboxOne, and Android:

Historically these platforms did not have the word “Platform” in their header file names (e.g. PS4Time.h), which was in contrast with other platforms. These headers and source files have been renamed in order to make them consistent with other platforms (e.g. PS4Time.h is now PS4PlatformTime.h).

Platforms which are not converted to Platform Extensions will still have these files renamed, so developers that have made changes to affected platform files will need to make sure to move their changes over.

Win32, Win64 and TVOS:

Since Win32 and Win64 each share common headers, and since TVOS uses the IOS headers, we have added a mechanism to override the platform name that results when expanding the [FONT=courier new]COMPILED_PLATFORM_HEADER macro. The override is declared in [FONT=courier new]UEBuild[Platform].cs in the [FONT=courier new]SetupEnvironment method by adding a new [FONT=courier new]CompileEnvironment definition with:

[FONT=courier new]CompileEnvironment.Definitions.Add("OVERRIDE_PLATFORM_HEADER_NAME=[SharedPlatform]”);

Examples:
[ul]
[li]Win32 and Win64 override to “Windows”, so they would share “WindowsPlatformTime.h”[/li][li]TVOS overrides to “IOS”, so it would use “IOSPlatformTime.h”[/li][/ul]

Log categories for Platforms

Impacted Audience: Anyone writing engine code

Description:

Platform log statements like [FONT=courier new]UE_LOG(LogWindows, …) have used hardcoded Log categories, which were globally defined for all platforms. Now, the category is generated based on a define that is only set on that platform. This means that if you use [FONT=courier new]UE_LOG(LogWindows, …) on any other platform than Windows, it will no longer compile. This should be an easy fix

Ini File Specification

Impacted Audience: Anyone who has added or will add new .ini files into the ini hierarchy.

Description:

We have simplified the ability to search for .ini files in deep directory structures. The current implementation used a rigid list of files, which has now been replaced with a more programmatic solution we call “Ini Layers”. This concept breaks up the ini stack into discrete layers which can each be expanded according to various factors. Consider the following ini stack, which we can describe as having 5 layers: [ol]
[li]Engine/BaseEngine.ini[/li][li]Engine/Base[Platform]Engine.ini[/li][li]Project/DefaultEngine.ini[/li][li]Engine/[Platform]Engine.ini[/li][li]Project/[Platform]Engine.ini[/li][/ol] The** Ini Layer** feature enables us to expand each layer of the ini stack into multiple ini files according to the permutations appropriate for that layer.

For instance, Epic uses NotForLicensees and NoRedist as directories to segregate certain confidential/secret settings into directories with reduced distribution, which increases the permutations for each of these layers.

Additionally, this new feature expands upon our existing support for Ini Platform Parents, which now allow for a chain of parents, rather than just a single platform parent.

For example, suppose you have three platforms, A, B and C which are related in a chain; Grandparent A, Parent B and Child C. Ini settings for platform A (the grandparent) should be inherited by both A and B. Likewise, platform B settings should be inherited by platform C.

Previously, we did not have a way to specify platform A, and interlacing the appropriate ini files to cause C to inherit B’s settings was a challenge. Using Ini Layers, this full chain is now possible and would result in an ini stack for platform C as follows: [ol]
[li]Engine/BaseEngine.ini[/li][li]Engine/Base[…]Engine.ini[LIST=1][/li][li]Engine/Base[A]Engine.ini[/li][li]Engine/Base**Engine.ini[/li][li]Engine/Base[C]Engine.ini[/li][/ol]
[li]Project/DefaultEngine.ini[/li][li]Engine/[…]Engine.ini[ol][/li][li]Engine/[A]Engine.ini[/li][li]Engine/**Engine.ini[/li][li]Engine/[C]Engine.ini[/li][/ol]
[li]Project/[…]Engine.ini[ol][/li][li]Project/[A]Engine.ini[/li][li]Project/**Engine.ini[/li][li]Project/[C]Engine.ini[/li][/ol]
[/LIST] The specification of these Layers (GConfigLayers) and Expansions (GConfigLayerExpansions) is in ConfigCacheIni.cpp. See also EnumerateConfigFileLocations which defined in ConfigHierarchy.cs.

Two layers from the GConfigLayers definition are shown below. These definitions use bracketed tokens which are expanded to valid permutations when generating the ini file names.



// Project/Default*.ini
{ TEXT("ProjectDefault"), TEXT("{PROJECT}{ED}{EF}Default{TYPE}.ini"), TEXT(""), Flag_AllowCommandLineOverride | Flag_GenerateCacheKey },

// Project/Platform/Platform*.ini
{ TEXT("ProjectPlatform"), TEXT("{PROJECT}{ED}{PLATFORM}/{EF}{PLATFORM}{TYPE}.ini"), TEXT("{EXTPROJECT}/{ED}{EF}{PLATFORM}{TYPE}.ini") },


Valid tokens are as follows:
[ul]
[li][FONT=courier new]{PROJECT}[/li][LIST]
[li]The project directory[/li][li]Has no permutations[/li][li]Token ends in a ‘/’[/li][/ul]
[li][FONT=courier new]{ENGINE}[/li][ul]
[li]The engine directory[/li][li]Has no permutations[/li][li]Token ends in a ‘/’[/li][/ul]
[li][FONT=courier new]{TYPE}[/li][ul]
[li]The type of ini file it is[/li][li]Expands for each ini type; Game, Input, Engine, Editor, etc[/li][/ul]
[li][FONT=courier new]{ED}[/li][ul]
[li]The DirectoryPrefixs defined in GConfigLayerExpansions[/li][li]NotForLicensees, NoRedist, etc[/li][li]Expands for each DirectoryPrefix in GConfigLayerExpansions[/li][li]Token ends in a ‘/’[/li][/ul]
[li][FONT=courier new]{EF}[/li][ul]
[li]The FilePrefixs defined in GConfigLayerExpansions[/li][li]DedicatedServer, etc[/li][li]Expands for each FilePrefix specified in GConfigLayerExpansions[/li][/ul]
[li][FONT=courier new]{PLATFORM}[/li][ul]
[li]The current platform and any parent platform(s) in the IniParentChain[/li][li]Expands once for each platform in the chain[/li][/ul]
[/LIST] Note that your existing .ini files will still work. This only changes the way the hierarchy is specified, enabling more files to be easily added, and adds the PlatformExtension location to the search.

PlatformInfo structure

Impacted Audience: Anyone modifying the large table in PlatformInfo.cpp

Description:

We currently specify information about every platform in PlatformInfo.cpp. This naturally needed to change to remove platform information from the engine. The settings are now discovered by looking for DataDrivenPlatformInfo.ini files in each platform’s [FONT=courier new]Engine/Config/ directory.

Currently, the DataDrivenPlatformInfo.ini files are not project-extendable, as they are meant to simply describe a platform. However, in the future this may change.

ShaderPlatforms

Impacted Audience: Rendering programmers

Description:

A [FONT=courier new]ShaderPlatform is used to define characteristics of rendering capabilities of a rendering API on a platform. The information about these ShaderPlatforms have always been hard-coded in C++, which need to be removed.

A ShaderPlatform can now be specified in a DataDrivenPlatformInfo.ini via the [FONT=courier new]FDataDrivenShaderPlatformInfo class. This class will have more settings added to it as the rendering code adds more capabilities to check.

Currently, the existing ShaderPlatforms have not been converted to .ini-driven, so only about half of the functions named things like [FONT=courier new]RHISupportsXxxxxx make use of the new system. This is a work in progress.

From the 4.23 release notes page

this mean that HTML5 will not be supported by Epic from now and upcomming releases ?

The platform extension link there is bad. Where can we read more about it? Wait it’s this page…?

I want to believe that EPIC one day reduces Launcher version size too so download is smaller and more optimal. Currently deselecting unneeded platforms/source in launcher still keeps so much platforms stuff. There should be possible to download only chosen platform support and even possible to get “blueprint only UE” that has no headers, pdb, help, python, .lib included.

iwtb.jpg

That would be so great !

Are these changes live in 4.23? I can’t find a Platforms folder in either UE4 or Project root (I’m currently porting the game on Nintendo Switch, so the platform add-on is installed).

I still don’t get how I can export my UE4 project in HTML now.

Basically, you don’t. Stay on the version you have now for that project.

Do we have an updated estimate for when this change will be complete? As of 4.24.1, running UAT BuildGraph to build the engine for internal team distribution with platform support (PS4 in our case) in the same way as worked perfectly in 4.22 no longer works; the engine builds successfully, but platform support isn’t working (example).

The platform files are in there, just incomplete and in the wrong place.

HTML support is ALMOST the only reason I chose to get started in Unreal Engine. Imagine the possibilities… what a bummer. Are there any updates on the questions previously posted?

The HTML5 Platform now lives at GitHub - UnrealEngineHTML5/Documentation as documented (in cyan-on-brown for some reason…) on Developing HTML5 Projects | Unreal Engine Documentation