Skip to content

Object and type system

Engine internalsArchitecture

Where runtime state, shared type data, engine IDs, factories, and INI reads belong.

AbstractClass is the common base for persistent engine entities. Map objects and INI-backed type definitions are separate branches of that hierarchy. A runtime instance stores state for one object in the current match; a type definition stores data shared by every instance with the same INI identifier.

This page covers simulation objects and their definitions. UI controls, file classes, and locomotion COM objects use other hierarchies.

TermMeaning in this manual
Runtime instanceOne object or state record created for the current match, such as a UnitClass or HouseClass.
Type definitionShared configuration loaded once for an INI identifier, such as a UnitTypeClass.
ObjectType IDFor an ObjectTypeClass family, the identifier returned by Name() and used as that definition’s INI section name. Other AbstractTypeClass families can use IniName as an entry key in a registry section.
RTTIThe engine’s RTTIType value. It is separate from C++ RTTI.
Heap IDThe index returned by Fetch_Heap_ID() for classes stored in a family-specific heap.

IsActive, IsInLimbo, and Strength are independent runtime fields. The phrase “runtime instance” does not imply a particular value for any of them.

The tree below shows the primary behavioral base path. Parenthesized bases are additional C++ bases, not part of that path.

Primary runtime inheritance
AbstractClass
+- ObjectClass
+- MissionClass
| +- RadioClass
| +- TechnoClass (+ FlasherClass, StageClass)
| +- BuildingClass
| +- FootClass
| +- AircraftClass (+ IFlyControl)
| +- InfantryClass
| +- UnitClass
+- AnimClass (+ StageClass)
+- BulletClass
+- BuildingLightClass
+- IsometricTileClass
+- OverlayClass
+- ParticleClass
+- ParticleSystemClass
+- SmudgeClass
+- TerrainClass (+ StageClass)
+- VeinholeMonsterClass
+- VoxelAnimClass (+ BounceClass)
+- WaveClass

ObjectClass supplies map position, strength, limbo and active state, cell links, tags, render-layer membership, and the Class_Of() interface. MissionClass adds mission state; RadioClass adds synchronous object-to-object coordination; TechnoClass adds ownership, combat, targeting, cargo, and production state. FootClass is the mobile techno base.

Secondary bases add narrow behavior. For example, StageClass supplies staged animation, while IFlyControl is the aircraft locomotion control interface. Code that follows only the primary path must not assume that these contracts are absent.

Other persistent state derives from AbstractClass without being a map object or a type definition. Important families include HouseClass, TeamClass, TagClass, TriggerClass, TActionClass, TEventClass, ScriptClass, FactoryClass, CellClass, and SuperClass.

AbstractTypeClass also derives from AbstractClass. Type definitions therefore use the same engine identity and persistence interfaces as runtime state, but they do not derive from ObjectClass.

INI-backed type definitions
AbstractClass
+- AbstractTypeClass
+- ObjectTypeClass
| +- TechnoTypeClass
| | +- AircraftTypeClass
| | +- BuildingTypeClass
| | +- InfantryTypeClass
| | +- UnitTypeClass
| +- AnimTypeClass
| +- BulletTypeClass
| +- IsometricTileTypeClass
| +- OverlayTypeClass
| +- ParticleSystemTypeClass
| +- ParticleTypeClass
| +- SmudgeTypeClass
| +- TerrainTypeClass
| +- VoxelAnimTypeClass
+- AITriggerTypeClass
+- CampaignClass
+- HouseTypeClass
+- ScriptTypeClass
+- SideClass
+- SuperWeaponTypeClass
+- TagTypeClass
+- TaskForceClass
+- TeamTypeClass
+- TiberiumClass
+- TriggerTypeClass
+- WarheadTypeClass
+- WeaponTypeClass

AbstractTypeClass owns the INI identifier (IniName), display-name token (GivenName), and the common Read_INI/Write_INI contract. ObjectTypeClass adds properties shared by map-object definitions, including artwork identifiers, strength, armor, footprint behavior, and object factories. TechnoTypeClass adds data shared by owned combat actors, including weapons, movement, production, targeting, and veterancy.

