Academic Resources for the Unreal Development Environment

From Oldunreal-Wiki
Jump to navigation Jump to search

Basics of Unreal

Unreal Tournament is a FPS multiplayer combat game based on its predecessor, Unreal, which was a single player scenario game. The player's avatar/character is competitor in a gladiator-like competition which takes place in a dismal, Blade Runner style future, where mega-corporations sponsor contained conflict to decrease violence among the populace. As opposed to quests, the thrust of the gameplay is sport-like matches or tasks with human and computer-controlled participants. Good reflexes and coordination are paramount, but strategy also plays a role in gameplay.

You can play a single-player game against Bots (computer controlled opponents) or a multi-player competition between humans and bots over the Internet or a LAN. Once you have configured your avatar by selecting its look and name, you are ready to begin a match. Simply select a new game from the menu and you're off. When you start the game, you will be spawned in a level and immediately have control over your avatar's perspective, movement, and action.

The environment you are in and the rules that govern its behavior and content are found in a map file (xxx.unr). Each map can be considered a world of its own. After you have played for a while, you will start to find you like certain environments and will want to play those maps more.

Each map will have a default game type associated with it. Within UT, there are several different types of games. There is DeathMatch, in which every man is out for himself and everyone you see is your enemy. The goal in this type is to kill, or "frag", as many opponents as possible to increase your ranking. Then, there are team games like Capture The Flag and Team DeathMatch. These are often populated by two teams, red and blue. The object is to cooperate with other players on your team and combat those who oppose. There is also the Assault type game, which should be of special interest to anyone who wants to make a Mod that differs greatly from UT. These types of games have a specific, sometimes complex agenda. The object is to complete some task in as little time as possible. There is the typical combat oriented conflict but one must solve a puzzle of sorts to score highly. The reason that this should be noted by Mod and map builders is because there are special techniques that are often used to make Assault scenarios work and each map can be almost like a different game in itself.

For the sake of simplicity, the composition of UT can be divided into two, almost distinct parts. The first is the engine. If you have not heard this term before, it is basically the low-level software that does things like quick 3D mathematics and network and graphics hardware interface. The idea is that aside from tweaking and special uses for different needs, the engine can be reused and separated from the content, which is the second piece of UT. Though UT comes with its own content out of the box, it is conveniently packaged with tools to help you design your own content without changing the underlying engine, but by simply interfacing with its API.

For those who want to change UT's content, there are three basic options. First, one can make her own maps using the UTEditor, or UTEd, which comes with the UT game itself. This will not change any rules about how the world behaves, it simply takes the pieces of content and building blocks of the vanilla UT, and allows you to build your own environment, placing decorations, landscapes, objects, and characters for others to play. A second way is to use a hook built into Unreal for Mutators. Mutators are variations on UT for things that only slightly change or customize the gameplay of typical UT game types. The third way is to make a Mod (Modification) using the engine's API for content creation and management, UnrealScript. We will focus on the first and third techniques, as Mutators are limited, especially if one wishes to make a completely new game, often called a "full conversion Mod".

Mod Making

