Unreal Packages

Tim Sweeney
Epic MegaGames, Inc.
tim@epicgames.com
http://www.epicgames.com/

This document is a trade secret of Epic MegaGames, Inc.

Overview

An Unreal "package" is a collection of related objects such as textures, sound effects, and scripts which are grouped together for convenient distribution and use.

For example, in Unreal, textures are stored in texture package files, which use the ".utx" extension. A .utx file contains many (tens or hundreds) of textures which are part of a similar theme, such as the "SkyCity.utx" texture package.

Unreal's file format is based on packages because packages enable the game engine and content to be developed very modularly. Artists maintain their textures in .utx files; the programmers working on the engine and game maintain separate packages of UnrealScript classes; and so on.

One package might refer to objects which are contained in another package. For example, an .unr level package may refer to textures which reside in various external .utx files; sounds in other .uax files; and music in a .umx file. We say that the level file is "dependent" on the other packages. To load that .unr level file successfully, you need to have all of the other .utx, .uax, and .umx files which that level refers to. If one of those packages is missing, you will not be able to load the .unr file.

Package file extensions

All Unreal package files are stored in the same binary file format, but they use different extensions to identify their type:

When the Unreal engine needs to load a package, it looks in the following subdirectories (off the main Unreal directory) to find matching files:

Which file formats are finalized and which will break before release

The texture (.utx), audio (.uax), and music (.umx) file formats have been finalized. So, it is safe to perform final organization of your textures, sounds, and music. However, we always advise keeping your source files (such as .pcx, .bmp, .wav) handy because taking advantage of future engine improvements, like improved palette quantization, may require reimporting your data.

The level (.unr) and class (.u) file formats are not finalized and will change from time to time prior to release. This is why the .unr binary files can be exported to and imported from the text-based .t3d map file format which is final; and .u files can be imported from the text-based .uc script files.

Why Unreal is based on packages

Descriptions of the standard packages

Core The high-level framework Unreal is built on, similar to the MFC core or the Java Virtual Machine. The Core package contains the definitions of object, class, subsystem, script, property, name, and the object manager. The core is indepenent of any notion of a game or 3d engine.
Engine The Unreal 3d engine, including support for vector math, actors, physics, collision, interaction, cameras, and networking.
Editor The UnrealEd 3d editing environment with geometry editing, realtime lighting, and actor editing support.
Render The Unreal rendering engine implementation.
Window The platform-specific code supporting Unreal.
Galaxy The implementation of Unreal's sound system (UAudioSubsystem) running on top of the Galaxy sound system for Windows. It is possible (for example, when porting Unreal to another platform) to completely replace the Galaxy package with an implementation of another sound system.
GlideDrv Unreal 3d hardware support code for 3dfx's Glide library.
UnrealI The Unreal I game implementation.
WinDrv Windows viewport and client driver.
SoftDrv Software rendering driver.
Fire Fractal fire and water effects.
IpDrv TCP/IP networking driver.

Licensee usage

Licensees may use all packages except UnrealI verbatim or you may modify them to fit your needs. Bear in mind that it is attractive to use them in an unmodified form, as that makes merging with future code updates much easier and makes it easy to isolate problems in each others' code.

Licensees may use the UnrealI package as a reference and for internal development use, but the content in UnrealI is specific to our particular game, and it mustn't be used in your final product.

Licensees should create one more more new packages, for example "WheelOfTime" for their game-specific content. Keep in mind that your package and UnrealI can exist side-by-side during your development cycle until you've fully migrated away from the UnrealI specific content.

Packages in Internet play

In Unreal's Internet play, players can travel among servers on the net, downloading levels, textures, sounds, and other data as they explore the world. Unreal's content downloading is very similar to the Web's: On the web, your web browser automatically downloads the .html, .jpg, and .wav files comprising web pages into your browser's "cache" directory. In Unreal, the engine automatically downloads the .unr, .utx, and .uax package files comprising a level into the \Unreal\Cache directory. Thus, packages are the basic unit of caching and file transfer in Unreal's network play.

Programmers: Sample directory layout for the "Engine" package

Here is an example of the directory structure for all the files that are related to the "Engine" package. The other packages follow a similar structure.

Distributable files:

System\Engine.dll The package's C++ DLL file.
System\Engine.u The package's UnrealScript class file.

Developer files:

Engine\Inc\Engine.h Main public header file for the engine package.
Engine\Inc\*.* Various public header files for the engine package, included by Engine.h.
Engine\Src\EnginePrivate.h Private implementation header file.
Engine\Src\EngineClasses.h Scripted classes exported to C++.
Engine\Src\Engine.cpp Generates the package's precompiled header file.
Engine\Src\*.* Various C++ files comprising the engine's code.
Engine\Lib\Engine.lib The export library for linking with the engine.
Engine\Classes\*.uc The UnrealScript classes used in building Engine.u.
Engine\Graphics\*.* Graphics files used in building Engine.u.
Engine\Models\*.* Model files used in building Engine.u.
Engine\Sounds\*.* Sound files used in building Engine.u.

