Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ProwlEngine/Prowl/llms.txt
Use this file to discover all available pages before exploring further.
EngineObject is the root base class for every first-class object in the Prowl runtime — GameObject, MonoBehaviour, Scene, assets, and more all derive from it. It establishes a globally unique runtime identity via InstanceID, optional persistent asset identity via AssetID, a human-readable Name, a two-phase destruction system (DestroyLater / DestroyImmediate), and a deep-clone API backed by Prowl’s attribute-driven cloning infrastructure. Understanding EngineObject is essential before working with the scene hierarchy or writing editor tooling.
EngineObject carries [CloneBehavior(CloneBehavior.Reference)] at the class level, which means the cloning system treats any EngineObject reference as shared by default. Subclasses override this by applying their own [CloneBehavior] attribute — for example, MonoBehaviour uses CloneBehavior.ChildObject.Identity Properties
A monotonically incrementing integer assigned at construction time. Guaranteed unique within a single process lifetime. Never persisted to disk — it changes every time an object is created, including after deserialization.
The persistent asset GUID.
Guid.Empty for runtime-only objects (GameObjects that were never saved as assets). Set by the asset pipeline when an object is loaded from disk.A sub-file identifier used when multiple objects are packed into a single asset file.
0 when the object is the sole resident of its file.Human-readable display name. Defaults to
"New" + GetType().Name at construction, then overridden by the caller. Persisted to disk via the serialization header.Set to
true by either destroy path. The equality operators (== / !=) treat any two destroyed EngineObjects as equal and treat a destroyed object as equal to null. Check this flag before using a cached reference.Lifecycle Methods
CreatedInstance (virtual)
Called automatically at the end of theEngineObject base constructor, before Name is applied. Override in subclasses to perform initialization that must happen at the moment of allocation.
DestroyLater
Marks the object as destroyed and pushes it onto the deferred destruction stack. The object is not disposed immediately; disposal happens the next timeEngineObject.HandleDestroyed() is called (typically at the end of the frame by the scene manager).
DestroyImmediate
Marks the object as destroyed and callsOnDispose() synchronously. Use with care — calling this while the object’s list is being iterated can cause collection-modification exceptions.
HandleDestroyed (static)
Drains the deferred destruction stack, callingOnDispose() on every object that was queued by DestroyLater(). Called automatically by SceneManager.Clear() and should be called by the engine host after each frame if objects may have been deferred.
OnDispose (virtual)
Override in subclasses to release resources when the object is destroyed. The default implementation is empty.GameObject uses this to recursively destroy children and components; MonoBehaviour uses it to detach from its GameObject.
OnValidate (virtual)
Called by the editor inspector when a serialized field is modified. Override to enforce invariants (e.g. clamping a value or updating a cached computation).Clone API
Prowl’s cloning system is attribute-driven and supports deep copying with configurable field handling.EngineObject implements ICloneExplicit to coordinate the two-pass clone operation.
Clone
Creates a deep copy of this object using the Prowl cloning infrastructure.A newly allocated object with all fields deep-copied according to their
[CloneField] and [CloneBehavior] attributes.CopyTo
Copies data from this object into an existing target of the same type.The destination object. Must be the same concrete type as the source.
OnSetupCloneTargets (virtual, protected)
Override to customize the first pass of cloning, where the clone graph is constructed and target objects are linked. Called internally; only needed for advanced scenarios.OnCopyDataTo (virtual, protected)
Override to customize the second pass of cloning, where field values are actually copied. Called internally after all targets are established.Cloning Attributes
[CloneBehavior] — control how a type or field is cloned
[CloneBehavior] — control how a type or field is cloned
Applied to a class to set the default clone strategy for all instances of that type.
| Value | Meaning |
|---|---|
Default | Determined automatically from type attributes and context. |
Reference | The reference is copied as-is; the object itself is not cloned. |
ChildObject | The object is owned by its parent and deep-copied. |
[CloneField] — per-field clone flags
[CloneField] — per-field clone flags
Applied to individual fields to refine cloning behavior regardless of the class-level setting.
| Flag | Effect |
|---|---|
None | No special handling. |
IdentityRelevant | Field encodes identity (e.g. _instanceID); skipped in identity-preserving copies. |
Skip | Always omitted from the clone. |
DontSkip | Overrides SerializeIgnore and similar skip hints. |
Static Search Methods
FindObjectsOfType<T>
Searches the active scene for allGameObjects and MonoBehaviour components that are assignable to T.
Array of all matching objects. May contain
null entries if a match slot could not be cast.FindObjectByID<T>
Finds anEngineObject by its runtime InstanceID.
The
InstanceID to search for.The matching object cast to
T, or null if not found or the cast fails.FindObjectByIdentifier<T>
Finds anEngineObject by its persistent Guid identifier. Useful after deserialization, where InstanceIDs have changed but Guids are stable.
The persistent GUID to search for. On
GameObject this is GameObject.Identifier; on MonoBehaviour this is MonoBehaviour.Identifier.The matching object cast to
T, or null if not found.Equality and Null Safety
EngineObject overrides == and != to treat destroyed objects as null-equivalent:
| Comparison | Result |
|---|---|
null == null | true |
null == destroyed | true |
destroyed == destroyed | true |
alive == alive (same ref) | true |
alive == alive (different ref) | false |
Null() provides a concise null-or-destroyed check: