<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.frictionalgames.com/page?action=history&amp;feed=atom&amp;title=HPL3%2FScripting%2FScripting_Guide%2FObject_Instances_vs_Object_Handles</id>
	<title>HPL3/Scripting/Scripting Guide/Object Instances vs Object Handles - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.frictionalgames.com/page?action=history&amp;feed=atom&amp;title=HPL3%2FScripting%2FScripting_Guide%2FObject_Instances_vs_Object_Handles"/>
	<link rel="alternate" type="text/html" href="https://wiki.frictionalgames.com/page?title=HPL3/Scripting/Scripting_Guide/Object_Instances_vs_Object_Handles&amp;action=history"/>
	<updated>2026-08-04T06:06:22Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.34.2</generator>
	<entry>
		<id>https://wiki.frictionalgames.com/page?title=HPL3/Scripting/Scripting_Guide/Object_Instances_vs_Object_Handles&amp;diff=7045&amp;oldid=prev</id>
		<title>TiMan: Created page with &quot;{{Hpl3ScriptingGuideMenuAdvanced}} {{shortPageTitle}} {| style=&quot;border:0px;&quot; cellspacing=&quot;0&quot; |- valign=&quot;top&quot; | style=&quot;padding-right:0.2em&quot; | An '''object instance''' is one pa...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.frictionalgames.com/page?title=HPL3/Scripting/Scripting_Guide/Object_Instances_vs_Object_Handles&amp;diff=7045&amp;oldid=prev"/>
		<updated>2026-07-30T08:08:44Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;{{Hpl3ScriptingGuideMenuAdvanced}} {{shortPageTitle}} {| style=&amp;quot;border:0px;&amp;quot; cellspacing=&amp;quot;0&amp;quot; |- valign=&amp;quot;top&amp;quot; | style=&amp;quot;padding-right:0.2em&amp;quot; | An &amp;#039;&amp;#039;&amp;#039;object instance&amp;#039;&amp;#039;&amp;#039; is one pa...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Hpl3ScriptingGuideMenuAdvanced}}&lt;br /&gt;
{{shortPageTitle}}&lt;br /&gt;
{| style=&amp;quot;border:0px;&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| style=&amp;quot;padding-right:0.2em&amp;quot; |&lt;br /&gt;
An '''object instance''' is one particular object created from a class. An '''object handle''' is a variable which can refer to an instance.&lt;br /&gt;
&lt;br /&gt;
The difference determines whether an assignment copies an object's data or makes another variable refer to the same object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
cExample first;          // Create an instance.&lt;br /&gt;
cExample second;         // Create a separate instance.&lt;br /&gt;
second = first;          // Copy first's data into second.&lt;br /&gt;
&lt;br /&gt;
cExample@ pExample;&lt;br /&gt;
@pExample = @first;      // Make pExample refer to first.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After the value assignment, &amp;lt;code&amp;gt;first&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;second&amp;lt;/code&amp;gt; are independent instances. After the handle assignment, &amp;lt;code&amp;gt;pExample&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;first&amp;lt;/code&amp;gt; provide access to the same instance.&lt;br /&gt;
&lt;br /&gt;
{{note|The class is the object's type or blueprint. The instance is the actual object created from that class. A handle is a reference through which an instance can be accessed.}}&lt;br /&gt;
| style=&amp;quot;width:0.1%&amp;quot; |&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Object variables ==&lt;br /&gt;
&lt;br /&gt;
For an instantiable object type, a declaration without &amp;lt;code&amp;gt;@&amp;lt;/code&amp;gt; creates an object variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
class cCounter&lt;br /&gt;
{&lt;br /&gt;
	int mlValue;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Example()&lt;br /&gt;
{&lt;br /&gt;
	cCounter counter;&lt;br /&gt;
	counter.mlValue = 10;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;counter&amp;lt;/code&amp;gt; variable owns an instance of &amp;lt;code&amp;gt;cCounter&amp;lt;/code&amp;gt;. It is constructed when the declaration is reached and destroyed when its lifetime ends, unless a handle keeps a reference to it.&lt;br /&gt;
&lt;br /&gt;
Unlike a handle, an initialized object variable is not optional and cannot be set to &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;. Its identity does not change during its lifetime. Assigning another object to it copies data into the existing instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
cCounter first;&lt;br /&gt;
first.mlValue = 10;&lt;br /&gt;
&lt;br /&gt;
cCounter second;&lt;br /&gt;
second = first;&lt;br /&gt;
&lt;br /&gt;
second.mlValue = 20;&lt;br /&gt;
&lt;br /&gt;
// first.mlValue is still 10.&lt;br /&gt;
// second.mlValue is 20.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For script-declared classes, AngelScript automatically supplies an assignment operator which copies each member unless the class defines its own &amp;lt;code&amp;gt;opAssign&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Object handles ==&lt;br /&gt;
&lt;br /&gt;
A declaration with &amp;lt;code&amp;gt;@&amp;lt;/code&amp;gt; creates a handle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
cCounter@ pCounter;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This does not create a &amp;lt;code&amp;gt;cCounter&amp;lt;/code&amp;gt; instance. The handle is initially &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; and must be made to refer to an existing or newly created object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
cCounter counter;&lt;br /&gt;
cCounter@ pCounter = @counter;&lt;br /&gt;
&lt;br /&gt;
pCounter.mlValue = 30;&lt;br /&gt;
&lt;br /&gt;
// counter.mlValue is now 30 because pCounter refers to counter.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Several handles may refer to the same instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
cCounter counter;&lt;br /&gt;
&lt;br /&gt;
cCounter@ pFirst = @counter;&lt;br /&gt;
cCounter@ pSecond = @counter;&lt;br /&gt;
&lt;br /&gt;
pFirst.mlValue = 50;&lt;br /&gt;
&lt;br /&gt;
// pSecond.mlValue and counter.mlValue are also 50.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The handles are separate variables, but the object behind them is shared.&lt;br /&gt;
&lt;br /&gt;
== Value assignment versus handle assignment ==&lt;br /&gt;
&lt;br /&gt;
The assignment operator &amp;lt;code&amp;gt;=&amp;lt;/code&amp;gt; normally operates on object values. For script classes, it copies the source instance's members into the destination instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
second = first;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The handle assignment operator &amp;lt;code&amp;gt;@=&amp;lt;/code&amp;gt; changes which object a handle refers to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
@pCurrent = @first;&lt;br /&gt;
@pCurrent = @second;&lt;br /&gt;
@pCurrent = null;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rebinding &amp;lt;code&amp;gt;pCurrent&amp;lt;/code&amp;gt; does not copy, modify, or destroy &amp;lt;code&amp;gt;first&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;second&amp;lt;/code&amp;gt;. It only changes the reference stored in &amp;lt;code&amp;gt;pCurrent&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
AngelScript can infer handle assignment in many declarations and function calls:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
iLuxEntity@ pEntity = Map_GetEntity(&amp;quot;MyEntity&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When reassigning an existing handle, writing the leading &amp;lt;code&amp;gt;@&amp;lt;/code&amp;gt; explicitly makes the intended operation unambiguous.&lt;br /&gt;
&lt;br /&gt;
== Complete comparison ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Property&lt;br /&gt;
! Object variable&lt;br /&gt;
! Object handle&lt;br /&gt;
|-&lt;br /&gt;
| Example declaration&lt;br /&gt;
| &amp;lt;code&amp;gt;cCounter counter;&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;cCounter@ pCounter;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Creates an instance&lt;br /&gt;
| Yes, for an instantiable type.&lt;br /&gt;
| No.&lt;br /&gt;
|-&lt;br /&gt;
| Default state&lt;br /&gt;
| A constructed object.&lt;br /&gt;
| &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Assignment&lt;br /&gt;
| Copies or assigns object data using &amp;lt;code&amp;gt;=&amp;lt;/code&amp;gt;.&lt;br /&gt;
| Rebinds the reference using &amp;lt;code&amp;gt;@=&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Can be null&lt;br /&gt;
| No, after successful construction.&lt;br /&gt;
| Yes.&lt;br /&gt;
|-&lt;br /&gt;
| Can alias another variable's instance&lt;br /&gt;
| No.&lt;br /&gt;
| Yes.&lt;br /&gt;
|-&lt;br /&gt;
| Member access&lt;br /&gt;
| &amp;lt;code&amp;gt;counter.Method()&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;pCounter.Method()&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Identity comparison&lt;br /&gt;
| Take handles to the objects when identity must be compared.&lt;br /&gt;
| Use &amp;lt;code&amp;gt;is&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;!is&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Typical HPL3 use&lt;br /&gt;
| Independent script data and value-like utility objects.&lt;br /&gt;
| Entities, bodies, lights, resources, GUI objects, polymorphism, and optional references.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Value types and reference types ==&lt;br /&gt;
&lt;br /&gt;
AngelScript distinguishes between '''value types''' and '''reference types'''.&lt;br /&gt;
&lt;br /&gt;
=== Value types ===&lt;br /&gt;
&lt;br /&gt;
Value types directly contain their data. Assigning a value type creates an independent copy. Primitive types such as &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;bool&amp;lt;/code&amp;gt; are value types and cannot have object handles.&lt;br /&gt;
&lt;br /&gt;
HPL3 also registers many utility classes as value-like types. Vectors, colors, matrices, and IDs are normally passed or stored as values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
cVector3f firstPosition = cVector3f(1, 2, 3);&lt;br /&gt;
cVector3f secondPosition = firstPosition;&lt;br /&gt;
&lt;br /&gt;
secondPosition.x = 10;&lt;br /&gt;
&lt;br /&gt;
// firstPosition.x is still 1.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whether an application-registered object type supports handles is decided by HPL3. Do not assume that &amp;lt;code&amp;gt;@&amp;lt;/code&amp;gt; can be used with every class shown in the scripting API.&lt;br /&gt;
&lt;br /&gt;
=== Reference types ===&lt;br /&gt;
&lt;br /&gt;
Reference types are created separately in memory and may be accessed through handles. All script-declared classes are reference types. Many HPL3 engine classes are also exposed as reference types.&lt;br /&gt;
&lt;br /&gt;
Engine objects are usually retrieved as handles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
iLuxEntity@ pEntity = Map_GetEntity(&amp;quot;MyEntity&amp;quot;);&lt;br /&gt;
iPhysicsBody@ pBody;&lt;br /&gt;
&lt;br /&gt;
if(pEntity !is null)&lt;br /&gt;
	@pBody = pEntity.GetMainBody();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Classes such as &amp;lt;code&amp;gt;iLuxEntity&amp;lt;/code&amp;gt; represent engine-owned objects. They are normally obtained from HPL3 rather than instantiated directly in a map script.&lt;br /&gt;
&lt;br /&gt;
{{note|Reference type does not mean that every variable is automatically a nullable handle. A script-class object variable declared without &amp;lt;code&amp;gt;@&amp;lt;/code&amp;gt; still creates and owns an instance; adding &amp;lt;code&amp;gt;@&amp;lt;/code&amp;gt; creates a separately rebindable, nullable handle.}}&lt;br /&gt;
&lt;br /&gt;
== Copying script-class instances ==&lt;br /&gt;
&lt;br /&gt;
The automatically generated assignment operator for a script class copies each member:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
class cSettings&lt;br /&gt;
{&lt;br /&gt;
	float mfVolume;&lt;br /&gt;
	bool mbEnabled;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
cSettings original;&lt;br /&gt;
original.mfVolume = 0.5f;&lt;br /&gt;
original.mbEnabled = true;&lt;br /&gt;
&lt;br /&gt;
cSettings copy;&lt;br /&gt;
copy = original;&lt;br /&gt;
&lt;br /&gt;
copy.mfVolume = 1.0f;&lt;br /&gt;
&lt;br /&gt;
// original.mfVolume is still 0.5f.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A class may implement &amp;lt;code&amp;gt;opAssign&amp;lt;/code&amp;gt; to define different assignment behavior. HPL3 application types may also provide their own assignment operators, so the exact meaning of value assignment ultimately belongs to the type.&lt;br /&gt;
&lt;br /&gt;
=== Shallow copies of handle members ===&lt;br /&gt;
&lt;br /&gt;
Copying an object does not necessarily duplicate every object to which its members refer. If a class contains a handle, the generated assignment operator copies that handle:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
class cTarget&lt;br /&gt;
{&lt;br /&gt;
	int mlValue;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class cContainer&lt;br /&gt;
{&lt;br /&gt;
	cTarget@ mpTarget;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
cTarget target;&lt;br /&gt;
&lt;br /&gt;
cContainer first;&lt;br /&gt;
@first.mpTarget = @target;&lt;br /&gt;
&lt;br /&gt;
cContainer second;&lt;br /&gt;
second = first;&lt;br /&gt;
&lt;br /&gt;
second.mpTarget.mlValue = 25;&lt;br /&gt;
&lt;br /&gt;
// first.mpTarget and second.mpTarget still refer to the same target.&lt;br /&gt;
// target.mlValue is now 25.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is called a '''shallow copy'''. The &amp;lt;code&amp;gt;cContainer&amp;lt;/code&amp;gt; data was copied, but the target object was not duplicated. A true independent or '''deep copy''' must be implemented explicitly by constructing new referenced objects and copying their contents.&lt;br /&gt;
&lt;br /&gt;
== Function parameters ==&lt;br /&gt;
&lt;br /&gt;
The same distinction applies when passing objects to functions.&lt;br /&gt;
&lt;br /&gt;
Passing an object by value gives the function a copy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
void ChangeCopy(cCounter counter)&lt;br /&gt;
{&lt;br /&gt;
	counter.mlValue = 100;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Passing a handle gives the function access to the same instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
void ChangeOriginal(cCounter@ pCounter)&lt;br /&gt;
{&lt;br /&gt;
	if(pCounter !is null)&lt;br /&gt;
		pCounter.mlValue = 100;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Passing a value object by constant reference avoids a copy while preventing assignment through that parameter:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
float GetDistanceFromOrigin(const cVector3f &amp;amp;in avPosition)&lt;br /&gt;
{&lt;br /&gt;
	return avPosition.Length();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HPL3 functions commonly use &amp;lt;code&amp;gt;const Type &amp;amp;in&amp;lt;/code&amp;gt; for strings, vectors, colors, matrices, and other value objects which only need to be read.&lt;br /&gt;
&lt;br /&gt;
{{note|A handle parameter is itself passed by value. The called function can modify the shared object, but rebinding its local parameter does not rebind the caller's handle.}}&lt;br /&gt;
&lt;br /&gt;
== Instances and handles in arrays ==&lt;br /&gt;
&lt;br /&gt;
An array declaration also determines whether it stores instances or handles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
array&amp;lt;cCounter&amp;gt; counters;   // Stores counter instances.&lt;br /&gt;
array&amp;lt;cCounter@&amp;gt; targets;   // Stores handles to counter instances.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An array of instances owns independent elements. Reading an element into another object variable copies it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
cCounter copy;&lt;br /&gt;
copy = counters[0];&lt;br /&gt;
&lt;br /&gt;
copy.mlValue = 5;&lt;br /&gt;
&lt;br /&gt;
// counters[0].mlValue was not changed.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To edit the actual instance inside the array through an alias, take a handle to that element:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
cCounter@ pCounter = @counters[0];&lt;br /&gt;
pCounter.mlValue = 5;&lt;br /&gt;
&lt;br /&gt;
// counters[0].mlValue is now 5.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This pattern is used by the shipped HPL3 scripts when updating class instances stored in arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
for(uint i = 0; i &amp;lt; mvShakes.size(); ++i)&lt;br /&gt;
{&lt;br /&gt;
	cLuxEffect_ShakeInstance@ pShake = @mvShakes[i];&lt;br /&gt;
	pShake.mfTime -= afTimeStep;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An array of handles behaves differently. Its elements may be &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;, and several elements can refer to the same object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
array&amp;lt;iLuxEntity@&amp;gt; vEntities;&lt;br /&gt;
vEntities.push_back(Map_GetEntity(&amp;quot;EntityA&amp;quot;));&lt;br /&gt;
vEntities.push_back(Map_GetEntity(&amp;quot;EntityA&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
// Both elements may refer to the same map entity.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Choosing between an instance and a handle ==&lt;br /&gt;
&lt;br /&gt;
Use an object instance when:&lt;br /&gt;
&lt;br /&gt;
* the variable should own independent data;&lt;br /&gt;
* copying the object's state is the desired behavior;&lt;br /&gt;
* the value must always exist rather than being optional; or&lt;br /&gt;
* working with an HPL3 value type such as a vector, color, matrix, or ID.&lt;br /&gt;
&lt;br /&gt;
Use an object handle when:&lt;br /&gt;
&lt;br /&gt;
* referring to an object which already exists;&lt;br /&gt;
* several parts of the script must share the same object;&lt;br /&gt;
* &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; is a useful &amp;quot;no object&amp;quot; state;&lt;br /&gt;
* working with HPL3-owned entities, physics objects, resources, or GUI objects;&lt;br /&gt;
* using a base class or interface to refer to different derived types; or&lt;br /&gt;
* modifying an existing instance stored inside a container.&lt;br /&gt;
&lt;br /&gt;
For a long-lived reference to an HPL3-owned world object, store its &amp;lt;code&amp;gt;tID&amp;lt;/code&amp;gt; and resolve a temporary handle when needed. See [[HPL3/Scripting/Scripting Guide/Object Handles#Persistent references and tID|Object Handles]] and [[HPL3/Scripting/ID Handles|ID Handles]].&lt;br /&gt;
&lt;br /&gt;
== Common mistakes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Mistake&lt;br /&gt;
! Result&lt;br /&gt;
! Correct approach&lt;br /&gt;
|-&lt;br /&gt;
| Expecting &amp;lt;code&amp;gt;second = first&amp;lt;/code&amp;gt; to make &amp;lt;code&amp;gt;second&amp;lt;/code&amp;gt; an alias.&lt;br /&gt;
| The destination receives copied object data.&lt;br /&gt;
| Declare a handle and use &amp;lt;code&amp;gt;@second = @first&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Expecting a handle assignment to copy the object.&lt;br /&gt;
| Both handles refer to one shared instance.&lt;br /&gt;
| Create another instance and use value assignment when an independent copy is needed.&lt;br /&gt;
|-&lt;br /&gt;
| Changing a copied array element and expecting the array to change.&lt;br /&gt;
| Only the local copy changes.&lt;br /&gt;
| Take a handle to the element with &amp;lt;code&amp;gt;@array[index]&amp;lt;/code&amp;gt;, or assign the changed value back.&lt;br /&gt;
|-&lt;br /&gt;
| Assuming an object copy is always deep.&lt;br /&gt;
| Handle members in the copy still refer to the original referenced objects.&lt;br /&gt;
| Implement explicit deep-copy behavior when required.&lt;br /&gt;
|-&lt;br /&gt;
| Declaring an engine interface as a local instance.&lt;br /&gt;
| The type may be abstract, non-instantiable, or engine-owned.&lt;br /&gt;
| Retrieve the object through an HPL3 function and store the returned handle.&lt;br /&gt;
|-&lt;br /&gt;
| Using a handle where independent state is required.&lt;br /&gt;
| Changes made through any alias affect the shared object.&lt;br /&gt;
| Store an instance or create an explicit copy.&lt;br /&gt;
|-&lt;br /&gt;
| Keeping a raw engine-object handle as persistent saved state.&lt;br /&gt;
| The referenced engine object may be destroyed or reconstructed.&lt;br /&gt;
| Store a &amp;lt;code&amp;gt;tID&amp;lt;/code&amp;gt;, resolve it when needed, and validate the returned handle.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[HPL3/Scripting/Scripting Guide/Object Handles|Object Handles]]&lt;br /&gt;
* [[HPL3/Scripting/Scripting Guide/Type Casting|Type Casting]]&lt;br /&gt;
* [[HPL3/Scripting/ID Handles|ID Handles]]&lt;br /&gt;
* [[HPL3/Scripting/AngelScript Fundamentals/Chapter 8 - Classes|Classes - AngelScript]]&lt;br /&gt;
* [[HPL3/Scripting/AngelScript Fundamentals/Chapter 9 - Miscellaneous AngelScript Features|Miscellaneous AngelScript Features]]&lt;br /&gt;
&lt;br /&gt;
{{NavBar|HPL3/Scripting/Scripting Guide/Object Handles|Object Handles|HPL3/Scripting/HPL3 Scripting Guide|HPL3 Scripting Guide|HPL3/Scripting/Scripting Guide/Type Casting|Type Casting}}&lt;br /&gt;
&lt;br /&gt;
[[Category:HPL3 Scripting]]&lt;br /&gt;
[[Category:English]]&lt;/div&gt;</summary>
		<author><name>TiMan</name></author>
		
	</entry>
</feed>