Programmers: Associating packages and DLL's

When you declare an UnrealScript class as "intrinsic", the engine looks in the .DLL file corresponding to the class's package for the class's corresponding C++ code. For example, here is the declaration of the "PlayerPawn" class in the "Engine" package:

//=============================================
// PlayerPawn.
//=============================================
class PlayerPawn expands Pawn
	intrinsic;

(You can find the above code in the file \Unreal\Engine\Classes\PlayerPawn.uc.)

When you declare a class as "intrinsic" in UnrealScript, you are telling the engine that you have created some corresponding C++ code for the class. In this way, you can mix and match UnrealScript and C++ code when you write your game code.

When you declare "intrinsic" classes, Unreal looks for the .DLL file in the \Unreal\System directory whose name matches your package's name. For example, to find the C++ implementation of the PlayerPawn class, Unreal looks in the "\Unreal\System\Engine.dll" file.

In C++, you must use the IMPLEMENT_INTRINSIC macro (defined in UnObjBas.h) to tell the engine that you have implemented a new class in C++. Internally, this macro generates some __declspec(DLL_EXPORT) declarations that Unreal looks for in your DLL. For example, the PlayerPawn class is exposed in the source file "\Unreal\Engine\UnPawn.cpp" as follows:

IMPLEMENT_CLASS(APlayerPawn);

So, to summarize:

Programmers: Running the game and editor without the UnrealI.u package

You can start working with the "baseline" version of the Unreal engine (that is, the engine with all game-specific content removed), by following these directions.

1. Edit the file "\Unreal\System\Unreal.ini" and find the following text:

[EditPackages]
EditPackage0=Core
EditPackage1=Engine
EditPackage2=Editor
EditPackage3=Render
EditPackage4=Fire
EditPackage5=UnrealI

[DefaultGame]
GameInfo=UnrealI.UnrealGameInfo

[DefaultPlayer]
Name=Player
Class=UnrealI.Female

2. Change it to:

[EditPackages]
EditPackage0=Core
EditPackage1=Engine
EditPackage2=Editor
EditPackage3=Render
EditPackage4=Fire

[DefaultGame]
GameInfo=Engine.GameInfo

[DefaultPlayer]
Name=Player
Class=Engine.PlayerPawn

3. Go to "File/Import" and import the map titled "Baseline.t3d". Go to "Options/Rebuild" and click on the "Rebuild" button.

4. Go to "File/Save" to save your map.

5. Go to "File/Play" to play the baseline map.

While  you're playing with the baseline configuration, you won't be able to see the player model and you won't be able to use any weapons because, of course, all of those things are game-specific and stored in the UnrealI package. But, the point is, you can edit and play levels with only the baseline engine, without any of our game-specific content.

See below for a description of what the Unreal.ini [EditPackages], [DefaultGame], and [DefaultPlayer] settings mean.

Programmers: Replacing UnrealI.u with your own game-specific package

The first question is, "How do I create my own game package like your UnrealI.u?"

The easiest way to create a new package is by creating your first new class within UnrealEd. When creating a new game using the Unreal technology, you will need to create a custom "GameInfo" class to define high-level gameplay rules. Here's how:

  1. Run UnrealEd
  2. Bring up the "Classes" browser on the right-hand side of the screen.
  3. Expand the "Info" class.
  4. Right-click the "GameInfo" class.
  5. Pick the "Create new class below GameInfo..." menu option.
  6. Give the new class a name, for example "KlingonsGameInfo" and a package, for example "Klingons".
  7. Press F7 (or use the Script/Compile menu option) to recompile the new script.
  8. Save your package's .u binary file by hitting the "Save" button in the class browser and selecting your package.
  9. At the bottom of the class browser, hit the "Export" button to export all classes which you have modified. This generates *.uc files in a directory corresponding to your package. For example, if you just created a class named "KlingonsGameInfo" in a package called "Klingons", UnrealEd will generate the file "\Unreal\Klingons\KlingonGameInfo.uc". The .uc files are pure text versions of your scripts, which can later be cleanly rebuilt.

The next question is, "How do I have my new package used in the editor and during gameplay?" The Unreal.ini file defines many of these project-specific settings you will want to modify for your title:

Programmers: Working with classes and packages in UnrealEd

The most important thing you need to realize while working with classes is that each class is stored redundently in two separate places:

There are two ways you can create and edit UnrealScript classes:

To summarize:

Programmers: Cleanly rebuilding your packages from the command line

You can rebuild individual .u files, or all of the .u files, from the command line as follows:

  1. Delete the .u file(s) which you want to rebuild. For example, type "del \Unreal\System\*.u".
  2. Type "Unreal -make" to run Unreal and rebuild the .u files.
  3. Now, Unreal will go through all of the packages listed in the Unreal.ini [EditPackages] section, and rebuild any packages whose .u files are missing.