Unreal / Unreal Tournament Architecture Overview

    In UnrealTournament, all of the things in the world that you interact with, from Bots to elevators to bodies of water, are represented by hierarchical structured objects. The base class, like Java, is object. From this class, all Objects get the nominal amount of data and behavior for their use in the UnrealTournament environment. Examples are UWindow, UT's windowing system, Bitmap, a reference for externally stored bitmaps, and Time, a reference for the system's clock. These are all Objects that are independent of a map and may interact with UT outside of a given map's environment. Another class that extends Object is Actor. Classes that sublass from Actor are anything that will interact with the virtual world once a map has been initiated and the user becomes immersed in the 3D environment. Not all of these are visible or tangible. GameInfo, for example, defines the specifics of the gametype that will be played (DeathMatch, CTF, etc…). However, Actors are all relevant during execution of running map, so they are given special capabilities that are not present in base Objects, like physics, renderability, and network replication. With the possible exception of UWindow, writing a Mod will be done mostly through interaction with those classes that subclass from Actor. I will briefly introduce some of the more relevant Actors and expound upon them in later documents as they become relevant in certain contexts.
  • Pawns - These are actors that move and behave like living creatures. They have special characteristics like intelligence and the ability to move. You will manipulate the action and AI of NPC's by subclassing from ScriptedPawn or Bot. The former is a generalized class for any sort of NPC that will appear in your game. Examples are animals and the enigmatic Nali. Bots are a branch of pawn with special AI and behavior that is specifically catered to UT. If you want to stray very far from the behavior of the Bots in UT, I suggest using ScriptedPawn. Another important child class of Pawn is PlayerPawn.
  • PlayerPawn - PlayerPawn is responsible for the Player's avatar, or in-world character. The primary difference is between PlayerPawn and other Pawns is the lack of AI specific code and the addition of interface specific code for display and input, as well as the networking differences which are a result of this transformation from AI driven to interface driven behavior. In a full conversion Mod, you will likely spend a lot of time manipulating a subclass of PalyerPawn. This could be anything from keyboard mappings to the way the player's avatar moves. Another thing that is contained in the PlayerPawn class is a reference to the HUD class with which it is associated.
  • HUD - The HUD or "Head's Up Display" is a term that comes from flight simulators for all of the information that is displayed on the panel in front of pilots. The idea is that anything that needs to be displayed for the user's benefit that does not exist in the 3D world can be printed to this translucent panel. Another way to think of it is the in-game windowing system. Note that it is different than the UWindow windowing system, as this used for system control. The HUD is associated with things in the virtual world: ammo, targeting, playermessages, … and the UWindow system is for interfacing with things outside of the virtual world: Changing Video modes, Exiting UT,… You will almost certainly want to make a new HUD for your game, as this decides a lot of the look and feel, not to mention the interface capabilities, of your Mod.
  • Info - This class does exactly what it says, it holds information for various things. Most of the subclasses of Info are for internal use, but there are two which are extremely useful and another two which I could conceive might be used in a full conversion. The two essentials are GameInfo and ZoneInfo. The first is the superclass of all game types, including CTF, Assault, and DeathMatch. This is where the rules of your game, or subgames if you have more than one, will be found. If you decide to do an adventure game, where you pick up treasure or garner experience to win, you will put the rules here. ZoneInfo is a marker to describe the environment of a zone (see UTEd tutorial), like water or lava, etc… You may find this useful for changing the weather or environment of your Mod. The two useful, but complex Info subclasses are InternetInfo and ReplicationInfo. Unless you plan on changing or extending the network architecture of UT, you won't need to mess with these.
  • Inventory - This is the class for items which can be handled, moved, picked-up, etc… in the 3D environment. What makes these different from decorations is that they have special capabilities so that Characters can pick them up. Here you fill find the Weapon subclass as well as PickUp which has things like health and armor. Anything that is a movable object that can be picked up will be subclassed from Inventory. If it cannot, use decoration, its less computationally expensive. Every Inventory object has a pointer to another Inventory object, so more than one can be carried without using an array.

UT Mod Tutorial: New Game Type

This is a tutorial designed to give someone a quick start at making a Mod in UnrealScript. Like other tutorials, we will start by having you manipulate existing UT content and testing it out. Unlike other tutorials, however, we will start you off with the intent of you finishing with a completely new game. A knowledge of OO programming is assumed and some Java is helpful.

       Orange Text - refers to something interface specific, e.g.- Menu->File->New
       Green Text - refers to something system specific like files or paths, e.g.- C:\WINNT\
       Code Text - refers to something you will find in a file, e.g. - class Thesbian expands Actor { }

   What You Need
   Extracting Source Code With UTEd
   Creating a Package
   Editing UnrealScript code - 1: Configuring UT for your game
       Configuring WotGreal
       Configuring UnrealTournament.ini
   Editing UnrealScript code - 2: Creating Your New Game Type
       Subclassing From an Existing Game Type
       Customizing Your New Game Type Through DefaultProperties
       Configuring Your Game Type With
   Compiling Your New Game Type
   Testing Your New Game Type

What You Need

A copy of Unreal Tournament (If you want to work outside the lab)

   Make sure to include components like UTEd and when installing
   Make sure you have the latest UT patch: 4.36 patch for UT

Includes: Runtime Environment, UnrealEd, and UnrealScript Compiler

A copy of WotGreal for editing UnrealScript

   Extract WotGreal and install or wait until later in the tutorial

Available free of charge from

The first step is extract all of UT's source code using the UTEditor

   xxx.uc files are source files for UnrealScript. This step brings them from their source file format (xxx.u) that ships with UT back to source format for you to edit. You can do this with Mods you have downloaded and installed as well. You can think of the source exporter in UTEd as an application within the UT development environment that reverse engineers the content (but not the underlying engine) for you. You can extract models, textures, sounds, etc... but this step will only do the source code.

       Open up UTEd
       Open up the actor browser (the icon on the menu is a pawn)
       Goto Menu->File->Export All Scripts
       You will see a dialog box that asks if you would like to create xxx.uc files for later use. Click Ok.
       You should now see a list of Actor Classes in the Actor Browser and the main Actor classes from which they subclass. Feel free to expand parts of the tree to explore different types of Actors.
       Close UTEd.

