If you have skimmed through the exported UT3 UnrealScript source code, you may have noticed a certain property in each and every defaultproperties section, including any subobject definitions: ObjectArchetype. This article will explain what an "(Object)Archetype" is, how to use it and why it can be found all over the exported script sources, but not in the original source files you can download from UDN's UT3ModHome page. (Note that the UDK already comes with the original, not the exported sources.)
What is an archetype?
In the context of Unreal Engine 3 an "archetype" simply is an object template, a set of property values that will be assigned to newly created objects.
Using archetypes
A common explicit use (see the next section for an even more common implicit use) for archetypes is to duplicate objects. To duplicate a non-actor object, an expression like one of the following is used:
new OriginalObject.Class (OriginalObject) new(NewOuter) OriginalObject.Class (OriginalObject)
The first line duplicates the OriginalObject and uses the object executing that code as the duplicate's new Outer, while the second line explicitly specifies a different object as the Outer. See new for more details on creating objects with the special operator new.
Analogously you could duplicate actors with the Spawn() function, but this may not work correctly with replicated actors. There is no instance of spawning actors using archetypes in the stock code, though.
Actor archetypes can be used within UnrealEd, though. You can create archetypes for certain types of actors you are going to need more than just once. Before (and after!) you place actors based on that archetype, you can modify the archetype's properties and the change will be propagated to all actors created based on that archetype. If you changed a property of one of those actors directly, it will no longer be inherited from the archetype and any changes to the archetype's property is ignored by that specific actor instance.
Why is ObjectArchetype in all defaultproperties?
Actually it isn't. No really, it's not in there before compiling. You only see them there because the script exporter generated the defaultproperties blocks on-the-fly during export by simply dumping each class's corresponding default archetype's properties.
Just for clearification: Never set a Name or ObjectArchetype in the defaultproperties of your own classes. The remainder of this section only explains how the engine works with archetypes internally to represent default values, and not how you should do it.
This, however, provides an excellent view on how archetypes work and how they are used internally.
Let's have a look at the Core.Object class's exported defaults:
defaultproperties { Name="Default__Object" }
That's obviously not the class name, and it's not the name of newly created objects either. It's actually the name of the archetype object holding the default values of the Object class. This is the only defaultproperties block without an ObjectArchetype definition, by the way. Now let's have a look at a direct Object subclass: Core.Component.
defaultproperties { Name="Default__Component" ObjectArchetype=Object'Core.Default__Object' }
There's an ObjectArchetype, and look what it's set to: an object of class Object with the name Default__Object from the Core package.
Coincidence? Let's have a look at the direct Component subclass Engine.ActorComponent:
defaultproperties { TickGroup=TG_DuringAsyncWork Name="Default__ActorComponent" ObjectArchetype=Component'Core.Default__Component' }
Here, ObjectArchetype is set to an object of class Component with the name Default__Component from the Core package. See the pattern?
Ok, let's try the ActorComponent subclass Engine.PrimitiveComponent:
defaultproperties { // (stripped some defaults here) Name="Default__PrimitiveComponent" ObjectArchetype=ActorComponent'Engine.Default__ActorComponent' }
Aha, the ObjectArchetype now is an ActorComponent from the Engine package called Default__ActorComponent!
What you see here is how the Unreal Engine manages default values. The compiler actually turns the defaultproperties block into an archetype of the class defining those defaults and sets its ObjectArchetype property to the default archetype of the parent class. That's exactly what you would expect from defaultproperties, they are inherited from parent classes.
In other words, archetypes form a hierarchy tree very similar to the class tree with Object'Core.Default__Object' being the root. For each class that extends Object, there's an archetype that uses Object'Core.Default__Object' as its "parent archetype" to inherit property values from. When selecting a few of those archetypes, a tree like the following could be formed:
__TREETAG_3__Actor'Engine.Default_Actor'
__TREETAG_1____TREETAG_2__Info'Engine.Default__Info'
__TREETAG_2__Component'Core.Default__Component'
__TREETAG_0____TREETAG_2__ActorComponent'Engine.Default__ActorComponent'
__TREETAG_0____TREETAG_0____TREETAG_2__PrimitiveComponent'Engine.Default__PrimitiveComponent'
__TREETAG_0____TREETAG_0____TREETAG_0____TREETAG_2__SprintComponent'Engine.Default__SpriteComponent'
__TREETAG_0____TREETAG_0____TREETAG_0____TREETAG_0____TREETAG_2__SpriteComponent'Engine.Default__Info:Sprite'
Each node of this tree uses its parent node as its ObjectArchetype.
But wait, what's that last one? It looks totally different. That one actually is a subobject's archetype, the archetype of the subobject with the name "Sprite" in class Engine.Info, to be precise. To see why that's such a big deal, let's have a look at the Engine.Route class, which extends Engine.Info. In the exported defaultproperties you will notice the following lines:
Begin Object Class=SpriteComponent Name=Sprite ObjName=Sprite Archetype=SpriteComponent'Engine.Default__Info:Sprite' Sprite=Texture2D'EngineResources.S_Route' ObjectArchetype=SpriteComponent'Engine.Default__Info:Sprite' End Object
Urgh, what a messy subobject definition. Let's compare that to the original script source:
Begin Object Name=Sprite Sprite=Texture2D'EngineResources.S_Route' End Object
Oh, much better! As you can see there's no "Class=…" clause in the subobject definition. This means the subobject with the same name in the parent class is used as template, but with the modifications specified here. The actual result of this can be seen in the exported subobject definition above: the parent class subobject is used as archetype for the new subobject. In our "archetype tree" the Sprite subobject of class Route would become a child of the SpriteComponent'Engine.Default__Info:Sprite' node.
Here on the Unreal Wiki you cannot directly browse this "archetype tree", but whenever you stumble across a subobject definition on the class description pages, it will link to the subobject and class it is based on.