When Unreal rebuilds a package, it switches into the \Unreal\packagename\Classes directory (for example, if you're rebuilding the Engine package, it switches into \Unreal\Engine\Classes), and it imports all of the *.uc files it finds there.

.uc files are text files containing UnrealScript code. There is one .uc file for each class. The .uc filename must correspond to the class name. For example, the PlayerPawn class must reside in the file "PlayerPawn.uc".

.uc files may contain special UnrealEd commands which begin with the keyword "#exec". These "#exec" commands import various objects as the script is compiled. For example, #exec commands exist to import textures, sounds, meshes, and music. The "#exec" commands are not currently documented; you will need to see the example .uc files in the UnrealI package for examples of usage.

Rebuilding certain packages, such as the Engine package and the UnrealI package, requires that you have the source artwork, sounds, and meshes, which are available on the UnEdit ftp site as a separate download. The source data is not included in the regular source distribution because of its huge size. The source artwork can be extracted with WinZip into the various subdirectories of the Unreal\Engine\ and \Unreal\UnrealI\ directories (for example, the engine sounds go into \Unreal\Engine\Sounds).

When cleanly rebuilding, any UnrealScript compiler errors cause the rebuild to halt, and an appropriate error message is displayed on the screen.

To summarize:

Programmers: Generating C++ header files which mirror your UnrealScript classes

If you create any intrinsic UnrealScript classes, or if you need to access any UnrealScript classes from C++ code, then you can have Unreal generate a C++ header file which mirrors the classes you've defined in UnrealScript.

For example, the Actor class any many of its child classes are defined by scripts in the Engine package (such as \Unreal\Engine\Classes\Actor.uc). The C++ code in the engine often needs to access objects in the Actor class. Early in development, we manually created C++ definitions which mirrored all of the UnrealScript classes. This process became tedious and error-prone as the number of classes increased. So, we added an option to Unreal to automatically generate a C++ header file, based on your UnrealScript definitions.

For an example of an automatically-generated C++ header file, check out "\Unreal\Engine\Inc\EngineClasses.h". This file was not written by a human. Unreal generated it.

To automatically generate a C++ header for a package, do the following:

  1. Delete the package's .u file. For example, type "del \Unreal\System\Engine.u".
  2. Run Unreal with the following parameters: "Unreal -make -h".
  3. Unreal will create a new file for you, called "\Unreal\Engine\Inc\EngineClasses.h".
  4. Now recompile the C++ source code.

Because there are many ways which UnrealScript and C++ can share information back and forth, the automatically-generated header file (for example EngineClasses.h) contains a variety of definitions:

For a more concrete example, carefully examine the UnrealScript file "\Unreal\Engine\Classes\TcpLink.uc" and the following definitions in the file \Unreal\Engine\Inc\EngineClasses.h": enum ETcpLinkState, enum ETcpMode, and class ATcpLink. This provides an example of a fairly isolated UnrealScript class which defines several enumerations and intrinsic functions.

To summarize the important points here:

Finally, to avoid a chicken-and-egg scenario, you should create new classes in the following order: first create a class in UnrealScript, then generate the C++ header, then recompile the engine code (adding in the IMPLEMENT_CLASS macro for any new intrinsic classes you've added).

Programmers: Package related problems to avoid

Programmers: Putting .uc script files under source control with SourceSafe

For programmers who like to keep their work archived under Microsoft Visual SourceSafe, here are some tips. We use SourceSafe internally for our development, though it is purely optional -- nothing in the Unreal source code assumes that you have SourceSafe:

Programmers: Adding/Removing variables in UnrealScript classes can be dangerous

When you add or remove variables in an UnrealScript class, that changes the binary layout of objects belonging to that class. For example, if you have a script that contains some variable declarations like this:

class TestClass expands Actor;

var int i, j;
var texture t;

And you remove one of the variables like this:

class TestClass expands Actor;
var int i;
var texture t;

Then any objects in memory belonging to TestClass will become corrupted as soon as you recompile the script. The solution is to only add or remove variables from a script in an empty level. However, empty levels contain an actor belonging to the LevelInfo class, as well as one or more Camera actors, so it's never safe to add or remove variables from any of the following classes in UnrealEd: Actor, Info, LevelInfo, Camera, PlayerPawn, Pawn. To work with these files, edit their .uc files on-disk, and do a clean rebuild.

Also, bear in mind that Unreal makes heavy use of the Actor, Pawn, PlayerPawn, LevelInfo, and other intrinsic classes in C++ code. So, adding and removing variables to any intrinsic classes will cause the C++ code and UnrealScript code to disagree about the binary layout of classes. Whenever you change an intrinsic class, the safe thing to do is a clean rebuild with the "Unreal -make -h" option to generate new C++ header files for your classes, then recompile the Unreal C++ source.

Programmers: Future issues