Now you must create the Package for your game

   A package is an organizational scheme used by UT to separate game content into discrete projects. Packages are represented by folders found directly under the UnrealTournament folder in the file hierarchy. Some examples of packages are: Engine, Core, and UnrealShare (If you do not see these under (C:\)UnrealTournament\, go back to the source code extraction step). What this means to you is that you can keep all of your code and content in your new package to keep it distinct from the content distributed with UT as well as that made by other content developers like yourself.

   Create a new folder in your UnrealTournament folder with whatever name you want. We will proceed using "myGame".
   Make a new folder in myGame called "Classes":
   This new folder is where your source files will go. The myGame folder is the package that your new game, source, media, etc... will be contained in and associated with. The folder name determines where the compiler will look for different file types.
       \Classes - xxx.uc - UScript source files
       \Textures - xxx.utx - texture files
       \Models - xxx.3d, .psk, .psa, etc... model files which are converted at compile time
       \Sounds - xxx.uax
       \Music - xxx.umx
           Models, Sounds, and Musics do not have to be in those respective paths, as you will load them or path them explicitly in most cases, but it is a good convention so we will stick to it.
   You can just create the Classes folder for now

Editing UnrealScript code - 1: Configuring UT for your game

   Before you get started making content, you will have to configure UT so that it will recognize your new package and game type. Any Mod that you download had to do this at the beginning of its development. Fortunately, when it comes time for you to package your Mod, you will simply distribute your source, so the person playing doesn't have to do this step. However, you are essentially making your new Mod out of thin air, so you have to tell the UT engine that it is there and how to handle it during development. These are the first few steps in that process and should be enough to get you going.

Configuring WotGreal

It is not essential that you use WotGreal to edit your source. Any text editor will do. In fact, UTEd will also bring code up for you through the actor browser. However, WotGreal's interface is specifically designed for games that use the UT engine and all of the tutorials and reference material I have read advises AGAINST using UTEd to edit source at all costs. There are tutorials for using MSVStudio and such out there. I have had the most success with WotGreal, but it is a little buggy and idiomatic at times. The hardest part is getting it up and running the first time. After you have your new packages/games configured, it makes everything easier, but there is a little startup headache. If WotGreal freezes up during class/path refresh or startup, just close it and restart.

   If you have not run WotGreal before, you will be prompted to set up your new game's file paths immediately, otherwise go to the Menu->Options->Preferences
   Click the radio button that says, other or UT, whichever you prefer.
   The Game Executable section can be empty.
   the Deleted Class Path should be filled in by WotGreal. If not, just put it somewhere you will remember. This is where deleted xxx.uc files will be placed when you delete them through WotGreal's IDE.
   in the Game INI: text field, push the browse button (...) and open up the UnrealTournament.ini file. Start from wherever you have installed UnrealTournament:
   e.g.- (C:\)UnrealTournament\System\UnrealTournament.ini
   The next text field, UCC.exe:, should be filled in automatically for you when you specify the xxx.ini file
   ignore the text field, TestMap:
   choose OK/yes when prompted to expand the class tree, Menu->UT->refresh package/class tree

Configuring UnrealTournament.ini

xxx.ini files are used by the UT engine to store persistent data that is useful to the engine. xxx.ini files are usually associated with the engine in general and preferences, e.g.- User.ini stores player preferences; That's why they don't go away after you exit UT. In this case, we are saving changes to the compiler and UTEd configuration that were made since its release, namely your new Mod. Using WotGreal, we willl associate UnrealTournament with the myGame package we made before. Once we do this, the UnrealTournament compiler and game logic (ucc.exe contains both of these) will be able to reference it.

       From the menu, go to Menu->Tools->Modify/Edit Packages
       Add a package called "myGame". The package should now be associated with UT's compiler. Verify this by opening UnrealTournament.ini.
           A quick way to open up the xxx.ini file associated with your game (UnrealTournament.ini at this point) is to go the the Menu->UT-> edit UnrealTournament.ini.
       Now do a search on the string "editpackages" (Ctrl+F, case insensitive). You should now see a highlighted portion of the file like this:
   If you do not see this last line (it will not be red), then add it yourself by hand and replace "myGame" with your package name.
       refresh the package tree, Menu->UT->refresh package/class tree

Editing UnrealScript code - 2: Creating Your New Game Type

Ok, we are finally ready to look at a little UnrealScript source code. If you don't know, UnrealScript is an OO language like Java or C++, so it supports inheritance. We DO NOT EVER edit classes we did not write ourselves. This will compromise the integrity of UT, plus we don't have access to native source to ever get it back to the way it was. If you accidentally change code and don't know what you did or delete a UScript object file (xxx.u), just get xxx.u files from someone else's distro or backup your package and re-install UT.

We make changes to the way things operate by subclassing and using xxx.ini and files to tell the system which classes to use for different things. The class for our new game type will therefore be based on an existing game type, TournamentGameInfo. This will create a basic game with no rules, no HUD, no Bots, etc... You may certainly base your game type on DeathMatch, CTF, or whatever if you plan to focus more on changing things besides rules of the game. We use TournamentGameInfo because it provides multiplayer support and all the goodies that UT has to offer, but give you a clean slate to make a new game.

Subclassing From an Existing Game Type

From within WotGreal...

       Now create a new text file called nothing.uc from within WotGreal using File->New. The file should have compilable content. Put this code in nothing.uc and save it in your packages (C:\)UnrealTournament\myGame\Classes. folder
               class nothing expands object;
               All that this does is allow WotGreal to access the package.

           Go to the Class Browser on the left and expand the actor tree to find TournamentGameInfo.
           Right click on the TournamentGameInfo branch and choose Create SubClass. Choose myGame for your new class name and scroll through until you find myGame or type it in to the package name field.
           If prompted to create the package DO NOT say yes. This will make your package under the \System directory. This means that WotGreal cannot see your package.
           If WotGreal does not see your package, then go back and make sure that you have a (C:\)UnrealTournament\myGame\Classes folder with a compilable xxx.uc in it. WotGreal will look for any folders directly under UnrealTournament\ that, in turn, have a Classes\ folder directly under them. Only these packages will be usable in WotGreal.

Customizing Your New Game Type Through DefaultProperties

The DefaultProperties section is a very special section with a different parser, different syntax, and different behavior. It has links to the files I will talk about shortly, but for now just think of it as a a very irritable constructor. That is to say, this is where you can put default startup values for your class.

You should now see the source file, myGame.uc. you can see that it extends TournamentGameInfo and has a small empty section called DefaultProperties.

   NOTE: do not type anything after the DefaultProperties section.
   In the DefaultProperties section type this line:
   your file should now look like this:
   class MyGame expands TournamentGameInfo;
   NOTE: This line must look exactly like this except for the part in quotes, no extra spaces or anything. UT is VERY particular about the syntax of the DefaultProperties section.

Configuring Your Game Type With

Now we have to give a metaclass definition for our game type so UT will know in which package to look for its superclass. We will do this by creating an file to be associated with our package. files are similar to xxx.ini files, in that they are used for persistent data, except files are associated with a certain package. As a result, we can use a file for instructions to the engine on how to load our game type without mucking with the UnrealTournament.ini on the user's system once we have finished our Mod and want to install it on their system. You will make changes to this file later as you progress, but this should be all you need for now. Just remember that this file is here.

right click on the myGame class branch in the class or package browser: or and choose edit

Add the following line:

[Public] Object=(Name=MyGame.MyGame,Class=Class,MetaClass=Botpack.TournamentGameInfo)

Save the file, myGame.uc and minimize WotGreal

Compiling Your New Game Type

UTEd and WotGreal are pretty buggy, but you're in luck with the UCC compiler. It...Is...Rock...Solid... If there is anything you can rely on, it is this little piece of art...nay, miracle. The error messages are usually pretty helpful too, once you get used to UT syntax, anyway

   if this is your first time compiling, skip to the next (ucc make) step, otherwise you must delete the object file (xxx.u) associated with your package. The UT compiler will only compile packages that are listed in the EditPackages section of your game's xxx.ini file, and do not have a corresponding object file. Also, you can only reference classes that are defined in the same package or those compiled prior to yours.
       Type the following line
       >del myGame.u
   open a command prompt (cmd or command) and change to the UT's system directory: (C:\)UnrealTournament\System\
       type the following line:
       >ucc make
   If everything goes smoothly, you should see your package and class compile. Otherwise, you will have errors.

Testing Your New Game Type

   Start UT and from the menu, choose Multiplayer->Start New MultiPlayerGame. A dialog box will appear which shows the list of game types. Click on the listbox and choose myGame.
   A default map should start with your new game type being run within it.

UnrealScript Syntax

   Author: Robert J. Martin