Direct AbstractTypeClass families do not describe map objects. A weapon, warhead, team, trigger, or campaign definition therefore has no reason to inherit ObjectTypeClass just because it has an INI section.

AbstractClass exposes three different identifiers, and they are not interchangeable:

InterfacePurpose
What_Am_I() / Fetch_RTTI()Returns the concrete engine RTTIType. Abstract intermediate classes without an override remain abstract; they do not supply RTTI_NONE as a default identity.
Fetch_ID()Returns the object’s engine identity used by persistence and reference tracking.
Fetch_Heap_ID()Returns the slot in a family-specific heap when the concrete class overrides it; the base implementation returns zero.

An RTTI value selects a class family; a heap ID selects one object within that family’s heap; an ObjectType ID is the textual INI name.

Most INI-backed ObjectClass families expose their shared definition through Class_Of(); techno instances also expose it through Techno_Type_Class(). This is not a universal retained pointer. BuildingLightClass and WaveClass return null, while VeinholeMonsterClass obtains its rules-owned type through global state.

The table names the interface for each direction of travel between a definition and a runtime instance. The first two rows are lookups; the last two create an object from a definition, and they are virtual hooks rather than guaranteed reverse mappings.

DirectionInterface
Runtime instance to shared definitionClass_Of() or Techno_Type_Class() when the family provides one
Textual ID to object definitionObjectTypeClass::From_Name() and family-specific lookup
Definition to unplaced instanceCreate_One_Of(HouseClass*)
Definition to placed instanceCreate_And_Place(Cell, HouseClass*)

AircraftTypeClass::Create_And_Place() returns false, and current particle, particle-system, animation, bullet, and voxel-animation implementations include false, null, or no-op factory paths. Check the concrete family and the return value.

ObjectTypeClass::ObjectTypes is the cross-family registry of object definitions. Concrete families also use their own heaps and typed lookup functions. Code that already knows the family should use the typed path instead of scanning the cross-family registry.

Base-reader calls are an implementation property, not a consequence of C++ inheritance. A UnitTypeClass read passes through AbstractTypeClass, ObjectTypeClass, and TechnoTypeClass before applying unit-specific fields. AITriggerTypeClass, TagTypeClass, TriggerTypeClass, WarheadTypeClass, and WeaponTypeClass instead parse their fields without calling AbstractTypeClass::Read_INI. Trace the concrete reader before treating a base-class key as inherited.

The declaring reader determines where a key enters the hierarchy:

  • AbstractTypeClass::Read_INI applies to every definition whose read path reaches it.
  • ObjectTypeClass::Read_INI applies only to map-object definitions.
  • TechnoTypeClass::Read_INI applies only to aircraft, buildings, infantry, and units.
  • A concrete reader limits the key to that family unless another reader accepts the same spelling independently.

A derived reader may reinterpret or overwrite a field after its base call. The declaring class establishes the read location, not identical behavior in every derived family.

Each row pairs a requirement with the class that should hold the field. The rows run from state that varies per object, through the definition classes that share it, out to state that belongs to the match, with a final row for a field that refers to another object. Take the narrowest class that owns the invariant: moving a field upward widens the serialized layout and public INI surface, and moving it downward duplicates state and reader logic.

RequirementPlacementExample
Changes independently for every object during a matchThe narrowest runtime class that owns the behaviorRemaining fuel on one AircraftClass instance
Shared by every object with one INI identifierThe corresponding concrete TypeClassMaximum fuel on AircraftTypeClass
Shared by several map-object definition familiesObjectTypeClass or another common type baseA property used by animations, terrain, and technos
Shared only by owned combat definitionsTechnoTypeClassA targeting coefficient used by units, infantry, aircraft, and buildings
Applies to the match rather than an object definitionThe owning global or scenario subsystemA game-wide rule in RulesClass
References another persistent runtime objectRuntime state plus detach, load swizzling, and CRC reviewA non-owning target or contact pointer

Source files

Linked at revision 59fae722af8c.