This is intended as a quick reference for someone who is very familiar with Java/C++ style OO languages and is at least somewat familiar with UnrealScript in general. In particular, it is directed at those using UScript for academic purposes. I don't go in to a great amount of detail for many things, especially for things found in the UScript reference, READ THAT FIRST!!!. Please Contact me if you see any mistakes, need for extra clarification on anything, or have any contributions to make.

   Language Overview
   Basic Syntax
       Conventions (used in this document)
       Class Declaration
       Data Types
       Variable Specifiers
       Flow Control
   Advanced Syntax
       Operator Creation

Language Overview

For the most part, UnrealScript is very close to Java in syntax and behavior. Objects and inheritence are treated in a very similar way, and source code is compiled into something resembling byte code. There is an environment analgous to the JRE, in which Objects are instantiated and data is bound dynamically and function calls operate by making references to the underlying native code where appropriate. The parser uses a two-pass strategy.

   Like java, you will not have to use pointers directly or destroy objects. There is a service comparable to garbage collection that will do it for you.
   There are NOT separate header/source files. Declarations and Definitions are done in xxx.uc source file.
   Source files are compiled into a byte-code object file, xxx.u.
   You can only reference classes defined in the same package or in one that was compiled before the class that is referencing it. Package compilation order is determined by its order in in the EditPackages section of the xxx.ini file that UCC.exe uses (UnrealTournament.ini by default).

Conventions (this document)-

   italics - used to represent keywords in UnrealScript
   code - used when I give examples in compilable, UScript

Basic Syntax

   General -
       C/C++ style comments -
           e.g.- //this will not be compiled... /*nor will this*/
       code is NOT case sensitive
   Class Declaration -
       extends and expands can be used interchangably for inheritance.
           class MyGame expands TournamentGameInfo;
           class MyGame extends TournamentGameInfo;
           ...will both work
       The class declaration must be the first line (except for comments).
       #exec commands, if present, must follow immediately after class declaration
   Variables -
       var -
           It is the first word in class or state variable declaration
           You CANNOT initialize variables when they are created.
               Right: var int myInt;
               Wrong: var int myInt = 100;
           Var's are editable from UTEd when parentheses are used.
       local -
           Use local for declaring variable inside of a function. It will be recycled by the garbage collector when a function goes out of scope
               function myFunction( ) {
               local int myInt;
   Data Types -
       int -
           size: 32-bit
           range: -2147483648 to 2147483647
           literal = nnn
       float -
           size: 32-bit
           range: -8388608 to 8388608 (I think)
           literal = nnn.nnn
           floats literals from -1 to 1 exclusive MUST start with a 0
               Right: x = 0.314;
               Wrong x = .314;
       bool -
           literal = true or false
           does not support automatic string resolution
           The convention is to start bool variables with "b". You will see this throught UScript code. Try to stick with this to maintain consistency .
       byte -
           size: 8-bit (1 byte )
           range: 0-255
           literal = 0xnnn
       enum -
           size: 8-bit
               enum EColor{
               var EColor ShirtColor, HatColor;
               var enum EColor{
               } ShirtColor, HatColor;
           enums are stored internally as a byte. Don't use enums as parameters in functions. If an outside class attempts to call that function, you will get a compiler error even if both classes have the same definition. Use a byte instead:
               Right: function keyEvent(Byte key);
               Wrong: function keyEvent(EInputKey key);
           useful functions
               int enumCount(Enum ) - returns the number of elements for this enumeration
       string -
           literal = double quotes.
               string s;
               s = "hello";
           It is a primitive data type, NOT an object
           many objects, int, float, Object, etc... support automatic string resolution. bool does not.
           concatenation -
               $ - used to concatenation string variables and/or literals together
                   string s, t;
                   s = "Rocks";
                   t = "UT" $s $"MyWorld"; // t = "UTRocksMyWorld"
           relevant functions -
               int Len(string) - returns the length of the string
               int inStr(string s, string t) - returns the offset of the first appearance of t in s, or -1 if it is not found
               string Mid(string s, int i, optional int j) - returns the first j characters of the string starting at offset i
               string Left(string, int i) - returns the i leftmost characters of the string
               string Right(string, int i) - returns the i rightmost characters of the string
               string Caps(string) - returns the string converted to uppercase
       name -
           The name type is different from the string data type, but it can be cast as a string implicitly.
           It is constant; it cannot be changed after an object has been created. You can change it at spawn time, or within UTEd.
           An object's Name is guaranteed to be unique within a level. Default is the object's class concatenated with an enumerator
               e.g.- SniperRifle12, TMale2, etc...
           literal = single quotes
               if (other == 'Commander13') { ... }
           The name type can be used to represent class names as well in certain contexts. (see Class)
       struct -
           UScript structs are similar to C style structs. They are used for variables, but not functions.
           use -
               struct Vector {
               var float X;
               var float Y;
               var float Z
               var Vector destination;
           predefined structs -
               Vector: A unique 3D point or vector in space, with an X, Y, and Z component.
               Plane: Defines a unique plane in 3D space. A plane is defined by its X, Y, and Z components (which are assumed to be normalized) plus its W component, which represents the distance of the plane from the origin, along the plane’s normal (which is the shortest line from the plane to the origin).
               Rotator: A rotation defining a unique orthogonal coordinate system. A rotation contains Pitch, Yaw, and Roll components.
               Color: An RGB color value.
               Region: Defines a unique convex region within a level.
       array -
           Only one-dimensional arrays are valid
           only static arrays are valid, you cannot define array size with a variable, only a literal.
               Right: var int myArray[10];
               Wrong: var int myArray[x];
           relevant functions
               int arrayCount(array) - returns the number of elements in the array
       Object -
           constructors -
               There are NO constructors. You can use the DefaultProperties section for default initialization, but there are no constructor functions for object creation.
           instantiation (for non-Actor objects) -
               Console C;
               C = new (none) class 'myNewConsole'; /* instantiate a new Console of type myNewConsole */
           None - equivalent of NULL in Java
           Use "." separation for object resolution
           typecasting - you can use typcasting as in Java, but it looks like a function call
               local Actor A;
               A = enemy; //get this classes current enemy pawn
               A = PlayerPawn(A); // cast A as a playerPawn.
               will return None if it cannot convert
           super( ) -
               used to explicitly use parent data or behavior
               you can go multiple levels up the hierarchy
                   super(ancestorClass).ancestorVersion( ); // calls the function of this class's ancestor of type "ancestorClass"
                   notice that there are no single quotes around ancestorClass in this context
           Objects v. Actors
               instantiation (for Actors)
                   Actor A; // called from an actor
                   A = spawn(class 'BoomStick', self, , location, rotation);
                       Class - describes the class of the object you want to spawn (must be of type Actor)
                       Actor - owner of the new Actor - optional
                       Name - name of new Actor - optional
                       Vector - location of new Actor - optional
                       Rotator - rotation of new Actor - optional
               Actors use Self instead of This;
               Actors get their Tick( float ) function called by the engine, Objects do not have this function.
               Actors get their Pre/PostBeginPlay( ) as well as BeginPlay( ) functions called by the engine when the game starts up. This is another good place to put initialization and stuff. I don't know the difference between these functions.
       class -
           This is a class object. It is of name type and is a reference to a particular class type
           all Objects (and Actors) have a class field which can be used to get its class for various uses.
           relevant functions -
               bool isA(name queryClass) - returns true if the possessing object is of the type represented by the queryClass name.
           class limiter -
               Use the classlimiter to make sure that an object is of a certain class.
               This is like typecasting but for constraining classes DOWN the hierarchy tree
               example -
                   other is of type actor, but we only want it to be non-None if a Pawn is assigned to it.
                   var class<Pawn> C; // code from within in an Actor class
                   C = other.class; //will return null if not of type pawn.
   Variable Specifiers -
       private - same as Java, but not used to the same extent. This specifier is used very little in practice
       const - cannot be changed once initialized
       transient - will not be saved to disk
       config - configurable using xxx.ini and files.
       native - the variable will be stored using native C++ code rather than UScript code
       editable - editable variables can be changed within UTEd. put parens after the word var to designate a variable as editable
           var( ) int MyInteger; // Declare an editable integer in the default category.
           var(MyCategory) bool MyBool; // Declare an editable integer in "MyCategory".
   Conversions -
       UnrealScript supports many automatic conversions, e.g. - rotators to vectors
       see UScript reference
   Operators - see UScript reference

   Flow Control -
       if -
           more like Java than C/C++.
           you must use boolean statements in almost all contexts. There are exceptions but it is better to just stick to the rule to be safe.
               Right - if(Actor != none) { ... }
               Wrong - if(Actor) { ... }
           Just like Java/C++, you don't have to use curly brackets if your consequent is one line.
               if(true) x = 10;
               if(true) { x = 10; y = 12; }
       switch - almost exactly like C++/Java. I am not aware of any differences
       Loops -
           for -
               just like if, you must have a true boolean value
               you cannot declare a new variable in the condition section of the for loop
                   Right - int i; for( i = 0; ....)
                   Wrong - for( int i = 0; ....)
           while -
               just like if, you must have a true boolean value
           do-until -
               just like if, you must have a true boolean value
               UScript's version of "do ... while", but the semantics are reversed
                   i = 0;
                   j = 0;
                   i = i + 1;
                   j ++;
                   } until( i == 4 );
                   both i and j will be 4 when the loop terminates
           foreach (iterator) -
               these are special loops that can only be used from by subclasses of Actor.
               this is a quick way to go through a list of all actors or actors of a certain type.
               types - (Taken directly from UScript Reference)
                   AllActors ( class BaseClass, out actor Actor, optional name MatchTag );
                       Iterates through all actors in the level. If you specify an optional MatchTag, only includes actors which have a "Tag" variable matching the tag you specified.
                       Actor A;
                       foreach AllActors( class 'PlayerPawn', A) { //iterate through PlayerPawns
                       Log(A.location) // Log their location
                   ChildActors( class BaseClass, out actor Actor );
                       Iterates through all actors owned by this actor.
                       BasedActors( class BaseClass, out actor Actor ); Iterates throgh all actors which are standing on this actor.
                   TouchingActors( class BaseClass, out actor Actor );
                       Iterates through all actors which are touching (interpenetrating) this actor.
                   TraceActors( class BaseClass, out actor Actor, out vector HitLoc, out vector HitNorm, vector End, optional vector Start, optional vector Extent );
                       Iterates through all actors which touch a line traced from the Start point to the End point, using a box of collision extent Extent. On each iteration, HitLoc is set to the hit location, and HitNorm is set to an outward-pointing hit normal.
                   RadiusActors( class BaseClass, out actor Actor, float Radius, optional vector Loc );
                       Iterates through all actors within a specified radius of the specified location (or if none is specified, this actor’s location).
                   VisibleActors( class BaseClass, out actor Actor, optional float Radius, optional vector Loc );
                       Iterates through a list of all actors who are visible to the specified location (or if no location is specified, this actor’s location).
   Functions -
       definitions start with the word, function
       returntypes - return type is optional, void is implicitly assumed if there is not one specified.
       parameters -
           optional - means this parameter does not need to be present when the function is called. To test whether it has been specified from within the function in question, just test to see if the variable has been set.
               function bool bNoArgs(int j, string s, Actor A) {
               if( (j == 0) && (s == "") && (A == none) )
               return true;
           coerce - can be used to force a parameter to be cast as a certain type when the function is called. The only context I see this used in is forcing parameters to be cast as strings.
               function returnString(coerce string i, coerce string c, coerce string a) {
               return i $c $a;
               if this function is called in this way, with three non-"null" parameters:
                   int i;
                   Class c;
                   Actor a;
                   ... // initialize i, a, and c
                   Log(returnString( i, c, a));
               ... then it will return the integer, class, and actor reference as a concatenated string
           out - used for pass-by-reference. Any changes made to the variable within the function also affect the variable which was passed to the function.
       overriding & overloading -
           overriding is possible, in fact extremely necessary.
           overloading functions with different parameter lists or return type and the same name is impossible.
       Specifiers -
           static -
               so that the function can be called independent of an instance. You still need an object to be instantiated to call it though, I think using the Class object might work:
                   Class MyClass = MyObject.class;
               ... but I'm not sure. If someone knows better please contact me and I will update this section
           singular - only one instance of this function can be called at once. Useful for avoiding infinite recursion for mutually dependent functions... see UScript Reference
           native - can only be used inside of a class that is declared native. Every native function will require a native C++ definition.
           exec - can be used to have this function callable from the console or using consoleCommand(string).
   event -
       Native functions that will be passed up from the engine.
       A prime example is keyEvents and mouseEvents from input, etc...
   States -
       used to make FSM's within Objects. Mainly for AI purposes.
       Makes procedurally based code rather than functionally based. Like Basic if you were ever unfortunate enough to use that thing.
       CAN be used with non-Actor objects. I'm not sure why the UScript reference says "Actors". Though, in practice, it is almost always used within Actors. The exception I've seen is in UWindow stuff, which does not subclass from Actor.
       data and behavior hiding -
           each state can have different versions of the same data and functions. This essentially allows different logic for function calls depending upon the context (current state). e.g.- most pawn descendents have several different definitions for Bump(Actor other), so that the Actor possessing the function will behave differently.
       auto - A state declared auto will be the default state of an Actor if another one is not prompted to take effect.
       label -
           Begin - default starting point
           always use at least one label.
           will go to the label within the state
       gotoState('stateName', optional 'labelName')
           goes to the state, with the option of going to a label other than begin
       latent functions -
           latent functions are native functions that take some amount of time to return. They can only be called from within state code. Examples are MoveToward(Actor), Sleep(float), and FinishAnim( ).
           beginState( ), endState( )
       ignores -
           can be used to tell the state to ignore events and function called by the engine. This is to avoid a lot of the confusion that arises from mixing inheritance and states. If you don't want some other class or logic calling the global version of Bump( ) that might take you out of your state, just tell your state to ignore the Bump function.
               state myState {
               ignores Bump;
       BeginState/EndState functions:
           you can use these to prepare or wrap-up things before and after a state is used, respectively
           A state's BeginState( ) function is called before the state is entered, and EndState( ) is after the state is left (but before another state is entered), know matter what caused the state change.
       global - see UScript reference
       You can sort of think as this as a default constructor. When an Actor is created, values can be initialized here. This is also a way to set global variables that you may use for development. I owe a lot of sleepless nights to this section.
       This must be the last section in the class file.
       DO NOT end defaultproperty statements with a semicolon(;) and...
       DO NOT put spaces in between the "=" and the variable and value
           Right: ThisValue=100
           Wrong: ThisValue = 100;
       array elements are dereferenced using parentheses instead of square brackets
           Right: myArray(0)=5
           Wrong: myArray[0]=5
       Log(string) -
           This will write the string to whatever xxx.log file is defined in the games xxx.ini file.
       BroadcastMessage(string) -
           can only be called by classes inheriting from Actor. This will write a text message to the HUD so you can do runtime checking
       ConsoleCommands -
           see UScript reference(ConsoleCommands). You can declare a function to be of exec type and it can be called from the console if it is defined in certain classes: Console, HUD, etc.

Advanced Syntax-

   Dynamicism - This poorly labeled section is devoted to loading and manipulating things dynamically/by-name, which you cannot do with most languages.
       Classes -
           DynamicLoadObject( string className, name baseClass). used to get a Class object from a string.
           actually reads the file package you provide to get the class object
               String myClassName = "myPackage.myClass";
               Class myClassObject = DynamicLoadObject(myClassName, class 'Class');
               baseClass myObject = spawn (class <baseClass> myClassObject);
               So, you need to have a string that contains the package and the class, and you can instatntiate an object by a dynamically determined class name... neat, huh? If you need to get the package by string, you will have to use the ConsoleCommand for listing
       Data -
           You can actually set and get variables using the string representation of a variable's name.
           in the statement, x = 20; the string is "x".
               String getPropertyText(String propertyName) - returns the property as a string:
                   int myVar = 300;
                   String sValue = getPropertyText( "myVar" ); // sValue is equal to "300"
               setPropertyText(String propertyName, String propertyValue) - sets propertyName to propertyValue uses built-in conversion rules (String to int, String to float, etc...)
       Functions -
           The key to calling functions by their string name lies in the Exec keyword. What you have to do is make whatever function you want to call an exec style function:
               exec function myFunction(coerce string s) { }
               In this code, you have made 'myFunction' callable from the console, with whatever you write after any whitespace following the word 'myFunction' being pushed into the 's' variable
               so, from the console you would type :
               > myFunction myArgument
               ... then 's' will be equal to "myArgument", and you can use that within myFunction
               Now then, there is also a function within class Console called 'bool ConsoleCommand(coerce string s)'. to call your exec'd function, 'myFunction' from code, you type:
                   bool isFunctionThere; //optional
                   isFunctionThere = ConsoleCommand("myFunction myArgument");
               ... 'isFunctionThere' will be true if the function was there, false otherwise.
               NOTE: this technique will only take effect if you put your exec style function in an ACTIVE class that can use exec style functions. Examples include Console and HUD. Just because your class subclasses from one of these does not mean your function will be recognized. It has to be considered active by the engine (gameInfo).
   Operator Creation -
       You can create your own operators as well. For clues, check out Object.uc. It isn't much more complicated than that.
       example - I have an object I created that subclass directly from object for using XML. Let's say I want to override the concatenation operator so that it will make a new XML object when in the context of "XMLObject $string". The definition will start out something like this
       static final operator(40) XMLObject $ ( XMLObject A , string B ) { ... }
       This must be static and final. This means you can't make any references to instance variables or non-static functions within that class. I CAN, however make references to 'A' instance data.
       The (40) is a priority number for deciding order of operations in mixed expressions.
       In this example XMLObject is the return type and $ is the operator.
       A is the left outfix parameter, B is the right.